1.过滤器的应用场景
自定义过滤器实现filter接口,注册到WEB容器即可。既然是实现接口,那么我们就可以实现多个过滤器并用order来定义执行顺序。下面依次为大家展示下面几个应用场景的部分示例代码。
1.自动登录
2.统一设置编码格式
3.访问权限控制
4.敏感字符过滤等
1.1 自动登录
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
Operator user = (Operator) req.getSession().getAttribute("USER");
String requestURI = req.getRequestURI();
if(user == null && !("login").equals(requestURI)){
Cookie autologin = getCookieByName(req.getCookies(), "AUTOLOGIN");
if(autologin!= null){
String value = autologin.getValue();
UserService service = new UserServiceImpl();
user = service.login(value);
req.setAttribute("USER",user);
}
}
chain.doFilter(req,resp);
}
1.2.设置统一编码格式
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
request.setCharacterEncoding("utf-8");
chain.doFilter(request,response);
}
1.3. 参数去重
参数格式常见的分为表单参数和JSON格式参数,针对这两种参数格式进行去重
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
ServletRequest requestWrapper = null;
if (request instanceof HttpServletRequest) {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String methodType = httpRequest.getMethod();
if ("POST".equals(methodType) && ContentType.APPLICATION_JSON.getMimeType().equals(request.getContentType())) {
requestWrapper = new RequestPostJsonWrapper(
(HttpServletRequest) request);
}else if(ContentType.MULTIPART_FORM_DATA.getMimeType().equals(request.getContentType())){
requestWrapper = new RequestParamWrapper((HttpServletRequest) request);
}
}
if (null == requestWrapper) {
chain.doFilter(request, response);
} else {
chain.doFilter(requestWrapper, response);
}
}
这里用到了继承HttpServletRequestWrapper装饰器类,对我们的请求对象进行改装
1.3.1 RequestParamWrapper 表单参数处理
private Map<String, String[]> params = new HashMap<>();
public RequestParamWrapper(HttpServletRequest request) throws IOException {
super(request);
this.params.putAll(request.getParameterMap());
this.trimParamValues();
}
private void trimParamValues(){
Set<Map.Entry<String,String[]>> entrys = params.entrySet();
for(Map.Entry<String,String[]> entry :entrys) {
String[] values=entry.getValue();
for(int i=0;i<values.length;i++) {
values[i] = values[i].trim();
}
this.params.put(entry.getKey(), values);
}
}
@Override
public Enumeration<String> getParameterNames() {
return new Vector<String>(params.keySet()).elements();
}
@Override
public String getParameter(String name) {
String[] values = params.get(name);
if (values == null || values.length == 0) {
return null;
}
return values[0];
}
@Override
public String[] getParameterValues(String name) {
return params.get(name);
}
@Override
public Map<String,String[]> getParameterMap(){
return this.params;
}
1.3.2 RequestPostJsonWrapper JSON参数处理,因为JSON参数通过nputStream只能读取一次,会导致action层拿不到参数对象,所以要返回一个新的InputStream对象。
private final byte[] body;
private String bodyStr;
public RequestPostJsonWrapper(HttpServletRequest request) throws IOException {
super(request);
String bodyString = getBodyString(request);
bodyString = trimJsonStr(bodyString);
body = bodyString.getBytes(Charset.forName("UTF-8"));
bodyStr=bodyString;
}
public String getBodyStr() {
return bodyStr;
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body);
return new ServletInputStream() {
@Override
public int read() throws IOException {
return byteArrayInputStream.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
};
}
public String getBodyString(HttpServletRequest request) throws IOException {
StringBuilder sb = new StringBuilder();
InputStream inputStream = null;
BufferedReader reader = null;
try {
inputStream = request.getInputStream();
reader = new BufferedReader(
new InputStreamReader(inputStream, Charset.forName("UTF-8")));
char[] bodyCharBuffer = new char[1024];
int len = 0;
while ((len = reader.read(bodyCharBuffer)) != -1) {
sb.append(new String(bodyCharBuffer, 0, len));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}
private String trimJsonStr(String bodyString){
JSONObject jsonObject = JSONObject.parseObject(bodyString);
Set<String> strings = jsonObject.keySet();
strings.stream().forEach(key->{
String value = jsonObject.getString(key);
if(value != ""){
jsonObject.put(key,value.trim());
}
});
return jsonObject.toJSONString();
}
2. 结语
过滤器在我们的开发过程中起到了不可忽视的作用,在我们的许多优秀的框架中都运用到了它。所以熟练的掌握这项技术是必不可少的,那么与过滤器比较相近的就是拦截器,下一篇我们来了解拦截器吧。