scenario
- Modify the parameters in the request. Encrypt a field (the data that the interface needs to decrypt). Decrypt the field uniformly
- Request parameters and response results, log/save database
- Add additional fields to the request parameters (identifying certain systems, etc.)
OncePerRequestFilter
The GET method
GetParameterMap (), which gets only the parameters of the GET request
// Request parameters
parameterMap = httpRequest.getParameterMap();
// This is generic
// Request mode
String requestMethod = httpRequest.getMethod();
String remoteAddr = httpRequest.getRemoteAddr();
int remotePort = httpRequest.getRemotePort();
Copy the code
No modifications are allowed to a locked ParameterMap exception
/ / org. Apache. Catalina. Util. ParameterMap
@Override
public V put(K key, V value) {
checkLocked();
return delegatedMap.put(key, value);
}
private void checkLocked(a) {
if (locked) {
throw new IllegalStateException(sm.getString("parameterMap.locked")); }}/ / org. Apache. Tomcat. Util. Res., StringManager
public String getString(String key) {
if (key == null){
String msg = "key may not have a null value";
throw new IllegalArgumentException(msg);
}
String str = null;
try {
// Avoid NPE if bundle is null and treat it like an MRE
if(bundle ! =null) { str = bundle.getString(key); }}catch (MissingResourceException mre) {
//bad: shouldn't mask an exception the following way:
// str = "[cannot find message associated with key '" + key +
// "' due to " + mre + "]";
// because it hides the fact that the String was missing
// from the calling code.
//good: could just throw the exception (or wrap it in another)
// but that would probably cause much havoc on existing
// code.
//better: consistent with container pattern to
// simply return null. Calling code can then do
// a null check.
str = null;
}
return str;
}
/ * error code corresponding to the file under the tomcat org. Apache. Catalina. Util. LocalStrings. Properties PropertyResourceBundle bundle will be loaded into memory * / in the service started
parameterMap.locked=No modifications are allowed to a locked ParameterMap
/ / Java. Util. PropertyResourceBundle
private final Map<String,Object> lookup;
public PropertyResourceBundle (Reader reader) throws IOException {
Properties properties = new Properties();
properties.load(reader);
lookup = new HashMap(properties);
}
public Object handleGetObject(String key) {
if (key == null) {
throw new NullPointerException();
}
return lookup.get(key);
}
Copy the code
POST way
The request argument for POST is in the request body, and the body argument is in the form of a stream.
ServletInputStream inputStream = httpRequest.getInputStream();
InputStreamReader reader = new InputStreamReader(inputStream,StandardCharsets.UTF_8);
BufferedReader bfReader = new BufferedReader(reader);
StringBuilder sb = new StringBuilder();
String line;
while((line = bfReader.readLine()) ! =null){
sb.append(line);
}
System.out.println(sb.toString());
Copy the code
The request body is missing
The filter gets the POST request parameters, but the Controller layer reported an error.
The httpRequest. GetInputStream () can be used only once, use an error again
The InputStream read method has a postion flag inside. The position read by the current stream moves each time it is read, and if it reaches the end, the inputStream. read method returns -1. If you want to read it again, you can call the inputStream. reset method and position will move to the position where mark was called last time. Mark defaults to 0, so you can read it again. MarkSupported determines whether it can be reset. If it is true, it can be reset; if it is false, it cannot be reset. MarkSupported is false and a call to reset is a direct exception. Needs to be read into the InputStream preserved, use HttpServletRequestWrapper for processingCopy the code
Inheritance override method
@Component
@Slf4j
public class ParamFilter extends OncePerRequestFilter {
@Value("${app.self.name}")
private String selfName;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
RequestParameterWrapper requestWrapper=null;
String method=request.getMethod();
if("GET".equalsIgnoreCase(method)){
try {
requestWrapper = new RequestParameterWrapper(request, RequestMethod.GET);
Map<String, String[]> parameterMap = new HashMap<>(requestWrapper.getParameterMap());
log.info("The get parameter = {}", parameterMap.toString());
parameterMap.put("selfName".new String[]{selfName});
requestWrapper.setParameterMap(parameterMap);
}catch(Exception e){ e.printStackTrace(); }}else if("POST".equals(method)){
try {
requestWrapper = new RequestParameterWrapper(request, RequestMethod.POST);
// Get the body of the POST message
String body = requestWrapper.getBody();
JSONObject jsonObject = new JSONObject(body);
String dataAuthCode = (String) jsonObject.get("selfName");
if (StringUtils.isNotBlank(dataAuthCode)) {
chain.doFilter(request, response);
} else {
jsonObject.put("selfName", selfName); requestWrapper.setBody(jsonObject); }}catch(Exception e){ e.printStackTrace(); }}if(requestWrapper == null) {
chain.doFilter(request, response);
} else{ chain.doFilter(requestWrapper, response); }}}Copy the code
Inheritance HttpServletRequestWrapper
public class RequestParameterWrapper extends HttpServletRequestWrapper {
private String body;
private Map<String, String[]> parameterMap;
public RequestParameterWrapper(HttpServletRequest request, RequestMethod method) throws Exception{
super(request);
if(RequestMethod.POST.equals(method)){
StringBuilder stringBuilder = new StringBuilder();
try(BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(request.getInputStream(),"UTF-8")); {char[] charBuffer = new char[128];
int bytesRead;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead); }}catch (Exception ex) {
throw ex;
}
body = stringBuilder.toString();
}else if(RequestMethod.GET.equals(method)){ parameterMap=request.getParameterMap(); }}public String getBody(a) {
return this.body;
}
/** * Use * in post mode@param object
*/
public void setBody(JSONObject object) {
this.body=object.toString();
}
@Override
public ServletInputStream getInputStream(a) throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
return new ServletInputStream() {
@Override
public boolean isFinished(a) {
return false;
}
@Override
public boolean isReady(a) {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {}public int read(a) throws IOException {
returnbyteArrayInputStream.read(); }}; }@Override
public Enumeration<String> getParameterNames(a) {
Vector<String> vector = new Vector<String>(parameterMap.keySet());
return vector.elements();
}
@Override
public String getParameter(String name) {
String[] results = parameterMap.get(name);
return results[0];
}
@Override
public Map<String, String[]> getParameterMap() {
return parameterMap;
}
@Override
public String[] getParameterValues(String name) {
return parameterMap.get(name);
}
public void setParameterMap(Map<String, String[]> parameterMap) {
this.parameterMap = parameterMap; }}Copy the code