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

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

用postman测试

后台处理步骤:

一、 添加过滤器:

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" 放入到响应参数里
    }

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

猜你喜欢

转载自blog.csdn.net/weikzhao0521/article/details/82377951