springboot返回内容特殊符号处理

    技术2025-10-10  3

    需求说明

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

    解决方案

    可以在单个方法中对数据进行处理,但是这样会增加代码复杂度,具有侵入性 使用切面思想,对返回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 {}; }

    创建类实现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; }

    代码只对特殊字符进行处理,字段过滤等功能待开发。 在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>                     });

     

    Processed: 0.009, SQL: 9