SpringCloud系列--6网关 对应的项目完整代码

  |   0 评论   |   0 浏览

image.png

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>org.crazyit.cloud</groupId>
	<artifactId>zuul-gateway</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>Dalston.SR1</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-config</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-zuul</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpclient</artifactId>
			<version>4.5.3</version>
		</dependency>
		<dependency>
			<groupId>com.squareup.okhttp3</groupId>
			<artifactId>okhttp</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-actuator</artifactId>
			<version>1.5.3.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.codehaus.groovy</groupId>
			<artifactId>groovy-all</artifactId>
			<version>2.4.12</version>
		</dependency>
	</dependencies>

</project>

application.yml配置文件

spring:
  application:
    name: zuul-gateway
eureka:
  instance:
    hostname: localhost
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
management:
  security:
    enabled: false
zuul:
  ignoredPatterns: /sale/noRoute
  # sensitiveHeaders: cookie
  # ignoredHeaders: accept-language
  routes:
    sale:
      path: /sale/**
      serviceId: zuul-sale-service
    routeTest:
      path: /routeTest/163
      url: http://www.163.com
    route163:
      url: http://www.163.com
    noRoute163:
      url: www.163.com
    helloRoute:
      path: /test/**
      url: forward:/source/hello
    restTestRoute:
      path: /rest-tpl-sale/**
      serviceId: zuul-sale-service
    exceptionTest:
      path: /exceptionTest/**
  ribbon:
    eager-load:
      enabled: true

  #SendForwardFilter:
    #route:
      #disable: true

      

DynamicFilter.groovy 注意不是.java类

package groovy.filters;

import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;

import com.netflix.zuul.ZuulFilter;

class DynamicFilter extends ZuulFilter {

	public boolean shouldFilter() {
		return true;
	}

	public Object run() {
		System.out.println("=========  这一个是动态加载的过滤器:DynamicFilter");
		return null;
	}

	public String filterType() {
		return FilterConstants.ROUTE_TYPE;
	}

	public int filterOrder() {
		return 3;
	}
}

ExceptionFilter.java

package org.crazyit.cloud.filter;

import javax.servlet.http.HttpServletRequest;

import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.cloud.netflix.zuul.util.ZuulRuntimeException;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;

public class ExceptionFilter extends ZuulFilter {

	public boolean shouldFilter() {
		RequestContext ctx = RequestContext.getCurrentContext();		
		HttpServletRequest request = ctx.getRequest();
		// 获取请求的uri
		String uri = request.getRequestURI();
		// 为不影响其他例子,uri含有exceptionTest才执行本过滤器
		if(uri.indexOf("exceptionTest") != -1) {
			return true;
		}
		return false;
	}

	public Object run() {
		System.out.println("执行  ExceptionFilter,将抛出异常");
		throw new ZuulRuntimeException(new ZuulException("exception msg", 201, "my cause"));
	}

	public String filterType() {
		return FilterConstants.ROUTE_TYPE;
	}

	public int filterOrder() {
		return 3;
	}
}

FilterConfig.java

package org.crazyit.cloud.filter;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class FilterConfig {

	@Bean
	public MyFilter myFilter() {
		return new MyFilter();
	}
	
	@Bean
	public RestTemplateFilter restTemplateFilter(RestTemplate restTemplate) {
		return new RestTemplateFilter(restTemplate); // 注入RestTemplate
	}

	@Bean
	public ExceptionFilter exceptionFilter() {
		return new ExceptionFilter();
	}

	@LoadBalanced
	@Bean
	public RestTemplate getRestTemplate() {
		return new RestTemplate();
	}
}

MyFilter.java

package org.crazyit.cloud.filter;

import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;

import com.netflix.zuul.ZuulFilter;

public class MyFilter extends ZuulFilter {

	// 过滤器执行条件
	public boolean shouldFilter() {
		return true;
	}

	// 执行方法
	public Object run() {
		System.out.println("执行 MyFilter 过滤器");
		return null;
	}

	// 表示将在路由阶段执行
	public String filterType() {
		return FilterConstants.ROUTE_TYPE;
	}

	// 返回1,路由阶段,该过滤将会最先执行
	public int filterOrder() {
		return 1;
	}
}

RestTemplateFilter.java

package org.crazyit.cloud.filter;

import javax.servlet.http.HttpServletRequest;

import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.web.client.RestTemplate;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;

public class RestTemplateFilter extends ZuulFilter {
	
	private RestTemplate restTemplate;
	
	public RestTemplateFilter(RestTemplate restTemplate) {
		this.restTemplate = restTemplate;
	}
	
	public boolean shouldFilter() {
		RequestContext ctx = RequestContext.getCurrentContext();
		HttpServletRequest request = ctx.getRequest();
		// 获取请求uri
		String uri = request.getRequestURI();
		// 为了不影响其他路由,uri中含有 rest-tpl-sale 才执行本路由器
		if(uri.indexOf("rest-tpl-sale") != -1) {
			return true;
		} else {
			return false;
		}
	}

	public Object run() {
		RequestContext ctx = RequestContext.getCurrentContext();
		// 获取需要调用的服务id
		String serviceId = (String)ctx.get("serviceId");
		// 获取请求的uri
		String uri = (String)ctx.get("requestURI");
		// 组合成url给RestTemplate调用
		String url = "http://" + serviceId + uri;
		System.out.println(System.currentTimeMillis() + "执行RestTemplateFilter, 调用的url:" + url);
		// 调用并获取结果
		String result = this.restTemplate.getForObject(url, String.class);
		// 设置路由状态,表示已经进行路由
		ctx.setResponseBody(result);
		// 设置响应标识,
        //划重点: 设置为响应标识ctx.sendZuulResponse()后,SpringCloud自带的Ribbon路由过滤器(RibbonRoutingFilter)、
        // 简单路由过滤器(SimpleHostRoutingFilter)将不会执行
		ctx.sendZuulResponse();
		return null;
	}

	@Override
	public String filterType() {
		return FilterConstants.ROUTE_TYPE;
	}

	@Override
	public int filterOrder() {
		// TODO Auto-generated method stub
		return 2;
	}
}

FallbackConfig.java

package org.crazyit.cloud.hy;

import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FallbackConfig {

	@Bean
	public ZuulFallbackProvider saleFallbackProvider() {
		return new MyFallbackProvider();
	}
}

MyFallbackProvider.java

package org.crazyit.cloud.hy;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;

/**
 * 回退的处理类
 * @author 杨恩雄
 *
 */
public class MyFallbackProvider implements ZuulFallbackProvider {

	// 返回路由的名称
	public String getRoute() {
		return "*";
	}

	// 回退触发时,返回默认的响应
	public ClientHttpResponse fallbackResponse() {
		return new ClientHttpResponse() {

			public InputStream getBody() throws IOException {
				return new ByteArrayInputStream("fallback".getBytes());
			}

			public HttpHeaders getHeaders() {
				HttpHeaders headers = new HttpHeaders();
				headers.setContentType(MediaType.TEXT_PLAIN);
				return headers;
			}

			public HttpStatus getStatusCode() throws IOException {
				return HttpStatus.OK;
			}

			public int getRawStatusCode() throws IOException {
				return 200;
			}

			public String getStatusText() throws IOException {
				return "OK";
			}

			public void close() {
				
			}
		};
	}
}

MyErrorController.java

package org.crazyit.cloud.web;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.boot.autoconfigure.web.BasicErrorController;
import org.springframework.boot.autoconfigure.web.ErrorAttributes;
import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class MyErrorController extends BasicErrorController {

	public MyErrorController(ErrorAttributes errorAttributes) {
		super(errorAttributes, new ErrorProperties());
	}

	@Override
	public ModelAndView errorHtml(HttpServletRequest request,
			HttpServletResponse response) {
		System.out.println("===  输出异常信息   ===");
		System.out.println(request.getAttribute("javax.servlet.error.status_code"));
		System.out.println(request.getAttribute("javax.servlet.error.exception"));
		System.out.println(request.getAttribute("javax.servlet.error.message"));		
		return super.errorHtml(request, response);
	}
}

SourceController.java

package org.crazyit.cloud.web;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SourceController {

	@RequestMapping(value = "/source/hello/{name}", method = RequestMethod.GET)
	@ResponseBody
	public String hello(@PathVariable("name") String name) {
		return "hello " + name;
	}

	@RequestMapping(value = "/book/{name}", method = RequestMethod.GET)
	@ResponseBody
	public String testBook(@PathVariable("name") String name) {
		return "book " + name;
	}

	@RequestMapping(value = "/sale/noRoute", method = RequestMethod.GET)
	@ResponseBody
	public String saleNoRoute(HttpServletRequest request) {
		System.out.println("设置了ignoredPatterns,该方法将会执行");
		return "/sale/noRoute";
	}

}

GatewayApplication.java

package org.crazyit.cloud;

import java.io.File;
import java.net.URL;

import javax.annotation.PostConstruct;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

import com.netflix.zuul.FilterFileManager;
import com.netflix.zuul.FilterLoader;
import com.netflix.zuul.groovy.GroovyCompiler;
import com.netflix.zuul.groovy.GroovyFileFilter;

@EnableZuulProxy
@SpringBootApplication
public class GatewayApplication {
	
	@PostConstruct
	public void zuulInit() {
        FilterLoader.getInstance().setCompiler(new GroovyCompiler());
        // 读取配置,获取脚本根目录
        String scriptRoot = System.getProperty("zuul.filter.root", "groovy/filters");
		System.out.println("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%scriptRoot:" + scriptRoot);
		scriptRoot = "/Users/apple/coding/springcloud/codes/07/03/zuul-gateway/src/main/java/" + scriptRoot;
        // 获取刷新间隔
        String refreshInterval = System.getProperty("zuul.filter.refreshInterval", "5");
        if (scriptRoot.length() > 0) scriptRoot = scriptRoot + File.separator;
        try {
            FilterFileManager.setFilenameFilter(new GroovyFileFilter());
            FilterFileManager.init(Integer.parseInt(refreshInterval), scriptRoot + "pre", 
            		scriptRoot + "route", scriptRoot + "post");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
	}

	public static void main(String[] args) {
		URL resource = FilterFileManager.class.getClassLoader().getResource("/Users/apple/coding/springcloud/codes/07/03/zuul-gateway/src/main/java/groovy/filters/pre");
		System.out.println(resource);
		new SpringApplicationBuilder(GatewayApplication.class).properties(
				"server.port=8080").run(args);
	}
}

MyConfig.java

package org.crazyit.cloud;

import org.springframework.cloud.netflix.zuul.filters.discovery.PatternServiceRouteMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//@Configuration
public class MyConfig {

	/**
	 * 访问网关的 /xxxxx/**,将会被路由到 zuul-xxxxx-service 服务进行处理
	 */
	@Bean
	public PatternServiceRouteMapper patternServiceRouteMapper() {
		return new PatternServiceRouteMapper(
				"(zuul)-(?<module>.+)-(service)", "${module}/**");
	}
}


标题:SpringCloud系列--6网关 对应的项目完整代码
作者:码农路上
地址:http://wujingjian.club/articles/2020/03/24/1585048784732.html