Springboot中的响应拦截器

Springboot中的响应拦截器

1.标题

日常项目开发中,有时候会对响应结果进行处理,比如返回枚举字段时的名称,此文章用于记录响应拦截器在实战项目中的使用

2 工具类

2.1 自定义注解

  /**
    *  注解使用在返回Vo对象中的枚举字段
   */
   
 	@Target(ElementType.FIELD)
	@Inherited
	@Retention(RetentionPolicy.RUNTIME)
	public @interface EnumsMapper {
	    /**
	     * 目标字段
	     */
	    public String targetField() default "";
	}

2.2 响应拦截器

	/**
	  *  枚举类型返回字段处理
	  *   
	  */ 
	@Slf4j
	@RestControllerAdvice
	// 实现ResponseBodyAdvice接口,传入需要拦截的返回封装对象
	public class EnumsMapperHandlerAdvice implements ResponseBodyAdvice {
		 /**
	     * 判断拦截的方法返回对象是否包含  封装的返回对象
	     * @param returnType
	     * @param converterType
	     * @return
	     */
	    @Override
	 public boolean supports(MethodParameter returnType, Class> converterType) {
	        if (returnType.getMethod() == null) {
	            return false;
	        }
	        return ResponseMessage.class.isAssignableFrom(returnType.getMethod().getReturnType());
	    }
		  /**
	     * 判断返回的对象中的data数据    Vo对象是否实现Vo类,分页对象是否实现PageBean,列表数据是否实现List
	     * @param body
	     * @param returnType
	     * @param selectedContentType
	     * @param selectedConverterType
	     * @param request
	     * @param response
	     * @return
	     */
	    @Override
	    public ResponseMessage beforeBodyWrite(ResponseMessage body, MethodParameter returnType, MediaType selectedContentType, Class> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
	        Object data = body.getData();
	        if (data instanceof Vo) {
	            mapEnum(data);
	        } else if (data instanceof PageBean) {
	            mapEnums(((PageBean) data).getDatas());
	        } else if (data instanceof List) {
	            mapEnums((List) data);
	        }
	        return body;
	    }
	
	    private void mapEnums(List data) {
	        if (data != null) {
	            data.forEach(this::mapEnum);
	        }
	    }
	
	    private void mapEnum(Object data) {
	        if (data != null) {
	            processFields(data.getClass(), data);
	        }
	    }
	
	    private void processFields(Class clazz, Object data) {
	        // 递归处理父类
	        Class superClass = clazz.getSuperclass();
	        if (!superClass.equals(Object.class)) {
	            processFields(superClass, data);
	        }
	
	        Field[] fields = clazz.getDeclaredFields();
	        for (Field field : fields) {
	        	// 判断对象中是否存在自定义的注解 EnumsMapper
	            EnumsMapper mapper = field.getAnnotation(EnumsMapper.class);
	            if (mapper == null) {
	                continue;
	            }
	            // 对象中必须存在枚举字段   对应的返回枚举名称为枚举字段名+Name
	            String targetFieldName = mapper.targetField();
	            if (StringUtils.isEmpty(targetFieldName)) {
	                targetFieldName = field.getName() + "Name";
	            }
	            try {
	                if (!field.isAccessible()) {
	                    field.setAccessible(true);
	                }
	                Object fieldValue = field.get(data);
	                if (fieldValue instanceof EnumDictionarySupport) {
	                    Field targetField = clazz.getDeclaredField(targetFieldName);
	                    if (!targetField.isAccessible()) {
	                        targetField.setAccessible(true);
	                    }
	                    targetField.set(data, ((EnumDictionarySupport) fieldValue).getName());
	                }
	            } catch (IllegalAccessException | NoSuchFieldException e) {
	                log.error("enum field map failed: {}", e.getMessage());
	            }
	        }
	    }
	}

你可能感兴趣的:(Springboot)