zuul原理
流程:
- 正常流程:
- 请求到达首先会经过pre类型过滤器,而后到达routing类型,进行路由,请求就到达真正的服务提供者,执行请求,返回结果后,会到达post过滤器。而后返回响应。
- 异常流程:
- 整个过程中,pre或者routing过滤器出现异常,都会直接进入error过滤器,再error处理完毕后,会将请求交给POST过滤器,最后返回给用户。
- 如果是error过滤器自己出现异常,最终也会进入POST过滤器,而后返回。
- 如果是POST过滤器出现异常,会跳转到error过滤器,但是与pre和routing不同的时,请求不会再到达POST过滤器了。
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.55</version> </dependency>
package cn.jiedada.filter; import com.alibaba.fastjson.JSON; import com.fasterxml.jackson.databind.ObjectMapper; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; import org.apache.http.HttpStatus; import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.HashMap; import java.util.Map; /** * 登陆检查的过滤器,判断放行登陆请求,判断如果是登陆就放行, * 如果不是登陆执行run方法,判断是否有token,如果没有就不放行 */ @Component public class LoginCheckLogin extends ZuulFilter { //过滤的类型 @Override public String filterType() { return FilterConstants.PRE_TYPE; } //过滤的大小,越小越先执行 @Override public int filterOrder() { return FilterConstants.PRE_DECORATION_FILTER_ORDER; } //是否跳转到run方法,如果为true则跳转到run方法 //如果为false则直接放行 @Override public boolean shouldFilter() { //获得上下文对象 RequestContext context = RequestContext.getCurrentContext(); //获得访问路径 HttpServletRequest request = context.getRequest(); String requestURI = request.getRequestURI(); //判断是否包含登陆请求 if(requestURI.contains("login")){ //放行 return false; } //否则跳转到run return true; } //判断登录请求中是否包含token,如果包含放行,不包含不放行 @Override public Object run() throws ZuulException { //获得上下文对象,这个对象和上面的对象是同一个 RequestContext context = RequestContext.getCurrentContext(); //获得request和response对象 HttpServletRequest request = context.getRequest(); String token = request.getHeader("token"); //判断上下文对象中的token是否有东西, if(!StringUtils.hasLength(token)){ //设置响应参数 HttpServletResponse response = context.getResponse(); //设置编码 response.setContentType("text/json;charset=utf-8"); //设置响应401未登录 response.setStatus(HttpStatus.SC_UNAUTHORIZED); //如果没有东西则返回信息 Map map=new HashMap(); map.put("success",false); map.put("msg","未登录需要登陆后才能访问"); //需要把map转化为json对象 String s = JSON.toJSONString(map); try { //设置到响应中去 response.getWriter().write(s); } catch (IOException e) { e.printStackTrace(); } //不放行 context.setSendZuulResponse(false); } //如果有就放行, return null; } }