欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

spring boot 添加自定义拦截器过滤器 Content-Type=application/json 格式的参数请求方式处理

程序员文章站 2022-03-18 16:14:22
...

 Content-Type=application/json 格式的参数请求方式处理

用postman测试

spring boot 添加自定义拦截器过滤器 Content-Type=application/json 格式的参数请求方式处理

spring boot 添加自定义拦截器过滤器 Content-Type=application/json 格式的参数请求方式处理

后台处理步骤:

一、 添加过滤器:

Content-Type=application/json 格式的参数数据接收是通过流的形式接收的。流读取一次就没有了,如果只用拦截器里直接获取参数流统一验证后,再转到control层参数肯定就没了。所以这个需要先把流读取出来再放进去。

1,

Application.java 加入注解@ServletComponentScan控制过滤器

2,添加过滤器实现类 

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@WebFilter(filterName="httpServletRequestReplacedFilter",urlPatterns={"/*"})// TODO 多个用逗号分隔
public class HttpServletRequestReplacedFilter implements Filter {
    @Override
    public void destroy() {
        System.out.println("--------------过滤器销毁------------");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {
        ServletRequest requestWrapper = null;
        if(request instanceof HttpServletRequest) {
            requestWrapper = new MyHttpServletRequestWrapper((HttpServletRequest) request);
        }
        if(requestWrapper == null) {
            chain.doFilter(request, response);
        } else {
            chain.doFilter(requestWrapper, response);
        }
    }
    @Override
    public void init(FilterConfig arg0) throws ServletException {
        System.out.println("--------------过滤器初始化------------");
    }

}

 2,自定义请求实现HttpServletRequestWrapper

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;
public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper {
    private final byte[] body;

    public MyHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        String sessionStream = getBodyString(request);
        body = sessionStream.getBytes(Charset.forName("UTF-8"));
    }

    /**
     * 获取请求Body
     *
     * @param request
     * @return
     */
    public String getBodyString(final ServletRequest request) {
        StringBuilder sb = new StringBuilder();
        InputStream inputStream = null;
        BufferedReader reader = null;
        try {
            inputStream = cloneInputStream(request.getInputStream());
            reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
            String line = "";
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        }
        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();
    }

    /**
     * 复制输入流
     *
     * @param inputStream
     * @return</br>
     */
    public InputStream cloneInputStream(ServletInputStream inputStream) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len;
        try {
            while ((len = inputStream.read(buffer)) > -1) {
                byteArrayOutputStream.write(buffer, 0, len);
            }
            byteArrayOutputStream.flush();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        InputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
        return byteArrayInputStream;
    }
    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {

        final ByteArrayInputStream bais = new ByteArrayInputStream(body);

        return new ServletInputStream() {

            @Override
            public int read() throws IOException {
                return bais.read();
            }

            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener readListener) {
            }
        };
    }
}

二,拦截器  

1,添加拦截器配置

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@SpringBootApplication
public class InterceptorConfig extends WebMvcConfigurerAdapter {
    @Bean
    public ApiParameterInterceptor apiParameterInterceptor() {
        return new ApiParameterInterceptor();
    }

    public void addInterceptors(InterceptorRegistry registry) {
        // addPathPatterns 添加拦截规则
        registry.addInterceptor(apiParameterInterceptor())
                .addPathPatterns("/*") // 添加需要拦截请求的路径
                //.excludePathPatterns("/*") // 去除拦截请求的路径
    }

}

 2,添加自定义拦截器ApiParameterInterceptor.java

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.newcapec.cloudPay.model.BaseTermResource;
import com.newcapec.cloudPay.service.CacheCommonService;
import com.newcapec.cloudPay.utils.DateUtil;
import com.newcapec.cloudPay.utils.SignUtils;
import com.newcapec.cloudPay.utils.StringUtils;
import com.newcapec.core.utils.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class ApiParameterInterceptor implements HandlerInterceptor {
    private static final Logger log = LoggerFactory.getLogger(ApiParameterInterceptor.class);
    @Autowired
    private CacheCommonService cacheCommonService;

    /**
     * 在controller处理之前首先对请求验证参数验签处理。
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("---------------拦截器参数验签------------------");
        JSONObject responseJson = new JSONObject();
        try {
            response.setHeader("Content-type", "application/json;charset=UTF-8");
            String requestMethord = request.getRequestURI();//请求方法
            if (requestMethord == null) {
                return false;
            }

            // 获取Content-Type=application/json 请求参数
            JSONObject parameterMap = JSON.parseObject(new MyHttpServletRequestWrapper(request).getBodyString(request));
            System.out.println("请求参数" + parameterMap);
            
            if (!parameterMap.containsKey("timestamp")) {
                responseJson.put("retcode", "-1");
                responseJson.put("retmsg", "The request parameter timestamp is not existent !");
                ajaxResponseJsonReturn(response, request, responseJson);
                return false;
            }
            String ts = parameterMap.get("timestamp").toString();
            String dateNow = DateUtils.formatNow(DateUtils.DEFALUT_DATETIME_PATTERN_THREE);
            long min = StringUtils.dateDiff(DateUtil.timeStamp2Date(ts, "yyyyMMddHHmmss"), dateNow, "yyyyMMddHHmmss", "m");
            // 1分钟请求参数时间超时验证 
            if (Math.abs(min) > 1) { 
                log.error("active>=时间戳超时ts:{},dateNow:{}", DateUtil.timeStamp2Date(ts, "yyyyMMddHHmmss"), dateNow);
                responseJson.put("retcode", "6");
                responseJson.put("retmsg", "request param timeout");
                ajaxResponseJsonReturn(response, request, responseJson);
                return false;
            }
            if (!parameterMap.containsKey("sign")) {
                responseJson.put("retcode", "-1");
                responseJson.put("retmsg", "The request parameter sign is not existent !");
                ajaxResponseJsonReturn(response, request, responseJson);
                return false;
            }
            
            String sign = parameterMap.get("sign").toString();
            if (!parameterMap.containsKey("jsondata")) {
                responseJson.put("retcode", "-1");
                responseJson.put("retmsg", "The request parameter jsondata is not existent !");
                ajaxResponseJsonReturn(response, request, responseJson);
                return false;
            }

            JSONObject jsondataJson = JSONObject.parseObject(JSONObject.toJSONString(parameterMap.get("jsondata")));
            
            String paramStr = SignUtils.getJsonStr2Sign(parameterMap);
            paramStr += "&key=" + app_key; //

            // 对paramStr 字符串 进行 HmacSHA1加密,获取签名
            String newsign = SignUtils.getSignature(paramStr, app_key).toUpperCase();
            log.info("根据参数生成的新签名:" + newsign);
            if (!sign.equals(newsign)) { // 验签
                responseJson.put("retcode", "-1");
                responseJson.put("retmsg", "signature failure ! ");
                ajaxResponseJsonReturn(response, request, responseJson);
                return false;
            }

        } catch (Exception e) {
            log.error("接口调用异常:", e);
            e.printStackTrace();
            responseJson.put("retcode", "-1");
            responseJson.put("retmsg", "接口调用异常");
            ajaxResponseJsonReturn(response, request, responseJson);
            return false;
        }
        log.info("验签通过。");
        return true;
    }

    //    @Override
//    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
//        System.out.println("---------------拦截器方法二开始------------------");
//    }
//
//    @Override
//    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
//        System.out.println("---------------拦截器方法三开始------------------");
//    }
    protected void ajaxResponseJsonReturn(HttpServletResponse response, HttpServletRequest request, JSONObject responseJson) throws IOException {
/*        Map<String, String[]> map = request.getParameterMap();
        Map<String ,String > resultMap = new LinkedHashMap<>();
        for (Map.Entry<String, String[]> me : map.entrySet()) {
            String paramName = me.getKey();
            resultMap.put(paramName,request.getParameter(paramName));
        }
        System.out.println("request"+resultMap);*/

        response.setCharacterEncoding("UTF-8");//Constant.ENCODE_UTF8
        response.setContentType("application/json; charset=utf-8");
        PrintWriter out = response.getWriter();
        out.print(responseJson.toJSONString());
        out.flush();
        out.close();
    }
}

三,控制层处理,拦截器对共同验证后,就到了控制层:

    @RequestMapping(value = "test", method = {RequestMethod.POST})
    @ResponseBody
    public JSONObject active(@RequestBody RequestParam requestParam ) throws Exception { // RequestParam 按照指定的标准请求json格式,设计接收实体
        JSONObject responseJson = new JSONObject();
        // 业务参数数据获取
        JSONObject jsondata = 
        JSONObject.parseObject(JSONObject.toJSONString(payComRequest.getJsondata()));
        system.out.print("请求参数"+jsondata)

        .......

        responseJson.put("retcode", "100");
        responseJson.put("retmsg", "成功");
        return SignUtils.putEncryptSign(responseJson, baseTermResource.getDeskey()); // 将"data" 放入到响应参数里
    }

 

以上,就可以进行测试验证了。

相关标签: 拦截器

上一篇: Windows 搭建FTP服务

下一篇: 拦截器