需求说明
根据需求部分字段内容为正则表达式,包含特殊符号’<’,’>等,导致html解析错误,字段显示错误或显示部分。
对特殊字段需要过滤,如:用户密码等不应该返回到前端。
解决方案
可以在单个方法中对数据进行处理,但是这样会增加代码复杂度,具有侵入性
使用切面思想,对返回json进行统一处理
代码
1.创建注解
package ;
import ;
import ;
import ;
import ;
import ;
/**
* @user : Administrator
* @desc : 处理responseBody 只能在@ResponseBody 方法上使用
* @date : 2019年2月15日
*/
@Target()
@Retention()
@ResponseBody
public @interface SerializedField {
/**
* 需要去除的字段
* @return
*/
String[] excludes() default {};
/**
* 数据是否需要加密
* @return
*/
boolean encode() default false;
/**
* 需要替换特殊字符的字段 特殊字段包括< > 等
* @return
* */
String[] characters() default {};
}
创建类实现ResponseBodyAdvice接口,对返回参数进行处理。ResponseBodyAdvice可以指定参数类型,从而实现对不对返回类型数据进行不同处理,这里使用ResponseBodyAdvice对所有类型进行统一处理。
package ;
import ;
import ;
import ;
import ;
import .;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import .slf4j.Slf4j;
/**
* @user : Administrator
*
* @desc : 处理返回json
*
* @date : 2019年2月15日
*/
@Slf4j
@Order(1)
@ControllerAdvice(basePackages = "")
public class CustomResponseBodyAdvice implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> converterType) {
// 返回false 不执行 beforeBodyWrite方法
return ().isAnnotationPresent();
}
@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 = ();
String [] characters = ();
if (characters != null && > 0) { //处理特殊字符
Property property =new Property();
(characters);
if (body instanceof LayerData) {
LayerData<Object> os = (LayerData<Object>) body;
List<Object> data = ();
(handleList(data,property));
return os;
}else if(body instanceof RestResponse) {
RestResponse restData= (RestResponse) body;
Object object = ("data");
if(object instanceof List) {
(handleList((List<Object>) object,property));
}else {
(handleSingleObject(object,property));
}
return restData;
}
}
return body;
}
/**
* 处理单个对象
*
* @param object
* @return
*/
private Object handleSingleObject(Object o,Property property) {
try {
Field[] fields = ().getDeclaredFields();
List<String> characterList = (());
for (Field field : fields) {
// 只处理string类型
if(()==) {
(true);
// 有限考虑包含字段
if ((())) {
String newVal = (String) (o);
if(!(newVal)) {
newVal = ("<", "<").replaceAll(">", ">");
(o, newVal);
}
}
}
}
} catch (Exception e) {
("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);
(obj);
}
return retList;
}
}
@Data
class Property{
private String [] characters;
}
代码只对特殊字符进行处理,字段过滤等功能待开发。
在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 ??>
$("#regex").text("${}")
</#if>
});