前言

这几天开发一个项目,为了方便,前台将当前登陆人的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中的对应的参数值。

自定义注解获取请求Header中的值的更多相关文章

  1. 获取请求 header 中指定字段的值

    private function getHeader($name) {//获取请求头中$name的值 $name = 'HTTP_' . $name; foreach ($_SERVER as $ke ...

  2. @value 注解获取属性文件中的值

    一.属性文件 db.properties name=jack 二.配置文件 applicationContext.xml <!-- 加载配置文件,该节点只能存在一个,所以用 * ,加载所有属性文 ...

  3. WebAPi获取请求头中对应键值

    /// <summary> /// 依据键获取请求头中值数据 /// </summary> /// <param name="request"> ...

  4. SpringBoot 拦截器和自定义注解判断请求是否合法

    应用场景举例: 当不同身份的用户请求一个接口时,用来校验用户某些身份,这样可以对单个字段数据进行精确权限控制,具体看代码注释 自定义注解 /** * 对比请求的用户身份是否符合 * @author l ...

  5. Java如何获取JSON数据中的值

    场景:在接口自动化场景中,下个接口发送的请求参数,依赖上个接口请求结果中的值.需要将获取值作为全局参数引用. import java.io.File; import java.io.FileInput ...

  6. Spring 获取propertise文件中的值

    Spring 获取propertise文件中的值 Spring 获取propertise的方式,除了之前的博文提到的使用@value的注解注入之外,还可以通过编码的方式获取,这里主要说的是要使用Emb ...

  7. 使用JavaScript设置、获取父子页面中的值

    一:获取父页面中的值 有二种方法windows.open()和windows.showModalDialog() 1.windos.open(URL,name,reatures,replace) 再父 ...

  8. 网站开发进阶(十八)js获取html标签中的值

    js获取html标签中的值 项目开发过程中,由于需求所迫,需要获取html标签元素中的内容,下面做一简单总结.以下所讲的示例适用于其它标签元素. 主要包括2中方法获取元素内容: 方法一:.innerT ...

  9. 获取请求Requst中访问请求的客户端IP

    获取请求Request中访问请求的客户端IP /*获取请求客户端的IP地址*/ public static String getIpAddress(HttpServletRequest request ...

  10. 如何获取select中的value、text、index相关值 && 如何获取单选框中radio值 && 触发事件 && radio 默认选中

    如何获取select中的value.text.index相关值 select还是比较常用的一个标签,如何获取其中的内容呢? 如下所示: <select id="select" ...

随机推荐

  1. .NET与大数据

    前言 当别人做大数据用Java.Python的时候,我使用.NET做大数据.数据挖掘,这确实是值得一说的事. 写的并不全面,但都是实际工作中的内容. .NET在大数据项目中,可以做什么? 写脚本(使用 ...

  2. 2023牛客寒假算法基础集训营5 A-L

    比赛链接 A 题解 知识点:前缀和,二分. 找到小于等于 \(x\) 的最后一个物品,往前取 \(k\) 个即可,用前缀和查询. 时间复杂度 \(O(n + q\log n)\) 空间复杂度 \(O( ...

  3. 手把手教你将Eureka升级Nacos注册中心

    由于原有SpringCloud体系版本比较老,最初的注册中心使用的Eureka后期官方无升级方案,配置中心无法在线管理配置,还有实时上下线的问题,因此需要将原有系统的Eureka服务升级Nacos注册 ...

  4. Pycharm中图标的含义

    Pycharm中图标的含义 问题 有同学问,下面的v,c,f等都是啥意思 这个问题嘛,应该在python学习阶段来问,不过我也只能解释部分,有些也只能靠猜测 按图索骥找了下pycharm的官网doc, ...

  5. MySQL-多表查询的两种方法、Navicat、python操作MySQL

    1.多表查询的两种方法 1.连表操作: 1.1:inner join:内连接,将两张表共同的部分连接起来生成一张新表.拼接顺序是把后面的表拼在前面的表,如果颠倒位置结果不同. select * fro ...

  6. 多人协同开发,git workflow 提高团队协作能力

    集美们,还在为工作多年而只会使用简单的git指令被质疑是假简历而烦恼吗. Don't worry! || 今天给带来大家一个git攻略指南.成为大手子,参与开源大项目指日可待‍‍‍. . Git 这是 ...

  7. KMP 算法(Knuth–Morris–Pratt algorithm)的基本思想

    KMP 算法(Knuth–Morris–Pratt algorithm)的基本思想 阅读本文之前,您最好能够了解 KMP 算法解决的是什么问题,最好能用暴力方式(Brute Force)解决一下该问题 ...

  8. 基于C++的OpenGL 01 之Hello Triangle

    1. 引言 本文基于C++语言,描述OpenGL的绘制流程,这里描述的是OpenGL的核心模式(Core-profile) 本文基于Ubuntu 20.04.3 LTS系统,使用CMake构建程序,O ...

  9. Study for Go ! Chapter two - Expression

    Study for Go ! Chapter two - Expression 1. Keyword Golang仅有 25 个保留关键字,体现了 golang 语法规则的简洁性 保留关键字不能用作常 ...

  10. 18 网路进阶设定:Bridge、LACP、VLAN

    18 网路进阶设定:Bridge.LACP.VLAN 18.1 建立第二网路桥接装置(Bridge) 在预设安装完的情况下,PVE会使用其中一个连接埠桥接至[vmbr0]这个预设的网路桥接装置,所有的 ...