好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

使用RequestBodyAdvice实现对Http请求非法字符过滤

RequestBodyAdvice对Http请求非法字符过滤

利用RequestBodyAdvice对HTTP请求参数放入body中的参数进行非法字符过滤。

要求:spring 4.2+

额外的pom.xml

<dependency> <groupId> org.apache测试数据mons </groupId> <artifactId> commons-io </artifactId> <version> 1.3.2 </version> </dependency>   <dependency> <groupId> com.alibaba </groupId> <artifactId> fastjson </artifactId> <version> 1.2.44 </version> </dependency>

代码

package com . niugang . controller ; import java . io . IOException ; import java . io . InputStream ; import java . lang . reflect . Type ; import java . util . ArrayList ; import java . util . HashMap ; import java . util . List ; import java . util . Map ; import java . util . Map . Entry ; import java . util . Set ; import org . apache . commons . io . IOUtils ; import org . slf4j . Logger ; import org . slf4j . LoggerFactory ; import org . springframework . core . MethodParameter ; import org . springframework . http . HttpHeaders ; import org . springframework . http . HttpInputMessage ; import org . springframework . http . converter . HttpMessageConverter ; import org . springframework . web . bind . annotation . ControllerAdvice ; import org . springframework . web . servlet . mvc . method . annotation . RequestBodyAdvice ; import com . alibaba . fastjson . JSON ; import com . alibaba . fastjson . JSONArray ; /** * RequestBodyAdvice:解释 * 允许在将请求的主体读取和转换成一个对象之前对请求进行自定义, * 并允许在将其传递到控制器方法作为一个@RequestBody或HttpEntity方法参数之前处理结果对象。 * * @author niugang * */ @ControllerAdvice ( basePackages = "com.niugang" ) public class MyRequestBodyAdvice implements RequestBodyAdvice { private final static Logger logger = LoggerFactory . getLogger ( MyRequestBodyAdvice . class );   @Override public boolean supports ( MethodParameter methodParameter , Type targetType , Class <? extends HttpMessageConverter <?>> converterType ) { return true ; }   @Override public Object handleEmptyBody ( Object body , HttpInputMessage inputMessage , MethodParameter parameter , Type targetType , Class <? extends HttpMessageConverter <?>> converterType ) { return body ; }   @Override public HttpInputMessage beforeBodyRead ( HttpInputMessage inputMessage , MethodParameter parameter , Type targetType , Class <? extends HttpMessageConverter <?>> converterType ) throws IOException {   try { return new MyHttpInputMessage ( inputMessage ); } catch ( Exception e ) { e . printStackTrace (); return inputMessage ; } } @Override public Object afterBodyRead ( Object body , HttpInputMessage inputMessage , MethodParameter parameter , Type targetType , Class <? extends HttpMessageConverter <?>> converterType ) { return body ; }   class MyHttpInputMessage implements HttpInputMessage { private HttpHeaders headers ; private InputStream body ; @SuppressWarnings ( "unchecked" ) public MyHttpInputMessage ( HttpInputMessage inputMessage ) throws Exception { String string = IOUtils . toString ( inputMessage . getBody (), "UTF-8" ); Map < String , Object > mapJson = ( Map < String , Object >) JSON . parseObject ( string , Map . class ); Map < String , Object > map = new HashMap < String , Object >(); Set < Entry < String , Object >> entrySet = mapJson . entrySet (); for ( Entry < String , Object > entry : entrySet ) { String key = entry . getKey (); Object objValue = entry . getValue (); if ( objValue instanceof String ) { String value = objValue . toString (); map . put ( key , filterDangerString ( value )); } else { // 针对结合的处理 @SuppressWarnings ( "rawtypes" ) List < HashMap > parseArray = JSONArray . parseArray ( objValue . toString (), HashMap . class ); List < Map < String , Object >> listMap = new ArrayList < Map < String , Object >>(); for ( Map < String , Object > innerMap : parseArray ) { Map < String , Object > childrenMap = new HashMap < String , Object >(); Set < Entry < String , Object >> elseEntrySet = innerMap . entrySet (); for ( Entry < String , Object > en : elseEntrySet ) { String innerKey = en . getKey (); Object innerObj = en . getValue (); if ( innerObj instanceof String ) { String value = innerObj . toString (); childrenMap . put ( innerKey , filterDangerString ( value )); } } listMap . add ( childrenMap ); } map . put ( key , listMap ); } } this . headers = inputMessage . getHeaders (); this . body = IOUtils . toInputStream ( JSON . toJSONString ( map ), "UTF-8" ); }   @Override public InputStream getBody () throws IOException { return body ; }   @Override public HttpHeaders getHeaders () { return headers ; } } private String filterDangerString ( String value ) { if ( value == null ) { return null ; } value = value . replaceAll ( "\\|" , "" ); value = value . replaceAll ( "&" , "" ); value = value . replaceAll ( ";" , "" ); value = value . replaceAll ( "@" , "" ); value = value . replaceAll ( "'" , "" ); value = value . replaceAll ( "\\'" , "" ); value = value . replaceAll ( "<" , "" ); value = value . replaceAll ( "-" , "" ); value = value . replaceAll ( ">" , "" ); value = value . replaceAll ( "\\(" , "" ); value = value . replaceAll ( "\\)" , "" ); value = value . replaceAll ( "\\+" , "" ); value = value . replaceAll ( "\r" , "" ); value = value . replaceAll ( "\n" , "" ); value = value . replaceAll ( "script" , "" ); value = value . replaceAll ( "select" , "" ); value = value . replaceAll ( "\"" , "" ); value = value . replaceAll ( ">" , "" ); value = value . replaceAll ( "<" , "" ); value = value . replaceAll ( "=" , "" ); value = value . replaceAll ( "/" , "" ); return value ; } }

对于以上的配置Controller接收参数需要加@RequestBody。

测试

过滤后的数据

自定义RequestBodyAdvice过滤Json表情符号

/** * @Author: ZhiHao * @Date: 2021/6/4 19:03 * @Description: 过滤表情符号, POST-json请求 * @Versions 1.0 **/ @ControllerAdvice @Slf4j public class FilterEmojiRequestBodyAdvice implements RequestBodyAdvice { @Override public boolean supports ( MethodParameter methodParameter , Type targetType , Class <? extends HttpMessageConverter <?>> converterType ) { Annotation [] annotations = methodParameter . getParameterAnnotations (); for ( Annotation ann : annotations ) { Validated validatedAnn = AnnotationUtils . getAnnotation ( ann , Validated . class ); if ( validatedAnn != null || ann . annotationType (). getSimpleName (). startsWith ( "Valid" )) { return true ; } } return false ; } @Override public HttpInputMessage beforeBodyRead ( HttpInputMessage inputMessage , MethodParameter parameter , Type targetType , Class <? extends HttpMessageConverter <?>> converterType ) throws IOException { return inputMessage ; } @Override public Object afterBodyRead ( Object body , HttpInputMessage inputMessage , MethodParameter parameter , Type targetType , Class <? extends HttpMessageConverter <?>> converterType ) { try { this . filterEmojiAfterBody ( body ); } catch ( Exception e ) { log . info ( "过滤表情异常:{}" , e ); } return body ; } private void filterEmojiAfterBody ( Object body ) throws IllegalAccessException { if ( null != body ) { Field [] fields = ReflectUtil . getFields ( body . getClass ()); for ( int i = 0 ; i < fields . length ; i ++) { Field field = fields [ i ]; if ( field . isAnnotationPresent ( Valid . class )) { field . setAccessible ( true ); this . filterEmojiAfterBody ( field . get ( body )); } if ( field . isAnnotationPresent ( FilterEmoji . class )) { field . setAccessible ( true ); Object value = field . get ( body ); if ( value instanceof String ) { String str = filterEmoji ( value . toString ()); field . set ( body , str ); } } } } } @Override public Object handleEmptyBody ( Object body , HttpInputMessage inputMessage , MethodParameter parameter , Type targetType , Class <? extends HttpMessageConverter <?>> converterType ) { return body ; } /** * 过滤emoji 或者 其他非文字类型的字符 * * @param source * @return */ public static String filterEmoji ( String source ) { if ( StringUtils . isEmpty ( source )) { return "" ; } if (! containsEmoji ( source )) { return source ; //如果不包含,直接返回 } StringBuilder buf = new StringBuilder (); int len = source . length (); for ( int i = 0 ; i < len ; i ++) { char codePoint = source . charAt ( i ); if ( isNotEmojiCharacter ( codePoint )) { buf . append ( codePoint ); } } return buf . toString (). trim (); } /** * 检测是否有emoji字符 * * @param source * @return 一旦含有就抛出 */ public static boolean containsEmoji ( String source ) { if ( StringUtils . isBlank ( source )) { return false ; } int len = source . length (); for ( int i = 0 ; i < len ; i ++) { char codePoint = source . charAt ( i ); if (! isNotEmojiCharacter ( codePoint )) { //判断到了这里表明,确认有表情字符 return true ; } } return false ; } /** * 判断是否为非Emoji字符 * * @param codePoint 比较的单个字符 * @return */ public static boolean isNotEmojiCharacter ( char codePoint ) { return ( codePoint == 0x0 ) || ( codePoint == 0x9 ) || ( codePoint == 0xA ) || ( codePoint == 0xD ) || (( codePoint >= 0x20 ) && ( codePoint <= 0xD7FF )) || (( codePoint >= 0xE000 ) && ( codePoint <= 0xFFFD )) || (( codePoint >= 0x10000 ) && ( codePoint <= 0x10FFFF )); } }

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

原文链接:https://blog.csdn.net/niugang0920/article/details/80679096

查看更多关于使用RequestBodyAdvice实现对Http请求非法字符过滤的详细内容...

  阅读:13次