三种跨域解决方案:HttpClient、注解、网关


  • 注解:@CrossOrigin
  • 网关整合
  • Httpclient


三种跨域解决方案:HttpClient、注解、网关

为什么会有跨域问题

三种跨域解决方案:HttpClient、注解、网关


因为浏览器的同源政策,就会产生跨域。比如说发送的异步请求是不同的两个源,就比如是不同的的两个端口或者不同的两个协议或者不同的域名。由于浏览器为了安全考虑,就会产生一个同源政策,不是同一个地方出来的是不允许进行交互的。


三种跨域解决方案:HttpClient、注解、网关

常见的跨域解决方式

三种跨域解决方案:HttpClient、注解、网关


  1. 在控制层加入允许跨域的注解@CrossOrigin
  2. 使用httpclient,不依赖浏览器
  3. 使用网关Gateway

注解:@CrossOrigin

在控制层加入允许跨域的注解,即可完成一个项目中前后端口跨域的问题

网关整合

Spring Cloud Gateway作为Spring Cloud生态系统中的网关,目标是替代Netflix Zuul,其 不仅提供统一的路由方式,并且还基于Filer链的方式提供了网关基本的功能,例如:安全、监 控/埋点、限流等。

(1)路由

路由是网关最基础的部分,路由信息有一个ID、一个目的URL、一组断言和一组 Filter组成。如果断言路由为真,则说明请求的URL和配置匹配

(2)断言

Java8中的断言函数。Spring Cloud Gateway中的断言函数输入类型是Spring5.0框 架中的ServerWebExchangeSpring Cloud Gateway中的断言函数允许开发者去定义匹配来自 于http request中的任何信息,比如请求头和参数等。

(3)过滤器

一个标准的Spring webFilterSpring cloud gateway中的filter分为两种类型的 Filter,分别是Gateway FilterGlobal Filter。过滤器Filter将会对请求和响应进行修改处理

三种跨域解决方案:HttpClient、注解、网关

图片

Spring cloud Gateway发出请求。然后再由Gateway Handler Mapping中找到与请 求相匹配的路由,将其发送到Gateway web handler。Handler再通过指定的过滤器链将请求发 送到实际的服务执行业务逻辑,然后返回。

项目中使用

新建模块service_gateway

<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>

配置文件

#服务端口server.port=9090
# 服务名spring.application.name=service-gateway# nacos服务地址 默认8848spring.cloud.nacos.discovery.server-addr=127.0.0.1:8888#使用服务发现路由spring.cloud.gateway.discovery.locator.enabled=true#设置路由idspring.cloud.gateway.routes[0].id=service-hosp#设置路由的uri lb负载均衡spring.cloud.gateway.routes[0].uri=lb://service-hosp#设置路由断言,代理servicerId为auth-service的/auth/路径spring.cloud.gateway.routes[0].predicates= Path=/*/hosp/** #设置路由idspring.cloud.gateway.routes[1].id=service-cmn#设置路由的urispring.cloud.gateway.routes[1].uri=lb://service-cmn#设置路由断言,代理servicerId为auth-service的/auth/路径spring.cloud.gateway.routes[1].predicates= Path=/*/cmn/**#设置路由idspring.cloud.gateway.routes[2].id=service-hosp#设置路由的urispring.cloud.gateway.routes[2].uri=lb://service-hosp#设置路由断言,代理servicerId为auth-service的/auth/路径spring.cloud.gateway.routes[2].predicates= Path=/*/userlogin/**

创建启动类

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

修改前端.evn文件,改成访问网关端口号

做集群部署时,他会根据名称实现负载均衡

跨域理解:发送请求后,网关过滤器会进行请求拦截,将跨域放行,转发到服务器中

跨域配置类

@Configurationpublic 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去掉

Httpclient

常见的使用场景:多系统之间接口的交互、爬虫

微信搜索公众号:Linux技术迷,回复:linux 领取资料 。

http原生请求,获取百度首页代码

public class HttpTest {    @Test    public void test1() throws Exception {     String url = "https://www.badu.com";        URL url1 = new URL(url);        //url连接        URLConnection urlConnection = url1.openConnection();        HttpURLConnection httpURLConnection = (HttpURLConnection)urlConnection;        //获取httpURLConnection输入流        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发送请求、接收响应

  1. 创建HttpClient对象。
  2. 创建请求方法的实例,并指定请求URL。如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象。
  3. 如果需要发送请求参数,可调用HttpGetHttpPost共同的setParams(HetpParams params)方法来添加请求参数;对于HttpPost对象而言,也可调用setEntity(HttpEntity entity)方法来设置请求参数。
  4. 调用HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse
  5. 调用HttpResponsegetAllHeaders()getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponsegetEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。
  6. 释放连接。无论执行方法是否成功,都必须释放连接

集成测试,添加依赖

<dependency>    <groupId>org.apache.httpcomponents</groupId>    <artifactId>httpclient</artifactId>    <version>4.5.13</version></dependency>@Testpublic void test2(){    //可关闭的httpclient客户端,相当于打开一个浏览器    CloseableHttpClient client = HttpClients.createDefault();    String url = "https://www.baidu.com";    //构造httpGet请求对象    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数据保存信息

系统中

@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方法

@Overridepublic 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"));    //  http://localhost:8201/api/hosp/saveHospital    //httpclient    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工具类

/** * 封装同步请求 * @param paramMap * @param url * @return */public static JSONObject sendRequest(Map<String, Object> paramMap, String url){    String result = "";    try {        //封装post参数        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工具类

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;  } }

对应平台接口

@RestController@RequestMapping("/api/hosp")public class ApiController {    @Autowired    private HospitalService hospitalService;    @ApiOperation(value = "上传医院")    @PostMapping("saveHospital")    public R saveHospital(HttpServletRequest request) {        //通过request取到前端接口传过来的值        Map<String, String[]> parameterMap = request.getParameterMap();        //将数组值转换成一个值        Map<String, Object> paramMap = HttpRequestHelper.switchMap(parameterMap);        //将map集合转成josn字符串        String mapStr = JSONObject.toJSONString(paramMap);        //josn字符串转成对象        Hospital hospital = JSONObject.parseObject(mapStr, Hospital.class);        //加入MongoDB中        hospitalService.saveHosp(hospital);        return R.ok();    }}

即可完成不同系统中的相互调用


如喜欢本文,请点击右上角,把文章分享到朋友圈

    作者:远走与梦游

    来源:blog.csdn.net/weixin_52210557/article/details/122803085

    版权申明:内容来源网络,仅供分享学习,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢!

    本篇文章来源于微信公众号:程序IT圈

    原创文章,作者:software,如若转载,请注明出处:https://www.sldh123.com/7014.html

    (0)
    上一篇 1月 5, 2023 9:10 上午
    下一篇 1月 5, 2023 9:10 上午

    相关推荐

    • 架构师谈谈软件开发模式:瀑布与敏捷

      瀑布和敏捷不是什么新概念,这里只是个人在团队合作中不得不去思考而做的归纳和总结,同时记录自己曾经踩过的坑,新瓶装旧酒,希望对你有所启发。 瀑布模式   瀑布模型是比较传统一种开发模…

      11月 25, 2022
      430
    • 架构师如何写好技术文档 ?

      参加工作时间久一点的工程师应该有这样一个体会:自己平时代码写得再多再好,可一旦要用文档去描述或者表达某一个事情或者问题时,都感觉非常困难,无从下手,不知道自己该写什么不该写什么;或…

      10月 15, 2022
      1100
    • 架构师必须清楚的支付系统:对账系统详解

      在支付系统中,资金对账在对账中心进行,将系统保存的账务流水与银行返回的清算流水和清算文件进行对账,核对系统账务数据与银行清算数据的一致性,保证支付机构各备付金银行账户每日的预计发生…

      7月 3, 2022
      440
    • 再谈 Spring Boot + Redis 实现分布式锁

      欢迎关注:架构师指南 一、业务背景 有些业务请求,属于耗时操作,需要加锁,防止后续的并发操作,同时对数据库的数据进行操作,需要避免对之前的业务造成影响。 二、分析流程 使用 Red…

      1月 5, 2023
      300
    • 如何画出一张优秀的架构图?(老鸟必备)

      作者:三画 简介:阿里巴巴技术专家,梓敬、鹏升和余乐对此文亦有贡献。三画曾多年从事工作流引擎研发工作,现专注于高并发移动互联网应用的架构和开发。 技术传播的价值,不仅仅体现在通过商…

      9月 23, 2022
      580
    • 架构师都应该知道的康威定律

      今天的分享主要来自我之前的工作经验以及平时的学习总结和思考。我之前的背景主要是做框架、系统和平台架构,之前的工作过的公司 eBay、携程、唯品会都是平台型互联网公司,所以今天主要带…

      10月 4, 2022
      600
    • 架构概述之架构演化、模式与核心要素

      如何打造一个高可用、高性能、易扩展、可伸缩且安全的应用系统?相信这是困扰着无数开发者的难题,在这里我们以一个网站为例,来讨论一下如何做好大型应用系统的架构设计。 架构演化发展历程 …

      9月 25, 2022
      390
    • 架构师详解离线数仓逻辑和架构设计

      作者:北有榆树链接:https://www.jianshu.com/p/486aa21578f9 1.技术简介 组件 版本 简介 FLINK 1.12.1 分布式计算引擎 HIVE…

      9月 9, 2022
      740
    • sql语句优化的30种方法

      作者:羋虹光链接:https://www.jianshu.com/p/3ab117c83d0b 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order b…

      11月 13, 2022
      440
    • 架构师谈流程引擎的架构设计

      1 什么是流程引擎 流程引擎是一个底层支撑平台,是为提供流程处理而开发设计的。流程引擎和流程应用,以及应用程序的关系如下图所示。 常见的支撑场景有:Workflow、BPM、流程编…

      12月 10, 2022
      420

    发表回复

    您的电子邮箱地址不会被公开。