前言
和切面一样,在项目中同样使用了自定义注解,目前项目中使用的自定义注解主要分为以下一些方面:controller参数解析,缓存方法声明,导入功能中的POJO声明。
@JsonObject
用在controller的方法参数,解析前台提交的json参数,组装成java对象。用法如下:
@PostMapping("/bas/user/status/toggle") public PackVo toggleUserStatus(@JsonObject Long[] userIds , @JsonObject Long status ){ ... }
注解声明
@Target(ElementType.PARAMETER)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface JsonObject { String value() default ""; boolean required() default true;}
注解处理,实现HandlerMethodArgumentResolver,
public class JsonArgumentResolver implements HandlerMethodArgumentResolver { public static Logger logger = LoggerFactory.getLogger(JsonArgumentResolver.class); @Override public boolean supportsParameter(MethodParameter methodParameter) { return methodParameter.hasParameterAnnotation(JsonObject.class); } @Override public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception { try { JSONObject para = getRequestInfo(nativeWebRequest); Class type = methodParameter.getParameterType(); String name = methodParameter.getParameterName(); //获取参数注解JsonObject,如果为空,则使用参数名,不为空,则使用注解中的value Annotation[] annotations = methodParameter.getParameterAnnotations(); for(Annotation annotation : annotations){ if(annotation instanceof JsonObject){ String value = ((JsonObject) annotation).value(); if(StringUtils.isNotEmpty(value)){ name = value; } } } if (null != para && para.containsKey(name)) { if (String.class.equals(type)) { return para.getString(name); } if (List.class.equals(type)) { String typeName = methodParameter.getGenericParameterType().getTypeName(); typeName = typeName.substring(typeName.indexOf("<")+1); typeName =typeName.substring(0,typeName.length()-1); return JSON.parseArray(para.getString(name), Class.forName(typeName)); } return JSON.parseObject(para.getString(name), type); } } catch (Exception e) { e.printStackTrace(); logger.info("",e); } return null; } private JSONObject getRequestInfo(NativeWebRequest webRequest) throws IOException { JSONObject para = new JSONObject(); HttpServletRequest httpServletRequest = webRequest.getNativeRequest(HttpServletRequest.class); String method = httpServletRequest.getMethod(); if (!method.equals("GET") && !method.equals("DELETE")) { if (null != httpServletRequest.getAttribute("para")) { try { para = JSON.parseObject(httpServletRequest.getAttribute("para").toString()); } catch (Exception e) { e.printStackTrace(); logger.info("",e); } } else { StringBuilder buffer = new StringBuilder(); BufferedReader reader = httpServletRequest.getReader(); String line; while ((line = reader.readLine()) != null) { buffer.append(line); } httpServletRequest.setAttribute("para", buffer.toString()); try { para = JSON.parseObject(buffer.toString()); } catch (Exception e) { e.printStackTrace(); logger.info("",e); } } } else { MapparameterMap = webRequest.getParameterMap(); for (Map.Entry entry : parameterMap.entrySet()) { String key = entry.getKey(); String values = StringUtils.join(entry.getValue()); para.put(key, values); } } return para; }}
@RedisCache
接口使用方式如下:
注解声明,具体的注解处理在上一篇的DAO切面中有写到。
@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic @interface RedisCache { String value() default ""; boolean required() default true;}