java 通过自定义注解验签
时间: 2023-12-08 07:37:27 浏览: 47
根据提供的引用内容,我们可以看出这是一个Java Web项目,其中包含了自定义注解和拦截器的使用。在Java中,我们可以通过自定义注解和拦截器来实现验签功能。具体步骤如下:
1.定义自定义注解@Sign,用于标记需要验签的方法或类。
2.定义拦截器,在拦截器中获取请求参数和签名,并进行验签操作。
下面是一个简单的Java验签示例:
```java
// 自定义注解
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Sign {
}
// 拦截器
@Component
public class SignInterceptor implements HandlerInterceptor {
@Autowired
private SignService signService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 判断是否有@Sign注解
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Sign sign = handlerMethod.getMethodAnnotation(Sign.class);
if (sign == null) {
sign = handlerMethod.getBeanType().getAnnotation(Sign.class); }
if (sign != null) {
// 获取请求参数和签名
Map<String, String[]> parameterMap = request.getParameterMap();
String signValue = request.getHeader("sign");
// 验签
boolean verifyResult = signService.verifySign(parameterMap, signValue);
if (!verifyResult) {
// 验签失败,返回错误信息
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write("{\"code\":400,\"msg\":\"验签失败\"}");
return false;
}
}
}
return true;
}
}
// 验签服务
@Service
public class SignService {
// 验签密钥
private static final String SIGN_KEY = "123456";
/**
* 验签
*
* @param parameterMap 请求参数
* @param signValue 签名
* @return 验签结果
*/
public boolean verifySign(Map<String, String[]> parameterMap, String signValue) {
// 将请求参数按照字典序排序并拼接成字符串
StringBuilder sb = new StringBuilder();
parameterMap.keySet().stream().sorted().forEach(key -> {
String[] values = parameterMap.get(key);
Arrays.sort(values);
sb.append(key).append("=").append(values[0]).append("&");
});
sb.append("key=").append(SIGN_KEY);
// 计算签名
String sign = DigestUtils.md5Hex(sb.toString());
// 验证签名
return StringUtils.equals(sign, signValue);
}
}
// 控制器
@RestController
public class TestController {
@Autowired
private SignService signService;
@PostMapping("/test")
@Sign
public ResponseBody<AuthCodeJson> getAuthCode(@CurrentUser UserInfo userInfo) {
System.out.println(userInfo.getId());
System.out.println(ThreadContextHolder.getUserInfo().getUserId());
return this.success();
}
}
```
在上面的示例中,我们定义了一个自定义注解@Sign,用于标记需要验签的方法或类。然后定义了一个拦截器SignInterceptor,在拦截器中获取请求参数和签名,并进行验签操作。最后,在控制器TestController中使用@Sign注解标记了需要验签的方法getAuthCode。