使用Httpclient 完美解决服务端跨域问题

时间:2022-08-28 22:27:48

   项目需求:


     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>  


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


httpclient工作图解:

使用Httpclient 完美解决服务端跨域问题

核心代码展示:


(portal项目)contentcontroller.java

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


(portal项目)HttpClientUtil.java

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

(rest项目)contentserviceimpl.java

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

(rest项目)indexcontroller

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


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

使用Httpclient 完美解决服务端跨域问题


总结:


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