springboot返回内容特殊符号处理

需求说明

  1. 根据需求部分字段内容为正则表达式,包含特殊符号’<’,’>等,导致html解析错误,字段显示错误或显示部分。
  2. 对特殊字段需要过滤,如:用户密码等不应该返回到前端

解决方案

  1. 可以在单个方法中对数据进行处理,但是这样会增加代码复杂度,具有侵入性
  2. 使用切面思想,对返回json进行统一处理

代码

  1. 创建注解
package com.pactera.ai.manage.commons.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.web.bind.annotation.ResponseBody;

/**
* @user : Administrator

* @desc : 处理responseBody 只能在@ResponseBody 方法上使用

* @date : 2019年2月15日 
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@ResponseBody
public @interface SerializedField {

	/**
     * 需要去除的字段
     * @return
     */
    String[] excludes() default {};
    
    /**
     * 数据是否需要加密
     * @return
     */
    boolean encode() default false;
    
    /**
     * 需要替换特殊字符的字段 特殊字段包括< > 等
     * @return 
     * */
    String[] characters() default {};
}

  1. 创建类实现ResponseBodyAdvice接口,对返回参数进行处理。ResponseBodyAdvice可以指定参数类型,从而实现对不对返回类型数据进行不同处理,这里使用ResponseBodyAdvice对所有类型进行统一处理。
package com.pactera.ai.manage.commons.web;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.Order;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import com.pactera.ai.manage.commons.annotation.SerializedField;
import com.pactera.ai.manage.commons.util.LayerData;
import com.pactera.ai.manage.commons.util.RestResponse;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

/**
 * @user : Administrator
 * 
 * @desc : 处理返回json
 * 
 * @date : 2019年2月15日
 */
@Slf4j
@Order(1)
@ControllerAdvice(basePackages = "com.pactera.ai.manage.controller")
public class CustomResponseBodyAdvice implements ResponseBodyAdvice<Object> {

	@Override
	public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> converterType) {
		// 返回false 不执行 beforeBodyWrite方法
		return methodParameter.getMethod().isAnnotationPresent(SerializedField.class);
	}

	@SuppressWarnings("unchecked")
	@Override
	public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType selectedContentType,
			Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
			ServerHttpResponse response) {

		if (body == null)
			return null;

		SerializedField serializedField = methodParameter.getMethodAnnotation(SerializedField.class);
		String [] characters = serializedField.characters();
		if (characters != null && characters.length > 0) {  //处理特殊字符
			Property property =new Property();
			property.setCharacters(characters);
			if (body instanceof LayerData) {
				LayerData<Object> os = (LayerData<Object>) body;
				List<Object> data = os.getData();
				os.setData(handleList(data,property));
				return os;
			}else if(body instanceof RestResponse) {
				RestResponse restData= (RestResponse) body;
				Object object = restData.get("data");
				if(object instanceof List) {
					restData.setData(handleList((List<Object>) object,property));
				}else {
					restData.setData(handleSingleObject(object,property));
				}
				return restData;
			}
		}
					
	   return body;
	}
	/**
	 * 处理单个对象
	 *
	 * @param object
	 * @return
	 */
	private Object handleSingleObject(Object o,Property property) {
		try {
			Field[] fields = o.getClass().getDeclaredFields();
			List<String> characterList = Arrays.asList(property.getCharacters());
			for (Field field : fields) {
				// 只处理string类型
				if(field.getType()==String.class) {
					field.setAccessible(true);
					// 有限考虑包含字段				
					if (characterList.contains(field.getName())) {
						String newVal = (String) field.get(o);
						if(!StringUtils.isBlank(newVal)) {
							newVal = newVal.replaceAll("<", "&lt;").replaceAll(">", "&gt;");
							field.set(o, newVal);
						}						
					}
				}
			}
		} catch (Exception e) {
			log.error("handleSingleObject", e);
		}

		return o;
	}

	/**
	 * 处理返回值是列表
	 *
	 * @param list
	 * @return
	 */
	private List<Object> handleList(List<Object> list,Property property) {
		List<Object> retList = new ArrayList<>();
		for (Object o : list) {
			Object obj = handleSingleObject(o,property);
			retList.add(obj);
		}
		return retList;
	}

}
@Data
class  Property{
	
	private String [] characters;
}

代码只对特殊字符进行处理,字段过滤等功能待开发。
  1. 在Controller中使用注解
   @PostMapping("list")
	@SerializedField(characters= {"regex"})
	public LayerData<PatPredicatelibsys> list(@RequestParam(value = "page",defaultValue = "1")Integer page,
            @RequestParam(value = "limit",defaultValue = "10")Integer limit,String condition){
		LayerData<PatPredicatelibsys> resp= new LayerData<>();
			...
		return resp;
	}

返回页面处理

以上是返回json时的处理,如果返回是页面时如何处理呢? 系统使用.ftl类型页面,代码如下:

$(function(){
	<#if pat.regex??>
		$("#regex").text("${pat.regex}")
	</#if>					
});
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值