快捷搜索:  汽车  科技

httpclient设计模式:三种跨域解决方案 HttpClient 注解

httpclient设计模式:三种跨域解决方案 HttpClient 注解(1)路由。路由是网关最基础的部分,路由信息有一个ID、一个目的URL、一组断言和一组 Filter组成。如果断言路由为真,则说明请求的URL和配置匹配Spring Cloud Gateway作为Spring Cloud生态系统中的网关,目标是替代Netflix Zuul,其 不仅提供统一的路由方式,并且还基于Filer链的方式提供了网关基本的功能,例如:安全、监 控/埋点、限流等。2.使用HttpClient,不依赖浏览器3.使用网关 getway在控制层加入允许跨域的注解,即可完成一个项目中前后端口跨域的问题

为什么会有跨域问题

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

常见的跨域解决方式

1.在控制层加入允许跨域的注解 @CrossOrigin

2.使用HttpClient,不依赖浏览器

3.使用网关 getway

注解:@CrossOrigin

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

网关整合

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将会对请求和响应进行修改处理

httpclient设计模式:三种跨域解决方案 HttpClient 注解(1)

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服务地址 默认8848 spring.cloud.nacos.discovery.server-addr=127.0.0.1:8888 #使用服务发现路由 spring.cloud.gateway.discovery.locator.enabled=true #设置路由id spring.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/** #设置路由id spring.cloud.gateway.routes[1].id=service-cmn #设置路由的uri spring.cloud.gateway.routes[1].uri=lb://service-cmn #设置路由断言 代理servicerId为auth-service的/auth/路径 spring.cloud.gateway.routes[1].predicates= Path=/*/cmn/** #设置路由id spring.cloud.gateway.routes[2].id=service-hosp #设置路由的uri spring.cloud.gateway.routes[2].uri=lb://service-hosp #设置路由断言 代理servicerId为auth-service的/auth/路径 spring.cloud.gateway.routes[2].predicates= Path=/*/userlogin/**

创建启动类

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

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

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

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

跨域配置类

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

Httpclient

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

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. 如果需要发送请求参数,可调用HttpGet、HttpPost共同的setparams(HetpParams params)方法来添加请求参数;
对于HttpPost对象而言,也可调用setEntity(HttpEntity entity)方法来设置请求参数。

4. 调用HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse。

5. 调用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;
调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。

6. 释放连接。无论执行方法是否成功,都必须释放连接

集成测试,添加依赖

<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.13</version> </dependency>

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

@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")); // 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

猜您喜欢: