项目需求:

jsonp是从前台js的角度考虑,通过Ajax调用springMVC的接口。同一个ip、同一个网络协议、同一个端口,三者都满足就是同一个域,否则就是跨域问题了。首页广告需要一个轮播的效果,取后台数据json格式。上篇博客介绍了使用jsonp来解决跨域,现在有个新的方法来解决,那就是:ajax请求地址改为自己系统的后台地址,之后在自己的后台用HttpClient请求url。封装好的跨域请求url工具类。封装一个get一个POST即可。

两者的区别就在于,jsonp是基于客户端的跨域解决。而httpclient是基于服务端的跨域解决。

我现在有两个maven项目:

Taotao-portal(8082端口)

Taotao-rest(8081端口)

要使用httpclient需要在maven中引用(portal):

  1. <!-- httpclient -->
  2. <dependency>
  3. <groupId>org.apache.httpcomponents</groupId>
  4. <artifactId>httpclient</artifactId>
  5. </dependency>
<!-- httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>

rest项目中写了个后台的服务调广告的数据,在portal项目中的service层来调用rest项目中的controller层提供的服务。

httpclient工作图解:

核心代码展示:

(portal项目)contentcontroller.java

  1. @Controller
  2. public class ContentController {
  3. @Autowired
  4. private ContentService contentService;
  5. //getdata
  6. @RequestMapping("/content/{cid}")
  7. @ResponseBody
  8. public TaotaoResult getConentList(@PathVariable Long cid){
  9. try {
  10. List<TbContent> list=contentService.getContentList(cid);
  11. return TaotaoResult.ok(list);
  12. } catch (Exception e) {
  13. e.printStackTrace();
  14. return TaotaoResult.build(500, ExceptionUtil.getStackTrace(e));
  15. }
  16. }
  17. }
@Controller
public class ContentController {
@Autowired
private ContentService contentService;
//getdata
@RequestMapping("/content/{cid}")
@ResponseBody
public TaotaoResult getConentList(@PathVariable Long cid){ try {
List&lt;TbContent&gt; list=contentService.getContentList(cid);
return TaotaoResult.ok(list);
} catch (Exception e) {
e.printStackTrace();
return TaotaoResult.build(500, ExceptionUtil.getStackTrace(e));
}
}

}

(portal项目)HttpClientUtil.java

  1. package com.taotao.common.utils;
  2. import java.io.IOException;
  3. import java.net.URI;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6. import java.util.Map;
  7. import org.apache.http.NameValuePair;
  8. import org.apache.http.client.entity.UrlEncodedFormEntity;
  9. import org.apache.http.client.methods.CloseableHttpResponse;
  10. import org.apache.http.client.methods.HttpGet;
  11. import org.apache.http.client.methods.HttpPost;
  12. import org.apache.http.client.utils.URIBuilder;
  13. import org.apache.http.entity.ContentType;
  14. import org.apache.http.entity.StringEntity;
  15. import org.apache.http.impl.client.CloseableHttpClient;
  16. import org.apache.http.impl.client.HttpClients;
  17. import org.apache.http.message.BasicNameValuePair;
  18. import org.apache.http.util.EntityUtils;
  19. public class HttpClientUtil {
  20. public static String doGet(String url, Map<String, String> param) {
  21. // 创建Httpclient对象
  22. CloseableHttpClient httpclient = HttpClients.createDefault();
  23. String resultString = "";
  24. CloseableHttpResponse response = null;
  25. try {
  26. // 创建uri
  27. URIBuilder builder = new URIBuilder(url);
  28. if (param != null) {
  29. for (String key : param.keySet()) {
  30. builder.addParameter(key, param.get(key));
  31. }
  32. }
  33. URI uri = builder.build();
  34. // 创建http GET请求
  35. HttpGet httpGet = new HttpGet(uri);
  36. // 执行请求
  37. response = httpclient.execute(httpGet);
  38. // 判断返回状态是否为200
  39. if (response.getStatusLine().getStatusCode() == 200) {
  40. resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
  41. }
  42. } catch (Exception e) {
  43. e.printStackTrace();
  44. } finally {
  45. try {
  46. if (response != null) {
  47. response.close();
  48. }
  49. httpclient.close();
  50. } catch (IOException e) {
  51. e.printStackTrace();
  52. }
  53. }
  54. return resultString;
  55. }
  56. public static String doGet(String url) {
  57. return doGet(url, null);
  58. }
  59. public static String doPost(String url, Map<String, String> param) {
  60. // 创建Httpclient对象
  61. CloseableHttpClient httpClient = HttpClients.createDefault();
  62. CloseableHttpResponse response = null;
  63. String resultString = "";
  64. try {
  65. // 创建Http Post请求
  66. HttpPost httpPost = new HttpPost(url);
  67. // 创建参数列表
  68. if (param != null) {
  69. List<NameValuePair> paramList = new ArrayList<>();
  70. for (String key : param.keySet()) {
  71. paramList.add(new BasicNameValuePair(key, param.get(key)));
  72. }
  73. // 模拟表单
  74. UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
  75. httpPost.setEntity(entity);
  76. }
  77. // 执行http请求
  78. response = httpClient.execute(httpPost);
  79. resultString = EntityUtils.toString(response.getEntity(), "utf-8");
  80. } catch (Exception e) {
  81. e.printStackTrace();
  82. } finally {
  83. try {
  84. response.close();
  85. } catch (IOException e) {
  86. // TODO Auto-generated catch block
  87. e.printStackTrace();
  88. }
  89. }
  90. return resultString;
  91. }
  92. public static String doPost(String url) {
  93. return doPost(url, null);
  94. }
  95. public static String doPostJson(String url, String json) {
  96. // 创建Httpclient对象
  97. CloseableHttpClient httpClient = HttpClients.createDefault();
  98. CloseableHttpResponse response = null;
  99. String resultString = "";
  100. try {
  101. // 创建Http Post请求
  102. HttpPost httpPost = new HttpPost(url);
  103. // 创建请求内容
  104. StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
  105. httpPost.setEntity(entity);
  106. // 执行http请求
  107. response = httpClient.execute(httpPost);
  108. resultString = EntityUtils.toString(response.getEntity(), "utf-8");
  109. } catch (Exception e) {
  110. e.printStackTrace();
  111. } finally {
  112. try {
  113. response.close();
  114. } catch (IOException e) {
  115. // TODO Auto-generated catch block
  116. e.printStackTrace();
  117. }
  118. }
  119. return resultString;
  120. }
  121. }
package com.taotao.common.utils;

import java.io.IOException;

import java.net.URI;

import java.util.ArrayList;

import java.util.List;

import java.util.Map; import org.apache.http.NameValuePair;

import org.apache.http.client.entity.UrlEncodedFormEntity;

import org.apache.http.client.methods.CloseableHttpResponse;

import org.apache.http.client.methods.HttpGet;

import org.apache.http.client.methods.HttpPost;

import org.apache.http.client.utils.URIBuilder;

import org.apache.http.entity.ContentType;

import org.apache.http.entity.StringEntity;

import org.apache.http.impl.client.CloseableHttpClient;

import org.apache.http.impl.client.HttpClients;

import org.apache.http.message.BasicNameValuePair;

import org.apache.http.util.EntityUtils; public class HttpClientUtil {
public static String doGet(String url, Map&lt;String, String&gt; param) {

	// 创建Httpclient对象
CloseableHttpClient httpclient = HttpClients.createDefault(); String resultString = "";
CloseableHttpResponse response = null;
try {
// 创建uri
URIBuilder builder = new URIBuilder(url);
if (param != null) {
for (String key : param.keySet()) {
builder.addParameter(key, param.get(key));
}
}
URI uri = builder.build(); // 创建http GET请求
HttpGet httpGet = new HttpGet(uri); // 执行请求
response = httpclient.execute(httpGet);
// 判断返回状态是否为200
if (response.getStatusLine().getStatusCode() == 200) {
resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (response != null) {
response.close();
}
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
} public static String doGet(String url) {
return doGet(url, null);
} public static String doPost(String url, Map&lt;String, String&gt; param) {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
// 创建参数列表
if (param != null) {
List&lt;NameValuePair&gt; paramList = new ArrayList&lt;&gt;();
for (String key : param.keySet()) {
paramList.add(new BasicNameValuePair(key, param.get(key)));
}
// 模拟表单
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
httpPost.setEntity(entity);
}
// 执行http请求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} return resultString;
} public static String doPost(String url) {
return doPost(url, null);
} public static String doPostJson(String url, String json) {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
// 创建请求内容
StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
httpPost.setEntity(entity);
// 执行http请求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} return resultString;
}

}

(rest项目)contentserviceimpl.java

  1. @Service
  2. public class ContentServiceImpl implements ContentService {
  3. //service 写活,读配置文件
  4. @Value("${REST_BASE_URL}")
  5. private String REST_BASE_URL;
  6. @Value("${REST_CONTENT_URL}")
  7. private String REST_CONTENT_URL;
  8. @Value("${REST_CONTENT_AD1_CID}")
  9. private String REST_CONTENT_AD1_CID;
  10. @Override
  11. public String getAd1List() {
  12. //调用服务获得数据  跨域请求:http://localhost:8081/content/89
  13. String json = HttpClientUtil.doGet(REST_BASE_URL + REST_CONTENT_URL + REST_CONTENT_AD1_CID);
  14. //把json转换成java对象
  15. TaotaoResult taotaoResult = TaotaoResult.formatToList(json, TbContent.class);
  16. //取data属性,内容列表
  17. List<TbContent> contentList = (List<TbContent>) taotaoResult.getData();
  18. //把内容列表转换成AdNode列表
  19. List<AdNode> resultList = new ArrayList<>();
  20. for (TbContent tbContent : contentList) {
  21. AdNode node = new AdNode();
  22. node.setHeight(240);
  23. node.setWidth(670);
  24. node.setSrc(tbContent.getPic());
  25. node.setHeightB(240);
  26. node.setWidthB(550);
  27. node.setSrcB(tbContent.getPic2());
  28. node.setAlt(tbContent.getSubTitle());
  29. node.setHref(tbContent.getUrl());
  30. resultList.add(node);
  31. }
  32. //需要把resultList转换成json数据
  33. String resultJson = JsonUtils.objectToJson(resultList);
  34. return resultJson;
  35. }
  36. }
@Service
public class ContentServiceImpl implements ContentService {
//service 写活,读配置文件
@Value("${REST_BASE_URL}")
private String REST_BASE_URL;
@Value("${REST_CONTENT_URL}")
private String REST_CONTENT_URL;
@Value("${REST_CONTENT_AD1_CID}")
private String REST_CONTENT_AD1_CID;
@Override
public String getAd1List() {
//调用服务获得数据 跨域请求:http://localhost:8081/content/89
String json = HttpClientUtil.doGet(REST_BASE_URL + REST_CONTENT_URL + REST_CONTENT_AD1_CID);
//把json转换成java对象
TaotaoResult taotaoResult = TaotaoResult.formatToList(json, TbContent.class);
//取data属性,内容列表
List&lt;TbContent&gt; contentList = (List&lt;TbContent&gt;) taotaoResult.getData();
//把内容列表转换成AdNode列表
List&lt;AdNode&gt; resultList = new ArrayList&lt;&gt;();
for (TbContent tbContent : contentList) {
AdNode node = new AdNode();
node.setHeight(240);
node.setWidth(670);
node.setSrc(tbContent.getPic()); node.setHeightB(240);
node.setWidthB(550);
node.setSrcB(tbContent.getPic2()); node.setAlt(tbContent.getSubTitle());
node.setHref(tbContent.getUrl()); resultList.add(node);
}
//需要把resultList转换成json数据
String resultJson = JsonUtils.objectToJson(resultList);
return resultJson;
}

}

(rest项目)indexcontroller

  1. @Autowired
  2. private ContentService contentService;
  3. @RequestMapping("/index")
  4. public String showIndex(Model model){
  5. String json=contentService.getAd1List();
  6. model.addAttribute("ad1",json);
  7. return "index";
  8. }
@Autowired
private ContentService contentService;
@RequestMapping("/index")
public String showIndex(Model model){
String json=contentService.getAd1List();
model.addAttribute("ad1",json);
return "index";
}</pre><br>

查看网页源代码,可以看到传过来的json格式的数据。

总结:

HttpClient与Jsonp能够轻易的解决跨域问题,从而得到自己想要的数据(来自不同IP,协议,端口),唯一的不同点是,HttpClient是在Java代码中进行跨域访问,而Jsonp是在js中进行跨域访问。跨域还有一级跨域,二级跨域,更多内容值得研究。

使用Httpclient 完美解决服务端跨域问题的更多相关文章

  1. SharePoint 2013 APP 开发示例 (六)服务端跨域访问 Web Service (REST API)

    上个示例(SharePoint 2013 APP 开发示例 (五)跨域访问 Web Service (REST API))是基于JavaScript,运行在web browser内去访问REST AP ...

  2. 谷歌、火狐浏览器下实现JS跨域iframe高度自适应的完美解决方法,跨域调用JS不再是难题!

    谷歌.火狐浏览器下实现JS跨域iframe高度自适应的解决方法 导读:今天开发的时候遇到个iframe自适应高度的问题,相信大家对这个不陌生,但是一般我们都是在同一个项目使用iframe嵌套页面,这个 ...

  3. 服务端跨域处理 Cors

    1  添加 System.Web.Cors,System.Web.Http.Cors 2 global文件中 注册asp.net 管道事件 protected void Application_Beg ...

  4. CORS服务端跨域

    跨域,通常情况下是说在两个不通过的域名下面无法进行正常的通信,或者说是无法获取其他域名下面的数据,这个主要的原因是,浏览器出于安全问题的考虑,采用了同源策略,通过浏览器对JS的限制,防止恶意用户获取非 ...

  5. .net core api服务端跨域配置

    第1步:添加包引用(.net core 2.2 已自带此包,可跳过此步骤) Install-Package Microsoft.AspNetCore.Cors 第2步:在Startup.cs文件的Co ...

  6. 跨域调用webapi web端跨域调用webapi

    web端跨域调用webapi   在做Web开发中,常常会遇到跨域的问题,到目前为止,已经有非常多的跨域解决方案. 通过自己的研究以及在网上看了一些大神的博客,写了一个Demo 首先新建一个webap ...

  7. Vue Nginx反向代理配置 解决生产环境跨域

    Vue本地代理举例: module.exports = { publicPath: './', devServer: { proxy: { '/api': { target: 'https://mov ...

  8. Nginx配置解决NetCore的跨域

    使用Nginx配置解决NetCore的跨域 废话不多说,直接上Nginx配置 server { listen 80; server_name 你的Id或域名; location / { add_hea ...

  9. SpringCloud微服务Zuul跨域问题

    目前项目结构是VUE做前端,后端采用微服务架构,在开发时前端需要跨域请求数据,通过ZuulFilter配置解决了简单跨域请求需要.但当需要在请求的header中增加token信息时,出现了请求失败的情 ...

随机推荐

  1. 染色(dye)

    染色(dye) Description Serene 和 Achen 在玩染色游戏.Serene 和 Achen 站在一个 n 个点 m 条边的无向连通图中,在第 i 次玩染色游戏时,Serene 在 ...

  2. vagrant网站中box下载方法

    假设需要下载Laravel/homestead这个包. 首先定位到地址:https://app.vagrantup.com/laravel/boxes/homestead/versions/8.0.0 ...

  3. 深入浅出 Java Concurrency (40): 并发总结 part 4 性能与伸缩性[转]

    性能与伸缩性 使用线程的一种说法是为了提高性能.多线程可以使程序充分利用闲置的资源,提高资源的利用率,同时能够并行处理任务,提高系统的响应性. 但是很显然,引入线程的同时也引入了系统的复杂性.另外系统 ...

  4. redis深入学习(二)-----redis配置文件、持久化

    redis配置文件 地址 units单位 a  配置大小单位,开头定义了一些基本的度量单位,只支持bytes,不支持bitb  对大小写不敏感 GENERAL通用 1.daemonize 2.pidf ...

  5. HTML 项目符号

    无序符号 <ul> <li> </li> <li> </li> <li> </li> </ul> 属性 ...

  6. Spring MVC(八)--控制器接受简单列表参数

    有些场景下需要向后台传递一个数组,比如批量删除传多个ID的情况,可以使用数组传递,数组中的ID元素为简单类型,即基本类型. 现在我的测试场景是:要从数据库中查询minId<id<maxId ...

  7. myeclipse启动jboss报ERROR [MainDeployer] Could not create deployment

    今天用myeclipse启动jboss时报了这样的错,花了我将近一天的时间去解决这个问题,开始以为jar包问题,到最后发现是配置错了,所以分享一下.具体报错信息如下图: ERROR [MainDepl ...

  8. jsp页面判断当前请求的host

    需要引入<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %> ...

  9. python-爬免费ip并验证其可行性

    前言 最近在重新温习python基础-正则,感觉正则很强大,不过有点枯燥,想着,就去应用正则,找点有趣的事玩玩 00xx01---代理IP 有好多免费的ip,不过一个一个保存太难了,也不可能,还是用我 ...

  10. Mysql千万级数据性能调优配置

    背景: 笔者的源数据一张表大概7000多万条,数据大小36G,索引6G,加起来表空间有40G+,类似的表有4张,总计2亿多条 数据库mysql,引擎为innodb,版本5.7,服务器内存256G,物理 ...