版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/didi7696/article/details/83508499
由于在请求中请求域的属性在请求转发,路由等过程中,请求域的值会丢失,,在项目项目中使用请求头来传递信息,但是HttpRequest并没有实现增加请求头的方法,所以找到他的子类来实现
class MutableHttpServletRequest extends HttpServletRequestWrapper {
// holds custom header and value mapping
private final Map<String, String> customHeaders;
public MutableHttpServletRequest(HttpServletRequest request){
super(request);
this.customHeaders = new HashMap<String, String>();
}
public void putHeader(String name, String value){
this.customHeaders.put(name, value);
}
public String getHeader(String name) {
// check the custom headers first
String headerValue = customHeaders.get(name);
if (headerValue != null){
return headerValue;
}
// else return from into the original wrapped object
return ((HttpServletRequest) getRequest()).getHeader(name);
}
public Enumeration<String> getHeaderNames() {
// create a set of the custom header names
Set<String> set = new HashSet<String>(customHeaders.keySet());
// now add the headers from the wrapped request object
@SuppressWarnings("unchecked")
Enumeration<String> e = ((HttpServletRequest) getRequest()).getHeaderNames();
while (e.hasMoreElements()) {
// add the names of the request headers into the list
String n = e.nextElement();
set.add(n);
}
// create an enumeration from the set and return
return Collections.enumeration(set);
}
}
使用:
public class SecurityFilter implements javax.servlet.Filter {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
MutableHttpServletRequest mutableRequest = new MutableHttpServletRequest(req);
...
mutableRequest.putHeader("x-custom-header", "custom value");
chain.doFilter(mutableRequest, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
}
但是项目中我使用的SpringCloud ZUUL中使用这样 的方式失败:
@Component
public class AccessFilter extends ZuulFilter {
private Logger log = LoggerFactory.getLogger(AccessFilter.class);
@Autowired
private VerificationHelper helper;
private BufferedReader reader=null;
@Autowired
private KeyAndFrequencyService service;
@Autowired
private ZuulTest zuulTest;
@Autowired
private PermissionHandler permissionHandler;
@Override
public String filterType() {
//前置过滤器
return "pre";
}
@Override
public int filterOrder() {
//优先级,数字越大,优先级越低
return 0;
}
@Override
public boolean shouldFilter() {
//是否执行该过滤器,true代表需要过滤
return true;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
try {
permissionHandler.setTokenExpireTime(200000000);
String type = request.getHeader("type");
zuulTest.say();
System.out.println("......................................................");
if (type == null) {
System.out.println("......................................................验证1");
Object object = helper.AccessZuul(request, ctx);
return object;
} else {
System.out.println("......................................................验证2");
PermissionResult result=permissionHandler.check(request);
System.out.println(result);
if(result.isState()){
MutableHttpServletRequest mutRequest=new MutableHttpServletRequest (request);
//增加头部信息
DasAccountInfo accountInfo= permissionHandler.GetDasAccountInfoById(Integer.parseInt(result.getUserId()));
mutRequest.putHeader("dasAccountInfo", JSON.toJSONString(disablePropertyName())) ;RequestContext.getCurrentContext().setRequest(mutRequest);
ctx.setSendZuulResponse(true);// 对该请求进行路由
ctx.setResponseStatusCode(200);
ctx.set("isSuccess", true);
}else{
ctx.setSendZuulResponse(false);// 过滤该请求,不对其进行路由
ctx.setResponseStatusCode(401);// 返回错误码
ctx.setResponseBody("{\"code\":0,\"result\":\"网关验证失败!验证方式为2\"}");// 返回错误内容
ctx.set("isSuccess", false);
}
}
}catch (Exception e){
e.printStackTrace();
log.error("网关报错!!!",e.fillInStackTrace());
}
return null;
}
使用zuul网关的自带的设置请求头的方法,在网关中设置的请求头可以被路由下面的服务获取到:
ctx.getZuulRequestHeaders().put("dasAccountInfo", JSON.toJSONString(disablePropertyName()));
参考:
https://blog.csdn.net/wangjia55/article/details/51712574/