实现这个需求有2个方法
其中一些jar包
<!-- Springboot 环境 -->
<dependency>
<groupId>com.vdurmont</groupId>
<artifactId>emoji-java</artifactId>
<version>5.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.70</version>
</dependency>
方法一: 过滤器(Filter)
主要类:
EmojiFilter --> 过滤器
ParamsRequestWrapper -->参数过滤操作
FilterConfig -->配置filter
EmojiFilter:
public class EmojiFilter extends OncePerRequestFilter {
private static final String POST = "POST";
private static final String PUT = "PUT";
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
//只过滤post和put的请求,不然直接返回
if (!request.getMethod().equals(POST) && !request.getMethod().equals(PUT)) {
chain.doFilter(request, response);
return;
}
//执行过滤detail
EmojiRequestWrapper requestWrapper = new EmojiRequestWrapper(request);
chain.doFilter(requestWrapper, response);
}
}
public class EmojiFilter implements Filter {
private static final String POST = "POST";
private static final String PUT = "PUT";
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
if (!request.getMethod().equals(POST) && !request.getMethod().equals(PUT)) {
return;
}
EmojiRequestWrapper requestWrapper = new EmojiRequestWrapper(request);
chain.doFilter(requestWrapper, response);
}
@Override
public void destroy() {
}
}
EmojiRequestWrapper.java
json格式的提交
public class EmojisRequestWrapper extends HttpServletRequestWrapper {
/**
* ENCODING
*/
private static final String ENCODING = "UTF-8";
public EmojiRequestWrapper(HttpServletRequest request) {
super(request);
}
/**
* 字符串去除emoji的方法
*/
private String convertEmoji2Str(String source) {
if(EmojiManager.containsEmoji(source)){
EmojiParser.removeAllEmojis(source);
}
return s;
}
/**
* 重写getInputStream方法 post请求参数必须通过流才能获取到值
*/
@Override
public ServletInputStream getInputStream() throws IOException {
String json = "{}";
try (ServletInputStream stream = super.getInputStream();){
// 非json类型,直接返回
if (!MediaType.APPLICATION_JSON_VALUE.equals(super.getHeader(HttpHeaders.CONTENT_TYPE))
&& !MediaType.APPLICATION_JSON_UTF8_VALUE.equals(super.getHeader(HttpHeaders.CONTENT_TYPE))) {
return stream;
}
// 转化成字符串
json = IOUtils.toString(stream, ENCODING);
if (StringUtils.isBlank(json)) {
return stream;
}
} catch (Exception e) {
}
//去除表情并返回
String noEmojiStr = convertEmoji2Str(json);
// 写回request
ByteArrayInputStream bis = new ByteArrayInputStream(noEmojiStr.getBytes(ENCODING));
return bis.read();
}
}
可以获取提交的form表单,不是json提交
public class EmojiRequestWrapper extends HttpServletRequestWrapper {
private Map<String, String[]> params = new HashMap();
private static final String ENCODING = "UTF-8";
private static final String CLASSTYPE = "java.lang.String";
public EmojiRequestWrapper(HttpServletRequest request) {
super(request);
Map<String, String[]> requestMap = request.getParameterMap();
String s = JSON.toJSONString(requestMap);
if (!EmojiManager.containsEmoji(s)) {
return;
}
String json = EmojiParser.removeAllEmojis(s);
// 处理json数据,parseObject数组返回的是JSONArray,需要处理
Map<String, JSONArray> map = JSON.parseObject(json, Map.class);
map.forEach((k, v) -> {
Object o = v.get(0);
this.params.put(k, new String[] {
(String) o});
});
}
private Map<String, Object> modifyParams( String json) {
String s = convertEmoji2Str(json);
Map map = JSON.parseObject(s, Map.class);
return map;
}
@Override
public Map getParameterMap() {
return this.params;
}
@Override
public Enumeration getParameterNames() {
Vector l = new Vector(params.keySet());
return l.elements();
}
@Override
public String[] getParameterValues(String name) {
Object v = params.get(name);
if (v == null) {
return null;
} else if (v instanceof String[]) {
return (String[]) v;
} else if (v instanceof String) {
return new String[]{
(String) v};
} else {
return new String[]{
v.toString()};
}
}
@Override
public String getParameter(String name) {
Object v = params.get(name);
if (v == null) {
return null;
} else if (v instanceof String[]) {
String[] strArr = (String[]) v;
if (strArr.length > 0) {
return strArr[0];
} else {
return null;
}
} else if (v instanceof String) {
return (String) v;
} else {
return v.toString();
}
}
}
可以参考这篇博客:https://www.jianshu.com/p/ab6ab47fcbd8
配置filter
第一种:FilterConfig:
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean parmsFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new EmojiFilter());
registration.addUrlPatterns("/*");
registration.setName("emojiFilter");
registration.setOrder(Integer.MAX_VALUE - 1);
return registration;
}
}
第二种:
@WebFilter(filterName = "emojiFilter", urlPatterns = "/*")
@Order(Integer.MAX_VALUE - 1)
public class EmojiFilter implements Filter {
}
@ServletComponentScan
//Springboot 启动类
@SpringBootApplication
public class Application{
}{
}
方法二:aop (AspectJ)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
spring:
aop:
auto: true
@SpringBootApplication
@EnableAspectJAutoProxy
public class Application {
}
RequestParamterAspect.java
@Aspect
@Slf4j
@Component
public class RequestParamterAspectJ {
/**
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)
modifiers-pattern : 方法的修饰符 public protected
ret-type-patter 方法返回值类型, 比如void
declaring-type-pattern 类的路径 com.java.
name-pattern 方法名称 Aa()
param-parttern 方法参数类型 如java.lang.String
throws-pattern 方法抛出异常的类型,如Java.lang.Exception
* 通配符,该通配符主要用于匹配单个单词,或者是以某个词为前缀或后缀的单词
..通配符,该通配符表示0个或多个项,主要用于declaring-type-pattern和param-pattern中,如果用于declaring-type-pattern中,则表示匹配当前包及其子包,如果用于param-pattern中,则表示匹配0个或多个参数
* execution(public * com.spring.service.BusinessObject.businessService(java.lang.String,..))
* */
@Pointcut("execution(public * com.lsm.boot.controller.*Controller.*(..))")
public void pointcut() {
}
/**
* 这里只能是Around ,因为使用的是ProceedingJoinPoint
* @param joinPoint
* @return
* @throws Throwable
*/
@Around("pointcut()")
public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable {
// 方法执行前
Object[] args = joinPoint.getArgs();
String json = JSON.toJSONString(args);
//去 除 emoji
for (Object arg : args) {
System.out.println(arg);
}
// 方法执行 joinPoint.proceed()执行了目标方法
Object proceed = joinPoint.proceed(args);
// proceed 就是controller返回值
System.out.println(proceed);
return proceed;
}
}
aop Aspect文章
https://blog.csdn.net/loveyour_1314/article/details/108850282
总结
HTTP的POST请求中如果传入的是json类型的数据的话必须要重写getInputStream()【详细看EmojisRequestWrapper.getInputStream()】,此时可以不重写getParameterMap(),getParameter(String name)之类的request的方法,直接在getInputStream()用流写回去就可以了
HTTP的POST请求中如果传入的直接是form表单,不需要重写getInputStream(),直接使用 request.getParameterMap()就可以获取到,但是需要重写getParameterMap(),getParameter(String name),不然你修改的数据无法修改回去。
参考资料
https://www.jianshu.com/p/ab6ab47fcbd8
https://zhuanlan.zhihu.com/p/81936836
https://www.cnblogs.com/timeflying/p/11523314.html
https://blog.csdn.net/HouXinLin_CSDN/article/details/108430756