本次讨论post方式获取参数,request.getInputStream()获取一次以后不能第二次获取,以及
request.getParameter()与request.getInputStream()也存在这种情况
一、获取请求参数
1、request.getParameter()
2、request.getInputStream()或request.getReader()
二、请求方contentType
1、application/x-www-form-urlencoded
@RequestMapping("/testWwwFrom")
@ResponseBody
public Book testWwwFrom(Book req, HttpServletRequest servletRequest) {
logger.info("查询所有1用户信息" + JSON.toJSONString(req));
return req;
}
2、multipart/form-data
@RequestMapping("/testFormData")
@ResponseBody
public Book testFormData(Book req, HttpServletRequest servletRequest) {
logger.info("查询所有1用户信息" + JSON.toJSONString(req));
return req;
}
3、application/json
@RequestMapping("/testJson")
@ResponseBody
public Book testJsonFrom(@RequestBody Book req, HttpServletRequest servletRequest) {
logger.info("查询所有1用户信息" + JSON.toJSONString(req));
return req;
}
1、request.getParameter()对应application/x-www-form-urlencoded
2、request.getInputStream()或request.getReader()对应application/json
那么现在有一个这样的需求如果是form表单就获取formToken然后和缓存的进行CRSF防护
思路根据上面说的form表单参数获取分为2大类。
其中request.getInputStream()获取一次以后不能第二次获取,以及
request.getParameter()与request.getInputStream()也存在这种情况。
1、application/x-www-form-urlencoded以及multipart/form-data通过request.getParameter()获取
2、application/json通过request.getInputStream()或request.getReader()获取,这种要依赖HttpServletRequestWrapper
package com.study.ju.web.interceptor;
import org.apache.commons.io.IOUtils;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* <p>https://blog.csdn.net/kaizhangzhang/article/details/97900961</p>
*
*
* @version v 0.1 2023/5/29 15:37
*/
public class ResettableServletRequestWrapper extends HttpServletRequestWrapper {
//保存流中的数据
private byte[] data;
/**
* Constructs a request object wrapping the given request.
*
* @param request
* @throws IllegalArgumentException if the request is null
*/
public ResettableServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
//从流中获取数据
data = IOUtils.toByteArray(request.getInputStream());
}
@Override
public ServletInputStream getInputStream() throws IOException {
//在调用getInputStream函数时,创建新的流,包含原先数据流中的信息,然后返回
return new NewServletInputStream(new ByteArrayInputStream(data));
}
class NewServletInputStream extends ServletInputStream{
private InputStream inputStream;
public NewServletInputStream(InputStream inputStream){
this.inputStream = inputStream;
}
@Override
public int read() throws IOException {
return inputStream.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
}
package com.study.ju.web.interceptor;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
/**
* <p>form表单提交校验token</p>
*
*
* @version v 0.1 2023/5/29 13:45
*/
public class FormSubmitTokenInterceptor implements HandlerInterceptor {
private String formSubmitTokenInterceptorUrls = "[\"/testJson\",\"/test/testJson\",\"/test/testWwwFrom\",\"/test/testRequestParam\"]";
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String requestURI = getRequestURI(request);
if ("POST".equals(request.getMethod().toUpperCase()) && StringUtils.isNotEmpty(formSubmitTokenInterceptorUrls)) {
List<String> formInterceptorUrls = JSONArray.parseArray(formSubmitTokenInterceptorUrls, String.class);
if (CollectionUtils.isNotEmpty(formInterceptorUrls)) {
boolean contains = formInterceptorUrls.stream().anyMatch(e -> e.contains(requestURI));
if (contains) {
String contentType = request.getContentType();
System.out.println(contentType);
if ("application/json".equalsIgnoreCase(contentType)) {
ResettableServletRequestWrapper resettableServletRequestWrapper = new ResettableServletRequestWrapper(request);
String bodyParam = IOUtils.toString(resettableServletRequestWrapper.getInputStream());
System.out.println(bodyParam);
if (StringUtils.isNotEmpty(bodyParam)) {
JSONObject jsonObject = JSONObject.parseObject(bodyParam);
if (jsonObject.containsKey("formToken")) {
String formToken = (String) jsonObject.get("formToken");
System.out.println("formToken:"+formToken);
}
}
} else {
if (StringUtils.isNotEmpty(request.getParameter("formToken"))) {
System.out.println("formToken2:"+request.getParameter("formToken"));
}
System.out.println("name:"+request.getParameter("name"));
}
}
}
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
/**
* 获取用户请求的path,不带contextPath
* 如:/index.htm
*/
public static String getRequestURI(HttpServletRequest request) {
return StringUtils.replace(request.getRequestURI(), request.getContextPath(), "");
}
}
web.xml放在前面
<filter>
<filter-name>requestFilter</filter-name>
<filter-class>com.study.ju.web.Filter.HttpServletRequestReplacedFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>requestFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>