跨域问题的产生
因为浏览器的同源政策,就会产生跨域。比如说发送的异步请求是不同的两个源,就比如是不同的的两个端口或者不同的两个协议或者不同的域名。由于浏览器为了安全考虑,就会产生一个同源政策,不是同一个地方出来的是不允许进行交互的。
 
常见的跨域解决方式
- 在控制层加入允许跨域的注解 
@CrossOrigin 
- 使用
httpclient,不依赖浏览器 
- 使用网关 
Gateway 
1、注解:@CrossOrigin
在控制层加入允许跨域的注解,即可完成一个项目中前后端口跨域的问题
2、网关整合
Spring Cloud Gateway作为Spring Cloud生态系统中的网关,目标是替代Netflix Zuul,其 不仅提供统一的路由方式,并且还基于Filer链的方式提供了网关基本的功能,例如:安全、监控/埋点、限流等。
(1)路由
路由是网关最基础的部分,路由信息有一个ID、一个目的URL、一组断言和一组 Filter组成。如果断言路由为真,则说明请求的URL和配置匹配
(2)断言
Java8中的断言函数。Spring Cloud Gateway中的断言函数输入类型是Spring5.0框 架中的ServerWebExchange。Spring Cloud Gateway中的断言函数允许开发者去定义匹配来自 于http request中的任何信息,比如请求头和参数等。
(3)过滤器
一个标准的Spring webFilter。Spring cloud gateway中的filter分为两种类型的 Filter,分别是Gateway Filter和Global Filter。过滤器Filter将会对请求和响应进行修改处理

Spring cloud Gateway发出请求。然后再由Gateway Handler Mapping中找到与请 求相匹配的路由,将其发送到Gateway web handler。Handler再通过指定的过滤器链将请求发 送到实际的服务执行业务逻辑,然后返回。
项目中使用
新建模块service_gateway
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | <dependencies>
      <dependency>         <groupId>com.lzq</groupId>         <artifactId>service_utils</artifactId>         <version>0.0.1-SNAPSHOT</version>     </dependency>     <dependency>         <groupId>org.springframework.cloud</groupId>         <artifactId>spring-cloud-starter-gateway</artifactId>     </dependency>          <dependency>         <groupId>com.alibaba.cloud</groupId>         <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>     </dependency> </dependencies>
   | 
 
配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
   |  server.port=9090
 
  spring.application.name=service-gateway
  spring.cloud.nacos.discovery.server-addr=127.0.0.1:8888
  spring.cloud.gateway.discovery.locator.enabled=true
  spring.cloud.gateway.routes[0].id=service-hosp
  spring.cloud.gateway.routes[0].uri=lb://service-hosp
  spring.cloud.gateway.routes[0].predicates= Path=/*/hosp/**  
  spring.cloud.gateway.routes[1].id=service-cmn
  spring.cloud.gateway.routes[1].uri=lb://service-cmn
  spring.cloud.gateway.routes[1].predicates= Path=/*/cmn/**
 
  spring.cloud.gateway.routes[2].id=service-hosp
  spring.cloud.gateway.routes[2].uri=lb://service-hosp
  spring.cloud.gateway.routes[2].predicates= Path=/*/userlogin/**
 
  | 
 
创建启动类
1 2 3 4 5 6
   | @SpringBootApplication public class ApiGatewayApplication {     public static void main(String[] args) {         SpringApplication.run(ApiGatewayApplication.class, args);     } }
   | 
 
修改前端.evn文件,改成访问网关端口号
做集群部署时,他会根据名称实现负载均衡
跨域理解:发送请求后,网关过滤器会进行请求拦截,将跨域放行,转发到服务器中
跨域配置类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   | @Configuration public class CorsConfig {     @Bean     public CorsWebFilter corsFilter() {         CorsConfiguration config = new CorsConfiguration();         config.addAllowedMethod("*");         config.addAllowedOrigin("*");         config.addAllowedHeader("*");           UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());         source.registerCorsConfiguration("/**", config);           return new CorsWebFilter(source);     } }
   | 
 
若之前采用注解跨域,需要将@CrossOrigin去掉
3、Httpclient
常见的使用场景:多系统之间接口的交互、爬虫
http原生请求,获取百度首页代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
   | public class HttpTest {     @Test     public void test1() throws Exception {      String url = "https://www.badu.com";         URL url1 = new URL(url);                  URLConnection urlConnection = url1.openConnection();         HttpURLConnection httpURLConnection = (HttpURLConnection)urlConnection;                  InputStream is = httpURLConnection.getInputStream();                  InputStreamReader reader = new InputStreamReader(is, StandardCharsets.UTF_8);         BufferedReader br = new BufferedReader(reader);         String line;                  while ((line = br.readLine())!= null){             System.out.println(line);         }     } }
  httpURLConnection.setRequestMethod("GET");
 
  httpURLConnection.setRequestProperty("Accept-Charset","utf-8");
  | 
 
使用HttpClient发送请求、接收响应
- 创建
HttpClient对象。 
- 创建请求方法的实例,并指定请求URL。如果需要发送GET请求,创建
HttpGet对象;如果需要发送POST请求,创建HttpPost对象。 
- 如果需要发送请求参数,可调用
HttpGet、HttpPost共同的setParams(HetpParams params)方法来添加请求参数;对于HttpPost对象而言,也可调用setEntity(HttpEntity entity)方法来设置请求参数。 
- 调用
HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse。 
- 调用
HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。 
- 释放连接。无论执行方法是否成功,都必须释放连接
 
集成测试,添加依赖
1 2 3 4 5 6 7
   | <dependency>     <groupId>org.apache.httpcomponents</groupId>     <artifactId>httpclient</artifactId>     <version>4.5.13</version> </dependency>
 
 
   | 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
   | @Test public void test2(){          CloseableHttpClient client = HttpClients.createDefault();     String url = "https://www.baidu.com";          HttpGet httpGet = new HttpGet(url);          CloseableHttpResponse response = null;     try {         response = client.execute(httpGet);                  String result = EntityUtils.toString(response.getEntity(), "utf-8");         System.out.println(result);     } catch (Exception e) {         e.printStackTrace();     }finally {                  if (client != null){             try {                 client.close();             } catch (IOException e) {                 e.printStackTrace();             }         }     } }
   | 
 
项目中使用,系统调用平台接口保存信息,根据传入josn数据保存信息
系统中
1 2 3 4 5 6 7 8 9 10 11
   | @RequestMapping(value="/hospital/save",method=RequestMethod.POST) public String saveHospital(String data, HttpServletRequest request) {  try {   apiService.saveHospital(data);  } catch (YyghException e) {   return this.failurePage(e.getMessage(),request);  } catch (Exception e) {   return this.failurePage("数据异常",request);  }  return this.successPage(null,request); }
   | 
 
saveHospital方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   | @Override public boolean saveHospital(String data) {     JSONObject jsonObject = JSONObject.parseObject(data);     Map<String, Object> paramMap = new HashMap<>();     paramMap.put("hoscode","10000");     paramMap.put("hosname",jsonObject.getString("hosname"))          paramMap.put("logoData", jsonObject.getString("logoData"));               JSONObject respone =             HttpRequestHelper.sendRequest(paramMap,this.getApiUrl()+"/api/hosp/saveHospital");     System.out.println(respone.toJSONString());
      if(null != respone && 200 == respone.getIntValue("code")) {         return true;     } else {         throw new YyghException(respone.getString("message"), 201);     } }
   | 
 
HttpRequestHelper工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
   | 
 
 
 
 
  public static JSONObject sendRequest(Map<String, Object> paramMap, String url){     String result = "";     try {                  StringBuilder postdata = new StringBuilder();         for (Map.Entry<String, Object> param : paramMap.entrySet()) {             postdata.append(param.getKey()).append("=")                     .append(param.getValue()).append("&");         }         log.info(String.format("--> 发送请求:post data %1s", postdata));         byte[] reqData = postdata.toString().getBytes("utf-8");         byte[] respdata = HttpUtil.doPost(url,reqData);         result = new String(respdata);         log.info(String.format("--> 应答结果:result data %1s", result));     } catch (Exception ex) {         ex.printStackTrace();     }     return JSONObject.parseObject(result); }
 
  | 
 
HttpUtil工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
   | public static byte[] send(String strUrl, String reqmethod, byte[] reqData) {   try {    URL url = new URL(strUrl);    HttpURLConnection httpcon = (HttpURLConnection) url.openConnection();    httpcon.setDoOutput(true);    httpcon.setDoInput(true);    httpcon.setUseCaches(false);    httpcon.setInstanceFollowRedirects(true);    httpcon.setConnectTimeout(CONN_TIMEOUT);    httpcon.setReadTimeout(READ_TIMEOUT);    httpcon.setRequestMethod(reqmethod);    httpcon.connect();    if (reqmethod.equalsIgnoreCase(POST)) {     OutputStream os = httpcon.getOutputStream();     os.write(reqData);     os.flush();     os.close();    }    BufferedReader in = new BufferedReader(new InputStreamReader(httpcon.getInputStream(),"utf-8"));    String inputLine;    StringBuilder bankXmlBuffer = new StringBuilder();    while ((inputLine = in.readLine()) != null) {          bankXmlBuffer.append(inputLine);      }      in.close();      httpcon.disconnect();    return bankXmlBuffer.toString().getBytes();   } catch (Exception ex) {    log.error(ex.toString(), ex);    return null;   }  }
  | 
 
对应平台接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
   | @RestController @RequestMapping("/api/hosp") public class ApiController {     @Autowired     private HospitalService hospitalService;     @ApiOperation(value = "上传医院")     @PostMapping("saveHospital")     public R saveHospital(HttpServletRequest request) {                  Map<String, String[]> parameterMap = request.getParameterMap();                  Map<String, Object> paramMap = HttpRequestHelper.switchMap(parameterMap);                  String mapStr = JSONObject.toJSONString(paramMap);                  Hospital hospital = JSONObject.parseObject(mapStr, Hospital.class);                  hospitalService.saveHosp(hospital);         return R.ok();     } }
   | 
 
即可完成不同系统中的相互调用