需求描述,Controller接口定义的返回实体类型,但是前端需要jsonp格式,就是传入callback参数时,对返回的数据进行包裹::形如callback(data),现在需要一个统一的方法对所有的Controller添加返回数据格式修改,尝试使用了AOP,但是AOP的返回值会转型为Controller接口定义的类型,对于JSONP返回的字符串类型来说肯定是不行的,于是有了以下方法
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Map;
@WebFilter(urlPatterns = "/*", filterName = "callbackFilter")
public class ResponseFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
//获取参数
Map<String, String[]> params = request.getParameterMap();
String key;
//查找有没有callback或者cb参数
if (!params.containsKey("callback")) {
if (!params.containsKey("cb")) {
filterChain.doFilter(request, response);
return;
}
key = "cb";
} else {
key = "callback";
}
String callback = "";
String[] param = params.get(key);
if (param != null && param.length > 0) {
callback = param[0];
}
MyResponseWrapper responseWrapper = new MyResponseWrapper((HttpServletResponse) response);
// 这里只拦截返回,直接让请求过去,如果在请求前有处理,可以在这里处理
filterChain.doFilter(request, responseWrapper);
byte[] content = responseWrapper.getContent();
String str = new String(content, "UTF-8");
// System.out.println(str);
str = callback + "(" + str + ")";
//把返回值输出到客户端
ServletOutputStream out = response.getOutputStream();
byte[] re = str.getBytes("UTF-8");
response.setContentLength(re.length);//重新设置返回长度
out.write(re);
}
private class MyResponseWrapper extends HttpServletResponseWrapper {
private ByteArrayOutputStream buffer;
private ServletOutputStream out;
public MyResponseWrapper(HttpServletResponse httpServletResponse) {
super(httpServletResponse);
buffer = new ByteArrayOutputStream();
out = new WrapperOutputStream(buffer);
}
@Override
public ServletOutputStream getOutputStream()
throws IOException {
return out;
}
@Override
public void flushBuffer()
throws IOException {
if (out != null) {
out.flush();
}
}
public byte[] getContent()
throws IOException {
flushBuffer();
return buffer.toByteArray();
}
class WrapperOutputStream extends ServletOutputStream {
private ByteArrayOutputStream bos;
public WrapperOutputStream(ByteArrayOutputStream bos) {
this.bos = bos;
}
@Override
public void write(int b)
throws IOException {
bos.write(b);
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setWriteListener(WriteListener arg0) {
}
}
}
@Override
public void init(FilterConfig arg0)
throws ServletException {
}
@Override
public void destroy() {
}
}
使用@WebFilter 注解时,需要在启动类加上@ServletComponentScan
不使用@WebFilter 注解也可以使用手动注册,实现自定义扫描路径
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component
public class ResponseFilterConfig {
@Value("${jsonp-filter-urlPatterns:/*}")
private String patterns;
@Bean
public FilterRegistrationBean setFilter(){
FilterRegistrationBean filterBean = new FilterRegistrationBean();
filterBean.setFilter(new ResponseFilter());
filterBean.setName("callbackFilter");
String[] patternStr=patterns.split(",");
filterBean.addUrlPatterns(patternStr);
return filterBean;
}
}
yml添加参数设置扫描路径,不设置时缺省值为 /*,即扫描全路径
jsonp-filter-urlPatterns: /user/getList,/user/get
修改Response参考博客:https://blog.csdn.net/u011974797/article/details/81315503
Filter两种实现参考博客: https://blog.csdn.net/qq_27905183/article/details/79078561
版权声明:本文为rui15111原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。