大数据互联网架构阶段 前台系统架构 跨域请求
生活随笔
收集整理的這篇文章主要介紹了
大数据互联网架构阶段 前台系统架构 跨域请求
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
電商項目 前臺系統(tǒng)的架構(gòu)
零、目錄
- 前臺架構(gòu)設(shè)計
- 前臺分類樹
- 跨域請求技術(shù)
- jsonp
- httpClient
一 、前臺架構(gòu)設(shè)計
二、 前臺分類樹
數(shù)據(jù)的要求
每個data中的list對象進(jìn)行封裝嵌套完成3層結(jié)構(gòu)
u, n, i; 其中u和n都是字符串 i是list集合,集合的元素類型又是itemCatData按照以上要求完成pojo設(shè)計
public class ItemCatResult {@JsonProperty("data")private List<ItemCatData> itemCats ;public List<ItemCatData> getItemCats() {return itemCats;}public void setItemCats(List<ItemCatData> itemCats) {this.itemCats = itemCats;}} public class ItemCatData {@JsonProperty("u")//傳遞時以u傳遞 , 減少跨域傳遞數(shù)據(jù)的字節(jié)數(shù) , 加快傳遞速度private String url;@JsonProperty("n")private String name;@JsonProperty("i")private List<?> items;public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}public String getName() {return name;}public void setName(String name) {this.name = name;}public List<?> getItems() {return items;}public void setItems(List<?> items) {this.items = items;}} 完成三成結(jié)構(gòu)數(shù)據(jù)的封裝 處理前臺分類樹 請求,返回具有三層結(jié)構(gòu)偶的數(shù)據(jù)@RequestMapping("web/itemcat/all")@ResponseBodypublic ItemCatResult queryItemCat() {//整理三層結(jié)構(gòu)的數(shù)據(jù)//先獲取所有的數(shù)據(jù)List<ItemCat> itemCats = itemCatService.queryAll();//創(chuàng)建一個返回對象ItemCatResult result = new ItemCatResult();//引入一個map + list + 三層for循環(huán)嵌套//map維護(hù)當(dāng)前分類中的父子關(guān)系, key保存一個id , value保存該id的所有子類(list形式)Map<Long , List<ItemCat>> map = new HashMap<Long , List<ItemCat>>();//對map進(jìn)行處理for(ItemCat itemCat : itemCats) {//從當(dāng)前的所有l(wèi)ist中獲取一個parentIdif(!map.containsKey(itemCat.getParentId())) {//創(chuàng)建一個map的元素 ,key為整個parentId , value為該id的所有子類(list形式)map.put(itemCat.getParentId(), new ArrayList<ItemCat>());}//把當(dāng)前對象放入map維護(hù)的父子關(guān)系中 。 map.get(itemCat.getParentId()).add(itemCat);}//開始構(gòu)建result對象//一級菜單內(nèi)容 , 從map獲取一級分類的listList<ItemCat> itemCatList01 = map.get(new Long(0));//從一級菜單入手完成result的dataList<ItemCatData> itemCatDataList1 = new ArrayList<ItemCatData>();//完成data里的數(shù)據(jù)for(ItemCat itemCat : itemCatList01) {ItemCatData itemCatData1 = new ItemCatData();itemCatData1.setUrl("/products/"+itemCat.getId()+".html");itemCatData1.setName("<a href='"+itemCatData1.getUrl()+"'>"+itemCat.getName()+"</a>");//進(jìn)行當(dāng)前對象的二層菜單的數(shù)據(jù)封裝個 , 使用第二層forList<ItemCatData> itemCatDataList2 = new ArrayList<ItemCatData>();List<ItemCat> itemCatList02 = map.get(itemCat.getId());for(ItemCat itemCats2 : itemCatList02) {ItemCatData itemCatData2 = new ItemCatData();itemCatData2.setUrl("/products/"+itemCats2.getId()+".html");itemCatData2.setName("<a href='"+itemCatData2.getUrl()+"'>"+itemCats2.getName()+"</a>");List<String> itemCatDataList3 = new ArrayList<String>();List<ItemCat> itemCatList03 = map.get(itemCats2.getId());for(ItemCat itemCat3 : itemCatList03) {itemCatDataList3.add("/products/"+itemCat3.getId()+".html"+itemCat3.getName());}itemCatData2.setItems(itemCatDataList3);itemCatDataList2.add(itemCatData2);}itemCatData1.setItems(itemCatDataList2);itemCatDataList1.add(itemCatData1);}result.setItemCats(itemCatDataList1);return result;}三 、 跨域請求問題
四、 Jsonp跨域請求數(shù)據(jù)
前臺調(diào)用的jquery代碼
$.getJSONP(url , 參數(shù)){}開發(fā)步驟:
自定義responseBody轉(zhuǎn)換器
public class CallbackMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {// 做jsonp的支持的標(biāo)識,在請求參數(shù)中加該參數(shù)private String callbackName;@Overrideprotected void writeInternal(Object object, HttpOutputMessage outputMessage) throws IOException,HttpMessageNotWritableException {// 從threadLocal中獲取當(dāng)前的Request對象HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();String callbackParam = request.getParameter(callbackName);if (StringUtils.isEmpty(callbackParam)) {// 沒有找到callback參數(shù),直接返回json數(shù)據(jù)super.writeInternal(object, outputMessage);} else {JsonEncoding encoding = getJsonEncoding(outputMessage.getHeaders().getContentType());try {//將對象轉(zhuǎn)換為json串,然后用回調(diào)方法包括起來String result = callbackParam + "(" + super.getObjectMapper().writeValueAsString(object)+ ");";IOUtils.write(result, outputMessage.getBody(), encoding.getJavaName());} catch (JsonProcessingException ex) {throw new HttpMessageNotWritableException("Could not write JSON: " + ex.getMessage(), ex);}}}public String getCallbackName() {return callbackName;}public void setCallbackName(String callbackName) {this.callbackName = callbackName;}}將自定義的轉(zhuǎn)換器配置在spring-mvc配置文件中
<!-- MVC注解驅(qū)動 --><mvc:annotation-driven><!-- 采用自定義方案 --><mvc:message-converters><!-- 定義原有的文本轉(zhuǎn)化器 , 如果不定義 則會被后定義的文本轉(zhuǎn)換器覆蓋--><bean class="org.springframework.http.converter.StringHttpMessageConverter"><constructor-arg index="0" value="UTF-8" /></bean><!-- 添加自定義json轉(zhuǎn)化器,完成jsonp格式數(shù)據(jù)的峰裝 , 支持json跨域 --><beanclass="com.jt.common.spring.exetend.jackson.CallbackMappingJackson2HttpMessageConverter"><!-- 跨域請求中的請求參數(shù)名 --><!-- 當(dāng)參數(shù)中有callback屬性時 , 調(diào)用這個轉(zhuǎn)換器 --><!-- 從參數(shù)中尋找callback , 在代碼中處理 --><property name="callbackName" value="callback"></property></bean></mvc:message-converters></mvc:annotation-driven>四、 httpClient跨域請求
自定義httpClientService
@Service public class HttpClientService {private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientService.class);@Autowired(required=false)private CloseableHttpClient httpClient;@Autowired(required=false)private RequestConfig requestConfig;/*** 執(zhí)行g(shù)et請求* * @param url* @return* @throws Exception*/public String doGet(String url,Map<String, String> params,String encode) throws Exception {LOGGER.info("執(zhí)行GET請求,URL = {}", url);if(null != params){URIBuilder builder = new URIBuilder(url);for (Map.Entry<String, String> entry : params.entrySet()) {builder.setParameter(entry.getKey(), entry.getValue());}url = builder.build().toString();}// 創(chuàng)建http GET請求HttpGet httpGet = new HttpGet(url);httpGet.setConfig(requestConfig);CloseableHttpResponse response = null;try {// 執(zhí)行請求response = httpClient.execute(httpGet);// 判斷返回狀態(tài)是否為200if (response.getStatusLine().getStatusCode() == 200) {if(encode == null){encode = "UTF-8";}return EntityUtils.toString(response.getEntity(), encode);}} finally {if (response != null) {response.close();}// 此處不能關(guān)閉httpClient,如果關(guān)閉httpClient,連接池也會銷毀}return null;}public String doGet(String url, String encode) throws Exception{return this.doGet(url, null, encode);}public String doGet(String url) throws Exception{return this.doGet(url, null, null);}/*** 帶參數(shù)的get請求* * @param url* @param params* @return* @throws Exception*/public String doGet(String url, Map<String, String> params) throws Exception {return this.doGet(url, params, null);}/*** 執(zhí)行POST請求* * @param url* @param params* @return* @throws Exception*/public String doPost(String url, Map<String, String> params,String encode) throws Exception {// 創(chuàng)建http POST請求HttpPost httpPost = new HttpPost(url);httpPost.setConfig(requestConfig);if (null != params) {// 設(shè)置2個post參數(shù),一個是scope、一個是qList<NameValuePair> parameters = new ArrayList<NameValuePair>(0);for (Map.Entry<String, String> entry : params.entrySet()) {parameters.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));}// 構(gòu)造一個form表單式的實體UrlEncodedFormEntity formEntity = null;if(encode!=null){formEntity = new UrlEncodedFormEntity(parameters,encode);}else{formEntity = new UrlEncodedFormEntity(parameters);}// 將請求實體設(shè)置到httpPost對象中httpPost.setEntity(formEntity);}CloseableHttpResponse response = null;try {// 執(zhí)行請求response = httpClient.execute(httpPost);// 判斷返回狀態(tài)是否為200if (response.getStatusLine().getStatusCode() == 200) {return EntityUtils.toString(response.getEntity(), "UTF-8");}} finally {if (response != null) {response.close();}}return null;}/*** 執(zhí)行POST請求* * @param url* @param params* @return* @throws Exception*/public String doPost(String url, Map<String, String> params) throws Exception {// 創(chuàng)建http POST請求HttpPost httpPost = new HttpPost(url);httpPost.setConfig(requestConfig);if (null != params) {// 設(shè)置2個post參數(shù),一個是scope、一個是qList<NameValuePair> parameters = new ArrayList<NameValuePair>(0);for (Map.Entry<String, String> entry : params.entrySet()) {parameters.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));}// 構(gòu)造一個form表單式的實體UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters);// 將請求實體設(shè)置到httpPost對象中httpPost.setEntity(formEntity);}CloseableHttpResponse response = null;try {// 執(zhí)行請求response = httpClient.execute(httpPost);// 判斷返回狀態(tài)是否為200if (response.getStatusLine().getStatusCode() == 200) {return EntityUtils.toString(response.getEntity(), "UTF-8");}} finally {if (response != null) {response.close();}}return null;}public String doPostJson(String url, String json) throws Exception {// 創(chuàng)建http POST請求HttpPost httpPost = new HttpPost(url);httpPost.setConfig(requestConfig);if(null != json){//設(shè)置請求體為 字符串StringEntity stringEntity = new StringEntity(json,"UTF-8");httpPost.setEntity(stringEntity);}CloseableHttpResponse response = null;try {// 執(zhí)行請求response = httpClient.execute(httpPost);// 判斷返回狀態(tài)是否為200if (response.getStatusLine().getStatusCode() == 200) {return EntityUtils.toString(response.getEntity(), "UTF-8");}} finally {if (response != null) {response.close();}}return null;}}在spring配置文件中配置
<!-- 定義httpclient連接池 --> <bean id="httpClientConnectionManager" class="org.apache.http.impl.conn.PoolingHttpClientConnectionManager" destroy-method="close"><!-- 設(shè)置連接總數(shù) --><property name="maxTotal" value="${http.pool.maxTotal}"></property><!-- 設(shè)置每個地址的并發(fā)數(shù) --><property name="defaultMaxPerRoute" value="${http.pool.defaultMaxPerRoute}"></property> </bean><!-- 定義 HttpClient工廠,這里使用HttpClientBuilder構(gòu)建--> <bean id="httpClientBuilder" class="org.apache.http.impl.client.HttpClientBuilder" factory-method="create"><property name="connectionManager" ref="httpClientConnectionManager"></property> </bean><!-- 得到httpClient的實例 --> <bean id="httpClient" factory-bean="httpClientBuilder" factory-method="build"/><!-- 定期清理無效的連接 --> <bean class="com.jt.common.util.IdleConnectionEvictor" destroy-method="shutdown"><constructor-arg index="0" ref="httpClientConnectionManager" /><!-- 間隔一分鐘清理一次 --><constructor-arg index="1" value="60000" /> </bean><!-- 定義requestConfig的工廠 --> <bean id="requestConfigBuilder" class="org.apache.http.client.config.RequestConfig.Builder"><!-- 從連接池中獲取到連接的最長時間 --><property name="connectionRequestTimeout" value="${http.request.connectionRequestTimeout}"/><!-- 創(chuàng)建連接的最長時間 --><property name="connectTimeout" value="${http.request.connectTimeout}"/><!-- 數(shù)據(jù)傳輸?shù)淖铋L時間 --><property name="socketTimeout" value="${http.request.socketTimeout}"/><!-- 提交請求前測試連接是否可用 --><property name="staleConnectionCheckEnabled" value="${http.request.staleConnectionCheckEnabled}"/> </bean> <!-- 得到requestConfig實例 --> <bean id="requestConfig" factory-bean="requestConfigBuilder" factory-method="build" />配置文件所需要的參數(shù)信息 httpclient.properties
#從連接池中獲取到連接的最長時間http.request.connectionRequestTimeout=500#5000http.request.connectTimeout=5000#數(shù)據(jù)傳輸?shù)淖铋L時間http.request.socketTimeout=30000#提交請求前測試連接是否可用http.request.staleConnectionCheckEnabled=true#設(shè)置連接總數(shù)http.pool.maxTotal=200#設(shè)置每個地址的并發(fā)數(shù)http.pool.defaultMaxPerRoute=100總結(jié)
以上是生活随笔為你收集整理的大数据互联网架构阶段 前台系统架构 跨域请求的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大数据 互联网架构阶段 Redis(三)
- 下一篇: windows 下终止指定端口的进程