ICAT技术 阅读:924评论: 0 2018-08-27

什么是接口网关,有什么作用?

image.png

介绍:

(1)从图上可以看到,一个h5页面中,想调用2个不同域名接口的服务,会出现跨域问题,报错。

(2)这时,我们可以使用接口网关拦截这2个请求,用过接口网关跳转到请求来源指定的服务。

作用:

(1)接口网关可以解决多服务不同域名或不同端口的跨域问题。

(2)可以对请求进行拦截,比如:有些服务需要token认证才能请求服务,这是可以进行拦截判断token是否正确有效期内。


第一步:新建一个拦截中心的项目,导入pom和application.yml配置相关

(1)导入pom.xml的相关的包

<?xml version="1.0" encoding="UTF-8"?>
<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>com.example</groupId>
	<artifactId>eureka.zuul</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>eureka.zuul</name>
	<description>Demo project for Spring Boot</description>
	<!--基于Springboot -->
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.4.0.RELEASE</version>
		<relativePath />
	</parent>

	<properties>
		<!--设置字符编码及java版本 -->
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<!--增加eureka-server的依赖 -->
		<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.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<!--依赖管理,用于管理spring-cloud的依赖,其中Camden.SR3是版本号 -->
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>Camden.SR3</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>


</project>

(2)配置application.yml

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8888/eureka/
server:
  port: 8765
spring:
  application:
    name: server-zuul
zuul:
  routes:
    api-a:
      path: /api-menber/**    #拦截api-menber跳转到server-menber
      service-id: server-menber #服务的名字
    api-b:
      path: /api-order/**
      service-id: server-order

(1)配置注册中心地址

(2)配置服务端口

(3)配置服务名

(4)注册中心配置

        1.接口命名  api-a:

        2.接口地址    path : 

        3.接口服务名字 service-id:


第二步:新建启动类

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@SpringBootApplication
@EnableEurekaClient
/* 开启网关代理*/
@EnableZuulProxy
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}
}

第三步:测试

测试之前,先把我们之前创建的相关启动完成手把手教【SpringCloud分布式开发】教程|第一章:服务注册与服务发现

启动注册中心,订单服务,会员服务,最后启动网关服务。

启动完成后,访问http://localhost:8888/查看注册中心

image.png

从服务类表中中可以看到,server-menber,server-order,server-zuul  3条端口不一样的服务。

(1)访问server-menber中的一个接口http://192.168.1.134:8762/getMenberApi

image.png

(2)访问server-order中的接口http://192.168.1.134:8763/getOrderApi

image.png

(3)我们会发现虽然都是同一域名,但是端口不一致,在h5页面中用ajax请求会导致跨域问题,接下来就用到第三个工程服务的server-zuul

(4)再次通过网关访问menber工程http://192.168.1.134:8765/api-menber/getMenberApi

image.png

发现访问到menber工程下的getMenberApi接口的数据了。

url中的api-menber是自己配置的服务的名字

getMenberApi是这个服务下面的一个接口地址

image.png

(4)访问order工程服务的接口也是上面那个方法。更换服务名和接口地址。域名和端口不变,这样解决了跨域的问题。


(5)我们还可以在这里加入参数拦截

package com.example.demo;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Component;

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

/**
 * 自定义过滤器
 * 
 * @ClassName: MyFilter
 * @Description: TODO
 * @author icat
 * @date 2018年8月27日 下午1:29:04
 *
 */
@Component
public class MyFilter extends ZuulFilter {

	@Override
	public Object run() {
		RequestContext ctx = RequestContext.getCurrentContext();
		HttpServletRequest request = ctx.getRequest();
		/*
		 * 获取参数token
		 */
		Object token = request.getParameter("token");
		if (token != null) {
			return null;
		}
		ctx.setSendZuulResponse(false);
		ctx.setResponseStatusCode(401);
		try {
			ctx.getResponse().getWriter().write("token emtip");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;

	}

	@Override
	public boolean shouldFilter() {
		return true;
	}

	@Override
	public int filterOrder() {
		return 0;
	}

	@Override
	public String filterType() {
		return "pre";
	}

}

继承ZuulFilter类 filterType需要返回pre shouldFilter返回true

完成后启动。

image.png


发现token为空的信息。是因为上面的过滤掉了。不传参数token就返回这个.

下面我们传个参数token在来看看效果

http://192.168.1.134:8765/api-menber/getMenberApi?token=231

image.png

这样就进来了,访问成功了。这就是一个参数拦截的功能。


转载请注明来源:

评论