spring boot 添加自定义拦截器过滤器 Content-Type=application/json 格式的参数请求方式处理
程序员文章站
2022-03-18 16:14:22
...
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" 放入到响应参数里
}
以上,就可以进行测试验证了。
上一篇: Windows 搭建FTP服务
下一篇: 拦截器