版权声明:本文为博主原创文章,未经博主允许不得转载。否则切鸡鸡~~ https://blog.csdn.net/kang5789/article/details/83015324
为什么写拦截器呢 ?是因为在项目中遇到了一个大坑!!!
项目中用拦截器操作了request,之后在controller使用@ResponseBody会报错,具体错误就是说request已经被使用过了,一次请求只能操作一次request
解决方法就是在内存中复制一份
拦截器:
package com.example.config;
import java.text.SimpleDateFormat;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
@Configuration
public class TokenAdapter extends WebMvcConfigurerAdapter {
@Bean
public TokenInterceptor myInterceptor() {
return new TokenInterceptor();
}
// 自定义json返回的转换器,null值不返回
@Bean
public MappingJackson2HttpMessageConverter customJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.setSerializationInclusion(Include.NON_NULL);
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
jsonConverter.setObjectMapper(objectMapper);
return jsonConverter;
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(customJackson2HttpMessageConverter());
super.configureMessageConverters(converters);
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
registry.addResourceHandler("/templates/**").addResourceLocations("classpath:/templates/");
super.addResourceHandlers(registry);
}
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myInterceptor())//
// addPathPatterns 用于添加拦截规则
.addPathPatterns("/**")//
.excludePathPatterns("/error");
super.addInterceptors(registry);
}
}
package com.example.config;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import com.example.utils.Result;
/**
* token拦截器,验证请求是否合理,使用请参考 com.jk.ehr.sso的 TokenAdapter
*
*/
@Component
public class TokenInterceptor implements HandlerInterceptor {
// 在请求处理之前进行调用(Controller方法调用之前)
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
// 校验url
String token = request.getParameter("token");
if (StringUtils.isNotEmpty(token)) {
return true;
}
// 校验请求体
CloneRequestWrapper myRequestWrapper = new CloneRequestWrapper((HttpServletRequest) request);
String body = myRequestWrapper.getBody();
if (StringUtils.isNotEmpty(body)) {
@SuppressWarnings("unchecked")
Map<String, Object> map = JSON.parseObject(body, Map.class);
token = String.valueOf(map.get("token"));
if (StringUtils.isNotEmpty(token)) {
return true;
}
}
Result result = Result.error(Result.RESULT_ERROR, "token验证错误");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
response.getWriter().write(JSON.toJSONString(result));
return false;
}
// 在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception {
}
// 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
@Override
public void postHandle(HttpServletRequest servletRequest, HttpServletResponse servletResponse, Object arg2, ModelAndView arg3) throws Exception {
}
}
复制request
package com.example.config;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import org.springframework.context.annotation.Configuration;
@Configuration
@WebFilter(urlPatterns = "/*")
public class CloneRequestFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
ServletRequest requestWrapper = null;
if (request instanceof HttpServletRequest) {
requestWrapper = new CloneRequestWrapper((HttpServletRequest) request);
}
if (requestWrapper == null) {
chain.doFilter(request, response);
} else {
chain.doFilter(requestWrapper, response);
}
}
@Override
public void destroy() {
}
}
package com.example.config;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class CloneRequestWrapper extends HttpServletRequestWrapper {
private final String body;
public CloneRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
InputStream inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
body = stringBuilder.toString();
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
ServletInputStream servletInputStream = new ServletInputStream() {
public boolean isFinished() {
return false;
}
public boolean isReady() {
return false;
}
public void setReadListener(ReadListener readListener) {
}
public int read() throws IOException {
return byteArrayInputStream.read();
}
};
return servletInputStream;
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
public String getBody() {
return this.body;
}
}