赞
踩
原文连接:http://www.360doc.com/document/19/0106/20/39911641_807065847.shtml
原文连接中有对 可重复读 和 验签业务逻辑的大致说明
编写 RequestWrapper类 extends HttpServletRequestWrapper
- package com.xihongshi.common.filter;
-
- import lombok.extern.slf4j.Slf4j;
- import javax.servlet.ReadListener;
- import javax.servlet.ServletInputStream;
- import javax.servlet.ServletRequest;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletRequestWrapper;
- import java.io.*;
- import java.nio.charset.Charset;
-
- /**
- * @author mgq
- * @since 2021-03-30 9:59
- */
- @Slf4j
- public class RequestWrapper extends HttpServletRequestWrapper {
- /**
- * 存储body数据
- */
- private final byte[] body;
- public RequestWrapper(final HttpServletRequest request) {
- super(request);
- // 将body数据存储起来
- String bodyStr=getBodyString(request);
- // 初始化body
- body = bodyStr.getBytes(Charset.defaultCharset());
- }
-
- public String getBodyString(ServletRequest request) {
- try {
- return inputStream2String(request.getInputStream());
- } catch (IOException e) {
- log.error("",e);
- throw new RuntimeException(e);
- }
- }
-
- public String getBodyString() {
- final InputStream byteArrayInputStream = new ByteArrayInputStream(body);
- return inputStream2String(byteArrayInputStream);
- }
-
- private String inputStream2String(InputStream inputStream) {
- StringBuilder sb = new StringBuilder();
- BufferedReader reder = null;
- try {
- reder=new BufferedReader(new InputStreamReader(inputStream,Charset.defaultCharset()));
- String line;
- while ((line=reder.readLine())!=null){
- sb.append(line);
- }
- } catch (Exception e) {
- log.error("",e);
- throw new RuntimeException(e);
- }finally {
- if (reder!=null) {
- try {
- reder.close();
- } catch (IOException e) {
- log.error("",e);
- }
- }
- }
- return sb.toString();
- }
-
- @Override
- public BufferedReader getReader() throws IOException {
- return new BufferedReader(new InputStreamReader(getInputStream()));
- }
-
- @Override
- public ServletInputStream getInputStream() throws IOException {
- final ByteArrayInputStream inputStream = new ByteArrayInputStream(body);
-
- return new ServletInputStream() {
- @Override
- public boolean isFinished() {
- return false;
- }
-
- @Override
- public boolean isReady() {
- return false;
- }
-
- @Override
- public void setReadListener(final ReadListener readListener) {
-
- }
-
- @Override
- public int read() throws IOException {
- return inputStream.read();
- }
- };
- }
- }
编写 ReplaceStreamFilter类,implements Filter
- package com.xihongshi.common.filter;
-
- import lombok.extern.slf4j.Slf4j;
-
- import javax.servlet.*;
- import javax.servlet.FilterConfig;
- import javax.servlet.http.HttpServletRequest;
- import java.io.IOException;
-
- /**
- * @author mgq
- * @since 2021-03-30 10:20
- */
- @Slf4j
- public class ReplaceStreamFilter implements Filter {
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {
- log.info("StreamFilter初始化");
- }
-
- @Override
- public void doFilter(final ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
- ServletRequest requestWrapper = new RequestWrapper((HttpServletRequest) request);
- chain.doFilter(requestWrapper,response);
- }
-
- @Override
- public void destroy() {
- log.info("StreamFilter销毁");
- }
- }
编写JWTInterceptor类,implements HandlerInterceptor 用于测试从request的body中取数据,验证后续接口是否能接收到@requestBody中的数据
- package com.xihongshi.client.interceptor;
-
- import com.auth0.jwt.JWT;
- import com.xihongshi.common.constants.RedisConstants;
- import com.xihongshi.common.errcode.BizErrorCodeEnum;
- import com.xihongshi.common.exception.BizException;
- import com.xihongshi.common.exception.InvalidSessionException;
- import com.xihongshi.common.filter.RepeatableRequestWrapper;
- import com.xihongshi.common.filter.RequestWrapper;
- import com.xihongshi.utils.JwtUtils;
- import com.xihongshi.utils.RedisUtil;
- import lombok.extern.slf4j.Slf4j;
- import me.chanjar.weixin.common.util.SignUtils;
- import org.slf4j.MDC;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.web.servlet.HandlerInterceptor;
- import org.springframework.web.servlet.ModelAndView;
-
- import javax.servlet.ServletInputStream;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.BufferedReader;
- import java.io.InputStream;
-
- /**
- *
- * @author: mengshaoshuai
- * @date 2021年3月12日 下午1:51:20
- */
- @Slf4j
- public class JWTInterceptor implements HandlerInterceptor {
-
- @Value("${client.auth.test.enabled:false}")
- private boolean authTestEnabled = false;
- @Value("${client.auth.test.accountId:}")
- private Integer authTestAccountId;
-
- @Autowired
- JwtUtils jwtUtils;
-
- @Autowired
- RedisUtil redisUtil;
-
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
- throws Exception {
- String token = request.getHeader("token");
- String sb = new RequestWrapper(request).getBodyString();
- System.out.println(sb);
- try {
- jwtUtils.verify(token);
- } catch (Exception e) {
- if(authTestEnabled) {
-
- //test
- request.setAttribute("unionId", authTestAccountId+"");
- request.setAttribute("accountId", authTestAccountId+"");
- }else{
- throw new InvalidSessionException(BizErrorCodeEnum.JWT_TOKEN_ERROR);
- }
- return true;
- }
- String id = JWT.decode(token).getAudience().get(0);
- String tknow = (String)redisUtil.get(RedisConstants.JWT_KEY_ACCOUNT+id);
- if(tknow==null || !tknow.equals(token)) {
- throw new BizException(BizErrorCodeEnum.JWT_TOKEN_EXPIRE);
- }
- String mobile = JWT.decode(token).getClaim("mobile").asString();
- request.setAttribute("accountId", id);
- request.setAttribute("unionId", mobile);
- return true;
- }
-
- @Override
- public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
- clearMdc();
- }
-
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
- clearMdc();
- }
-
- /**
- * 清理日志上下文
- */
- protected void clearMdc() {
- try {
- MDC.clear();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- }
第四步
过滤配置类
注意:第四不和第五步必须配置,要不然1和2步骤不生效
- package com.xihongshi.client.interceptor;
-
- import com.xihongshi.common.filter.RepeatableReadFilter;
- //import com.xihongshi.common.filter.ReplaceStreamFilter;
- import com.xihongshi.common.filter.ReplaceStreamFilter;
- import org.springframework.boot.web.servlet.FilterRegistrationBean;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
-
- import javax.servlet.Filter;
-
- /**
- * 过滤配置类
- * @author mgq
- * @since 2021-03-30 10:52
- */
- @Configuration
- public class FilterConfig {
-
- /**
- * 注册过滤器
- * @return
- */
- @Bean
- public FilterRegistrationBean someFilterRegistration(){
- FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
- filterRegistrationBean.setFilter(replaceStreamFilter());
- filterRegistrationBean.addUrlPatterns("/*");
- filterRegistrationBean.setName("streamFilter");
- return filterRegistrationBean;
- }
-
- /**
- * 实例化StreamFilter
- * @return
- */
- @Bean(name="replaceStreamFilter")
- public Filter replaceStreamFilter(){
- return new ReplaceStreamFilter();
- }
- }
第五步
拦截器配置
- package com.xihongshi.client.interceptor;
-
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.web.servlet.HandlerInterceptor;
- import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
- import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-
- /**
- * 拦截器配置
- * @author mgq
- * @since 2021-03-30 11:12
- */
- @Slf4j
- @Configuration
- public class InterceptorConfig implements WebMvcConfigurer {
- @Bean
- public JWTInterceptor getJWTInterceptor(){
- return new JWTInterceptor();
- }
-
- @Override
- public void addInterceptors(InterceptorRegistry registry) {
- registry.addInterceptor(getJWTInterceptor())
- .addPathPatterns("/**");
- }
- }
第六步
随便写一个controller接口,在接口中调用参数是@requestbody 接收的json对象
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。