首页 > 其他分享 >自定义注解获取请求Header中的值

自定义注解获取请求Header中的值

时间:2022-11-04 14:12:59浏览次数:42  
标签:return HeaderValue 自定义 获取 Header 注解 public String

前言

这几天开发一个项目,为了方便,前台将当前登陆人的ID和名称放在每个请求的Header中(这里不考虑安全性之类的),这样后台只要需要用到,就直接从Header中get出来就可以了。

后台实现方法

后台写了一个manage类,需要获取登陆人名称或ID的地方注入此类,然后执行里面的方法即可,manage类代码如下:

/**
 * @author jiangkd
 * @date 2022/4/12 10:17
 */
@Slf4j
@Component
public class HeaderManage {

    @Resource
    HttpServletRequest httpServletRequest;

    /**
     * 从header中获取当前登录人, name
     *
     * @return 登录人
     */
    public String getUsername() {
        //
        final String username = httpServletRequest.getHeader(HeaderConsts.KEY_NAME);
        try {
            // 解码
            return URLDecoder.decode(username, "UTF-8");
        } catch (Exception e) {
            // 解码异常了
            log.error("从header中获取name并进行URL解码异常", e);
            return null;
        }

    }

    /**
     * 从header中获取当前登录人的用户ID
     *
     * @return 用户ID
     */
    public String getUid() {
        //
        return httpServletRequest.getHeader(HeaderConsts.KEY_UID);
    }
}

实际使用这么的确是没有问题的,但是这几天突然发现,如果自定义一个注解,不就可以直接从Header中获取需要的参数值了,不用每次都要如注入一个HeaderManage类执行方法了,而是Controller的方法入口中,使用一个自定义注解标识的参数接收即可。

怎么实现呢 。。。

自定义注解方式

关于自定义注解的原理和说明,这里不做解释,不懂得伙伴百度一下吧,也不难。

首先我们创建一个注解类 HeaderValue,代码如下:

/**
 * 自定义注解, 从Header中获取指定key的值
 *
 * @author jiangkd
 */
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface HeaderValue {

    String value() default "";
}

我们这里只是实现我们一开始的需求,不做复杂的注解,所以这里只定义一个value()方法,默认值是“”。

下一步我们需要实现这个注解的请求解析处理,也就是实现一个HandlerMethodArgumentResolver类。

实现HandlerMethodArgumentResolver,代码如下:

/**
 * 自定义注解HeaderValue解析器, 获取Header中指定key的值
 *
 * @author jiangkd
 * @date 2022/11/1 9:49:48
 */
public class HeaderValueMethodArgumentResolver implements HandlerMethodArgumentResolver {

    /**
     * 判断Controller层方法中的参数, 是否满足条件, 满足条件则执行resolveArgument方法,不满足则跳过;
     *
     * @param parameter 要解析的方法参数对象,可以从对象获取参数的属性(如参数的类型,所修饰的注解等)
     * @return 满足条件返回true;否则false
     */
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        // 方法中的参数是否使用了注解@HeaderValue
        return parameter.hasParameterAnnotation(HeaderValue.class);
    }

    /**
     * 只有在supportsParameter方法返回true的情况下才会被调用, 用于处理一些业务, 将返回值赋值给Controller层中的这个参数
     *
     * @param parameter     要解析的方法参数对象,可以从对象获取参数的属性(如参数的类型,所修饰的注解等)
     * @param mavContainer  当前请求的 ModelAndViewContainer 容器
     * @param webRequest    当前的请求实体
     * @param binderFactory 实例创建工厂
     * @return 参数具体解析后封装的对象
     * @throws Exception e
     */
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {

        // 注解@HeaderValue
        final HeaderValue parameterAnnotation = parameter.getParameterAnnotation(HeaderValue.class);

        if (null != parameterAnnotation) {
            // 获取注解中的值, 也就是获取value的值
            String annotationValue = parameterAnnotation.value();
            if (StrUtil.isEmpty(annotationValue)) {
                // 不指定注解的value, 默认使用被标记的参数的名称
                annotationValue = parameter.getParameterName();
            }

            // HttpServletRequest
            final HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();

            // 从header中获取指定key的参数值
            final String headerValue = request.getHeader(annotationValue);

            // URL解码
            return URLDecoder.decode(headerValue, "utf-8");
        }
        return null;
    }
}

测试@HeaderValue

controller测试代码如下:

/**
 * 测试注解@HeaderValue
 *
 * @author jiangkd
 * @date 2022/11/1 9:53:42
 */
@RestController
@RequestMapping("/header/value")
public class HeaderValueController {

    @GetMapping("/test")
    public String test(@HeaderValue("uid") String uid, @HeaderValue() String name) {
        //
        return "uid:" + uid + ", name:" + name;
    }
}

测试方法中,参数uid的注解中定义了value的值,name的没有定义,所以上面的解析器中key就使用参数的名称,也就是name。

发送请求测试。。。

在这里插入图片描述
从结果可以看出,controller中的uid和name成功的获取到了header中的对应的参数值。

标签:return,HeaderValue,自定义,获取,Header,注解,public,String
From: https://www.cnblogs.com/no-celery/p/16857545.html

相关文章

  • Guava中常用Object方法-equals与null比较、hashCode、自定义toString、自定义compareT
    场景Java核心工具库Guava介绍以及Optional和Preconditions使用进行非空和数据校验:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/127683387在上面引入Gua......
  • @Cacheable注解实现Redis缓存
    SpringBoot缓存之@Cacheable介绍简介介绍:Spring从3.1开始就引入了对Cache的支持。定义了org.springframework.cache.Cache和org.springframework.cache.Cach......
  • kotlin 注解声明与使用
    前言函数的调用需要知道函数所在的类,函数的入参个数和参数类型,注解和反射可以跳过这个限制,注解和反射可以编写事先未知的任意类代码。注解可以为类库赋予特定的语义,反射可以......
  • gridpanel header click
    varmyGrid=Ext.Create('Ext.grid.Panel',{renderTo:'shrGrid',renderTo:myGrid,store:myStore,//JSONobjectcolumns:myGrid.columns,//JS......
  • Struts2的Action中自定义方法的输入校验
    自定义方法的输入校验对于通过action​的method​属性所指定的自定义方法myExecute​,其对应的自定义输入校验方法名为validateMyExecute​。(底层是通过反射调......
  • Struts2的Action中自定义方法的输入校验
    自定义方法的输入校验对于通过action​的method​属性所指定的自定义方法myExecute​,其对应的自定义输入校验方法名为validateMyExecute​。(底层是通过反射调......
  • qt输出自定义的pdf文件源码详解
    qt中有两种方式可以输出pdf:方式1:使用QPrinter即打印机的方式打印pdf这种方式,在qt4成为唯一的方式。QPrinterprinter(QPrinter::HighResolution);//高清晰度printer.set......
  • java.lang.IllegalArgumentException: Request header is too large
    该问题出现于接口使用get请求,参数的长度太长导致的问题,修复方案,将该接口的请求方式又get请求换成post请求即可进一步分析,两者都是http的请求方式,根本原因是浏览器和web服......
  • 浅谈自定义组件样式覆盖的方式
    简介有时候,基础组件提供的样式不够,需要在不同模块中使用不同的样式,而且差异大到无法通过一两个属性完成。比如组件的颜色,最常见的有三个区域(文字/图标、背景、边框,常用但......
  • C# .NET 获取枚举值的自定义属性(特性)信息
    一、引言枚举为我看日常开发的可读性提供的非常好的支持,但是有时我们需要得到枚举值得描述信息或者是注释(备注)信息比如要获得 TestEmun.aaa属性值得备注AAA,比较不方便得......