实现方式
反射。
代码
package one.util;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.RequestFacade;
import org.apache.tomcat.util.http.MimeHeaders;
import org.springframework.util.ObjectUtils;
import javax.servlet.ServletRequestWrapper;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public class HeadersEdit {
private final HttpServletRequest request;
private Map<String, String> modifyHeaders;
private MimeHeaders itsHeaders;
private boolean isDeleteKnown=true;
public HeadersEdit(HttpServletRequest request){
this.request=request;
modifyHeaders= new HashMap<>();
itsHeaders=getMimeHeaders(getRequestFacade());
}
private HttpServletRequest getRequestFacade(){
try{
Field field= ServletRequestWrapper.class.getDeclaredField("request");
HttpServletRequest result;
field.setAccessible(true);
result=(HttpServletRequest)field.get((request));
while(!(result instanceof RequestFacade)){
result=(HttpServletRequest)field.get((result));
}
return result;
}catch (Exception e){
e.printStackTrace();
throw new RuntimeException("HeadersEdit Error!");
}
}
private MimeHeaders getMimeHeaders(HttpServletRequest requestFacade){
try{
Field itsRequest= RequestFacade.class.getDeclaredField("request");
itsRequest.setAccessible(true);
HttpServletRequest o5=(HttpServletRequest) itsRequest.get(requestFacade);
Field coyoteField= Request.class.getDeclaredField("coyoteRequest");
coyoteField.setAccessible(true);
org.apache.coyote.Request coyoteRequest=(org.apache.coyote.Request) coyoteField.get(o5);
Field headers=org.apache.coyote.Request.class.getDeclaredField("headers");
headers.setAccessible(true);
return (MimeHeaders)headers.get(coyoteRequest);
}catch (Exception e){
e.printStackTrace();
throw new RuntimeException("HeadersEdit Error!");
}
}
private boolean setValueExecutor(Map<String,String>newHeaders){
String key;
for(Map.Entry<String, String> entry : newHeaders.entrySet()){
key=entry.getKey();
if(itsHeaders.getHeader(key)!=null){
if(isDeleteKnown){
itsHeaders.removeHeader(key);
}else{
return false;
}
}
itsHeaders.addValue(key).setString(entry.getValue());
}
return true;
}
public boolean setValue(String key,String value){
if(ObjectUtils.isEmpty(key)||ObjectUtils.isEmpty(value)){
return false;
}
Map<String,String>map=new HashMap<>();
map.put(key,value);
return setValueExecutor(map);
}
public boolean setValue(Map<String,String>newHeaders){
if(ObjectUtils.isEmpty(newHeaders)){
return false;
}
return setValueExecutor(newHeaders);
}
public void changeCheck(){
isDeleteKnown=!isDeleteKnown;
}
}
测试环境
springsecurity中的过滤器、以及普通的过滤器。
原理简述
许多过滤器都间接继承了ServletRequestWrapper类,它有个属性叫request。springsecurity或者普通的过滤器类只是将其包装了多层,通过反射一层一层剥开即可。
|