springboot--拦截器

版权声明:本文为博主原创文章,未经博主允许不得转载。否则切鸡鸡~~ 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;
	}

}

猜你喜欢

转载自blog.csdn.net/kang5789/article/details/83015324
今日推荐