HttpClient遠(yuǎn)程請(qǐng)求struts2的文件流并實(shí)現(xiàn)下載的方法

本篇內(nèi)容主要講解“HttpClient遠(yuǎn)程請(qǐng)求struts2的文件流并實(shí)現(xiàn)下載的方法”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“HttpClient遠(yuǎn)程請(qǐng)求struts2的文件流并實(shí)現(xiàn)下載的方法”吧!

我們提供的服務(wù)有:網(wǎng)站設(shè)計(jì)、做網(wǎng)站、微信公眾號(hào)開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、壽陽ssl等。為成百上千企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的壽陽網(wǎng)站制作公司

HttpClientUtil工具類:

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.URI;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class HttpClientUtil {
	private static final Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);
	
    /**
     * 封裝HTTP POST方法
     *
     * @param
     * @param
     * @return
     * @throws ClientProtocolException
     * @throws IOException
     */
    public static String post(String url, Map<String, String> paramMap) throws ClientProtocolException, IOException {
        HttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        //設(shè)置請(qǐng)求和傳輸超時(shí)時(shí)間
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build();
        httpPost.setConfig(requestConfig);
        List<NameValuePair> formparams = setHttpParams(paramMap);
        UrlEncodedFormEntity param = new UrlEncodedFormEntity(formparams, "UTF-8");
        httpPost.setEntity(param);
        HttpResponse response = httpClient.execute(httpPost);
//        logger.info("************{}", response);
        String httpEntityContent = getHttpEntityContent(response);
//        logger.info("************{}", httpEntityContent);
        httpPost.abort();
//        logger.info("************{}", httpEntityContent);
        return httpEntityContent;

    }

    /**
     * 封裝HTTP POST方法
     *
     * @param
     * @param
     * @return
     * @throws ClientProtocolException
     * @throws IOException
     */
    public static HttpResponse postForResponse(String url, Map<String, String> paramMap) throws ClientProtocolException, IOException {
        HttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        //設(shè)置請(qǐng)求和傳輸超時(shí)時(shí)間
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build();
        httpPost.setConfig(requestConfig);
        List<NameValuePair> formparams = setHttpParams(paramMap);
        UrlEncodedFormEntity param = new UrlEncodedFormEntity(formparams, "UTF-8");
        httpPost.setEntity(param);
        HttpResponse response = httpClient.execute(httpPost);
        return response;
    }
    
    /**
     * 封裝HTTP POST方法
     *
     * @param
     * @param (如JSON串)
     * @return
     * @throws ClientProtocolException
     * @throws IOException
     */
    public static String post(String url, String data) throws ClientProtocolException, IOException {
        HttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        //設(shè)置請(qǐng)求和傳輸超時(shí)時(shí)間
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build();
        httpPost.setConfig(requestConfig);
        httpPost.setHeader("Content-Type", "text/json; charset=utf-8");
        httpPost.setEntity(new StringEntity(URLEncoder.encode(data, "UTF-8")));
        HttpResponse response = httpClient.execute(httpPost);
        String httpEntityContent = getHttpEntityContent(response);
        httpPost.abort();
        return httpEntityContent;
    }

    /**
     * 封裝HTTP GET方法
     *
     * @param
     * @return
     * @throws ClientProtocolException
     * @throws IOException
     */
    public static String get(String url) throws ClientProtocolException, IOException {
        HttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet();
        //設(shè)置請(qǐng)求和傳輸超時(shí)時(shí)間
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build();
        httpGet.setConfig(requestConfig);
        httpGet.setURI(URI.create(url));
        HttpResponse response = httpClient.execute(httpGet);
        String httpEntityContent = getHttpEntityContent(response);
        httpGet.abort();
        return httpEntityContent;
    }

    /**
     * 封裝HTTP GET方法
     *
     * @param
     * @param
     * @return
     * @throws ClientProtocolException
     * @throws IOException
     */
    public static String get(String url, Map<String, String> paramMap) throws ClientProtocolException, IOException {
        HttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet();
        //設(shè)置請(qǐng)求和傳輸超時(shí)時(shí)間
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build();
        httpGet.setConfig(requestConfig);
        List<NameValuePair> formparams = setHttpParams(paramMap);
        String param = URLEncodedUtils.format(formparams, "UTF-8");
        httpGet.setURI(URI.create(url + "?" + param));
        HttpResponse response = httpClient.execute(httpGet);
        String httpEntityContent = getHttpEntityContent(response);
        httpGet.abort();
        return httpEntityContent;
    }

    /**
     * 封裝HTTP PUT方法
     *
     * @param
     * @param
     * @return
     * @throws ClientProtocolException
     * @throws IOException
     */
    public static String put(String url, Map<String, String> paramMap) throws ClientProtocolException, IOException {
        HttpClient httpClient = HttpClients.createDefault();
        HttpPut httpPut = new HttpPut(url);
        //設(shè)置請(qǐng)求和傳輸超時(shí)時(shí)間
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build();
        httpPut.setConfig(requestConfig);
        List<NameValuePair> formparams = setHttpParams(paramMap);
        UrlEncodedFormEntity param = new UrlEncodedFormEntity(formparams, "UTF-8");
        httpPut.setEntity(param);
        HttpResponse response = httpClient.execute(httpPut);
        String httpEntityContent = getHttpEntityContent(response);
        httpPut.abort();
        return httpEntityContent;
    }

    /**
     * 封裝HTTP DELETE方法
     *
     * @param
     * @return
     * @throws ClientProtocolException
     * @throws IOException
     */
    public static String delete(String url) throws ClientProtocolException, IOException {
        HttpClient httpClient = HttpClients.createDefault();
        HttpDelete httpDelete = new HttpDelete();
        //設(shè)置請(qǐng)求和傳輸超時(shí)時(shí)間
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build();
        httpDelete.setConfig(requestConfig);
        httpDelete.setURI(URI.create(url));
        HttpResponse response = httpClient.execute(httpDelete);
        String httpEntityContent = getHttpEntityContent(response);
        httpDelete.abort();
        return httpEntityContent;
    }

    /**
     * 封裝HTTP DELETE方法
     *
     * @param
     * @param
     * @return
     * @throws ClientProtocolException
     * @throws IOException
     */
    public static String delete(String url, Map<String, String> paramMap) throws ClientProtocolException, IOException {
        HttpClient httpClient = HttpClients.createDefault();
        HttpDelete httpDelete = new HttpDelete();
        //設(shè)置請(qǐng)求和傳輸超時(shí)時(shí)間
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build();
        httpDelete.setConfig(requestConfig);
        List<NameValuePair> formparams = setHttpParams(paramMap);
        String param = URLEncodedUtils.format(formparams, "UTF-8");
        httpDelete.setURI(URI.create(url + "?" + param));
        HttpResponse response = httpClient.execute(httpDelete);
        String httpEntityContent = getHttpEntityContent(response);
        httpDelete.abort();
        return httpEntityContent;
    }


    /**
     * 設(shè)置請(qǐng)求參數(shù)
     *
     * @param
     * @return
     */
    private static List<NameValuePair> setHttpParams(Map<String, String> paramMap) {
        List<NameValuePair> formparams = new ArrayList<NameValuePair>();
        Set<Map.Entry<String, String>> set = paramMap.entrySet();
        for (Map.Entry<String, String> entry : set) {
            formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }
        return formparams;
    }

    /**
     * 獲得響應(yīng)HTTP實(shí)體內(nèi)容
     *
     * @param response
     * @return
     * @throws IOException
     * @throws UnsupportedEncodingException
     */
    public static String getHttpEntityContent(HttpResponse response) throws IOException, UnsupportedEncodingException {
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            InputStream is = entity.getContent();
            BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
            String line = br.readLine();
            StringBuilder sb = new StringBuilder();
            while (line != null) {
                sb.append(line + "\n");
                line = br.readLine();
            }
            return sb.toString();
        }
        return "";
    }
}

spring跨域請(qǐng)求數(shù)據(jù):

/**
 * 跨域請(qǐng)求數(shù)據(jù)
 * @param model
 * @param code
 * @return
 */
@RequestMapping(value = "/getDataFromCost")
public void getDataFromCost(ModelAndView model,Long eprjInfoId,Long cprjInfoId,Integer uploadType,String loginname,String t,String h,String eprjAuthMap){
	GenericIdentityBean identityBean = this.genGenericIdentity((IdentityBean)model.getModel().get(WebReviewParam.MODEL_IDENTITY));
	UserObject user = userSessionService.getUser(identityBean);
	Map<String,String> postData = new HashMap<>();
	//costHost = "http://localhost:8080/cost";
	String url = costHost+"/token2";
	if(user != null) {
		Map<String, Object> paramsObject;
		try {
			paramsObject = this.goToCost(model, 1l);
			postData.put("loginname", paramsObject.get("loginname")+"");
			postData.put("t", paramsObject.get("t")+"");
			postData.put("h", paramsObject.get("h")+"");
			postData.put("eprjInfoId", "0");
			postData.put("uploadType", "50");
			postData.put("cprjInfoId", cprjInfoId+"");
			postData.put("isChina", "false");
			postData.put("remoteUrl", "down");
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		String filename = "備份文件導(dǎo)出.hwp";
		if(!UnitChange.isEmpty(loginname)){
			try {
				filename = URLDecoder.decode(loginname, "utf-8");
			} catch (Exception e) {
			}
		}
		try {
			HttpResponse postForResponse = HttpClientUtil.postForResponse(url, postData);
			HttpEntity entity = postForResponse.getEntity();
			if(entity != null) {
				InputStream is = entity.getContent();
				HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getResponse();
				
				String contentType = "application/x-hwp";
				String contentDisposition="attachment;";				
				filename = URLEncoder.encode(filename, "UTF-8");
				contentDisposition+="filename=\""+filename+"\"";
				response.setContentType(contentType);
				response.setHeader("accept-ranges", "bytes");
				response.setHeader("Content-Disposition", contentDisposition);
				
				try {
					ServletOutputStream outputStream = response.getOutputStream();
					IOUtils.copy(is, outputStream);
					outputStream.flush();
					outputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		} catch (ClientProtocolException e1) {
			e1.printStackTrace();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
	}
}

//獲取跨域跳轉(zhuǎn)需要的一些參數(shù)

/**
* 跳轉(zhuǎn)造價(jià)詳細(xì)審核頁面
* @return
* @throws Exception 
*/
@ResponseBody
@RequestMapping(value = "/goToCost")
public Map<String,Object> goToCost(ModelAndView model,Long eprjInfoId) throws Exception{
	GenericIdentityBean identityBean = this.genGenericIdentity((IdentityBean)model.getModel().get(WebReviewParam.MODEL_IDENTITY));
	UserObject user = userSessionService.getUser(identityBean);
	if(UnitChange.isEmpty(user.getSecretKey())) {
		user.setSecretKey(UuidUtil.uuid());
		userService.update(identityBean, user.getId(), user);
	}
	Map<String,Object> returnMap = new HashMap<>();
	returnMap.put("loginname", user.getUsername());
	long t = new Date().getTime();
	returnMap.put("t", t);
	String hash = MD5.encode16((user.getUsername()+user.getSecretKey()+t).getBytes(Charset.forName("UTF-8")));
	returnMap.put("h", hash);
	returnMap.put("costHost", costHost);
	returnMap.put("costHost2", GlobalParameters.getServerUrl()+"/cost");  //跳轉(zhuǎn)造價(jià)路徑直接取當(dāng)前域名+/cost
	returnMap.put("returnCode",EprjParam.SUCCESS);
	return returnMap;
}

html頁面和JS:

function downloadFile(url,paramObj){
    var xhr = new XMLHttpRequest();
    // xhr.open('GET', url, true);        // 使用GET方式比較簡單,參數(shù)直接附在URL上
    xhr.open('POST', url, true); 		//POST的格式相對(duì)比較靈活,參數(shù)可以有比較多的形式,例如JSON,表單FORM等   
    xhr.responseType = "blob";    // 返回類型blob 
//    xhr.setRequestHeader("Content-Type","application/json");//提交的數(shù)據(jù)為json格式
    xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
    //后臺(tái)有使用JWT的token驗(yàn)證,會(huì)從請(qǐng)求頭中讀取"X-token"的值,所以這里在請(qǐng)求頭加入"X-token"
    xhr.setRequestHeader("X-token", 'Bearer ' + localStorage.getItem(SAVE_AUTH));
    // 定義請(qǐng)求完成的處理函數(shù)
    xhr.onload = function () {
    	jQuery.messager.progress('close');
        // 請(qǐng)求完成
        if (this.status === 200) {
            // 返回200
            var blob = this.response;
            var reader = new FileReader();
            reader.readAsDataURL(blob);    // 轉(zhuǎn)換為base64,可以直接放入a表情href
            reader.onload = function (e) {
                // 轉(zhuǎn)換完成,創(chuàng)建一個(gè)a標(biāo)簽用于下載
                var a = document.createElement('a');
                a.download = paramObj["cprjName"]+".hwp";
                //可以通過導(dǎo)出空文件確認(rèn)文件最小的長度為700000,如果長度過小,則表示遠(yuǎn)程拋出異常
                if(e.target.result.indexOf("data:application/x-hwp") != -1 &&
 e.target.result.length > 700000){
                	a.href = e.target.result;
                	$("body").append(a);    // 修復(fù)firefox中無法觸發(fā)click
                	a.click();
                	$(a).remove();
                }else{
                	$.messager.show({ icon: "info", msg: "備份文件大小異常,可重新嘗試備份操作!", position: "topCenter" ,timeout:1000, height:80});
                }
            }
        }else{
        	 $.messager.show({ icon: "info", msg: "備份文件大小異常,可重新嘗試備份操作!", position: "topCenter" ,timeout:1000, height:80});
        }
    };
    // 發(fā)送ajax請(qǐng)求,案例中我們使用POST的請(qǐng)求格式,參數(shù)類型為JSON
    var param = {};
    xhr.send(null);
    jQuery.messager.progress({ title:'請(qǐng)稍候...',   text:'正在備份導(dǎo)出,請(qǐng)稍候...', interval:800  });
}

function myDownFun(paramObj){
	var url = "./iface/getDataFromCost?cprjInfoId="+paramObj["cprjInfoId"];
	var rowData = $('#gcxh').treegrid('getSelected');
	url += "&loginname="+encodeURIComponent(encodeURIComponent(rowData.name));
	var postData = {};
	postData["cprjName"] = rowData.cprjNameText;
	downloadFile(url,postData);
//	openPostWindow(url,data);
}

//本來可以使用form表單提交的方式,或者a連接的href進(jìn)行導(dǎo)出,只是這兩種方式不好捕捉和處理遠(yuǎn)程請(qǐng)求的異常exception
//<a class="easyui-linkbutton" href="${object.publicResourcesUrl }" target="_blank" 
//title="備份導(dǎo)出" data-options="plain: true,iconCls:'fas fa-file-download e-icon fa-fw'" download>下載</a>
function openPostWindow(url,obj) {
    var formStr = '';
    //設(shè)置樣式為隱藏,打開新標(biāo)簽再跳轉(zhuǎn)頁面前,如果有可現(xiàn)實(shí)的表單選項(xiàng),用戶會(huì)看到表單內(nèi)容數(shù)據(jù)
    formStr  = '<form id="downTable"  method="POST" action="' + url + '">';
    formStr += '<input type="hidden" name="eprjInfoId" value="0" />';
    formStr += '<input type="hidden" name="cprjInfoId" value="' + obj["cprjInfoId"] + '" />';
    formStr += '<input type="hidden" name="uploadType" value="' + obj["uploadType"] + '" />';
    formStr += '</form>';
    $('body').append(formStr);
    $('#downTable')[0].submit();
    $('#downTable').remove();
}

跨域訪問的方法struts2
 

<action name="token2" method="token2" class="cost-importAndExportAction">
	<result name="myJson" type="json"> <!-- 遠(yuǎn)程請(qǐng)求進(jìn)度條信息,這里不用管 -->
		<param name="contentType">text/html</param>
		<param name="includeProperties">returnCode,message,data.*</param>
		<param name="ignoreHierarchy">false</param>
		<param name="enableGZIP" >true</param>
	</result>
	<result type="stroageStream"><!-- 遠(yuǎn)程請(qǐng)求文件流 -->
		<param name="contentDisposition">${contentDisposition}</param>
		<param name="contentType">${contentType}</param>
		<param name="inputName">inputStream</param>
	</result>
	<result name="login" type="redirect">/default</result>
</action>

java(struts2):

public String token2(){
	if(VerifyString.isEmpty(loginname) || eprjInfoId == null) {
		return "login";
	}
    if (t<System.currentTimeMillis()/1000-60) {    //1分鐘內(nèi)有效
    	return "login";
    }
    UserObject userObject = null;
    try {
    	userObject = userService.findByUsername(null, URLDecoder.decode(loginname, "utf-8"));
	} catch (Exception e) {
	}
    if (userObject==null) {
    	throw new BaseException(this.getClass(),OrganException.USER_NOT_EXIST,"");	
    }
    String hash
=MD5.encode16((userObject.getUsername()+userObject.getSecretKey()+t).getBytes(Charset.forName("UTF-8")));
    if (!hash.equalsIgnoreCase(h)) {
    	throw new BaseException(this.getClass(),OrganException.USER_NOT_EXIST,"");	
    }
	return this.download();//文件流
}

struts2的xml請(qǐng)求配置文件

<action name="download" method="download" class="cost-personnelsAction">
	<result type="stroageStream">
		<param name="contentDisposition">${contentDisposition}</param>
		<param name="contentType">${contentType}</param>
		<param name="inputName">inputStream</param>
	</result>
</action>

文件流:

/**
 * 導(dǎo)出文件
 * @return
 */
@Permission(authorize=Permission.AUTHORIZE_EXPORT)
public String download() 
{
	Boolean isError=false;
	ActionContext context=ActionContext.getContext();
	if (context==null)
	{
		return ActionSupport.ERROR;				
	}
	
	Integer fileLength=0;
	HttpServletRequest request=(HttpServletRequest)context.get(ServletActionContext.HTTP_REQUEST);
	HttpServletResponse response=(HttpServletResponse)context.get(ServletActionContext.HTTP_RESPONSE);;
	try
	{
		String filename = "";
		switch (this.uploadType) {
		case 50:// 建設(shè)項(xiàng)目 工程項(xiàng)目備份導(dǎo)出
			{
				this.inputStream=cprjInfoService.backup(cprjInfoId, eprjInfoId);
				if(this.inputStream != null){ 
					fileLength=this.inputStream.available();
					int minLength=700000;//普通工程大小
                    //備份的建設(shè)項(xiàng)目或工程項(xiàng)目小于700000,代表備份文件有異常,報(bào)錯(cuò)
				    if(fileLength<minLength) {
                        throw new Excpetion(this.getClass(), Cost.COST_ERROR, "備份文件大小異常");
                    }
			    }
				
			}	
			break;
        default:
			break;
		}
		if(inputStream != null)
			fileLength=inputStream.available();
		else
			fileLength=0;

		String method=request.getMethod();
		String userAgent=request.getHeader("User-Agent");
		Browser browser=Browser.fromUserAgent(userAgent);
		this.contentType=FileContentType.buildContentType(filename);
		if("POST".equals(method))
		{
			filename=URLEncoder.encode(filename, "UTF-8");
		}
		else
		{
			switch(browser.getType())
			{
			case Browser.IE:
				filename=URLEncoder.encode(filename, "UTF-8");
				break;
			default:
				filename=new String(filename.getBytes(),"ISO8859-1");
				break;
			}
		}
		
		this.contentDisposition="attachment;";				
		this.contentDisposition+="filename=\""+filename+"\"";

		response.setHeader("accept-ranges", "bytes");
//			response.setHeader("content-length", String.valueOf(fileLength));
	}catch(Exception e)
	{
		isError=true;
		if(e instanceof BaseException)
		{
			this.returnCode=((BaseException)e).getCode();
			this.message=languageException.toString((BaseException)e);
			Log.error(e.getMessage(),e);
		}
		else
		{
			Log.error(e.getMessage(),e);
			this.returnCode=BaseException.UNKNOWN;
			this.message=languageException.toString(e);
		}			
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter out;
		try {
			out = new PrintWriter(response.getWriter());
		
			out.println("<html>");
			out.println("<body bgcolor=\"white\">");
			out.println("<span class=\"bold\">"+this.message+"</span>");
			out.println("</body>");
			out.println("</html>");
			 out.flush();
		} catch (Exception e1) {
		}
		
		return ERROR;
	}
	finally
	{
		if(progress != null && userObject != null)
		{
			progress.put("progressValue", 102);
			progress.put("progressText", "");
			userService.notsupSetProgressInfo(userObject, progress);
		}
	}
	if(!isError)
		return SUCCESS;
	else
		return ERROR;

到此,相信大家對(duì)“HttpClient遠(yuǎn)程請(qǐng)求struts2的文件流并實(shí)現(xiàn)下載的方法”有了更深的了解,不妨來實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

網(wǎng)站欄目:HttpClient遠(yuǎn)程請(qǐng)求struts2的文件流并實(shí)現(xiàn)下載的方法
網(wǎng)頁路徑:http://bm7419.com/article44/pceoee.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站營銷、全網(wǎng)營銷推廣、用戶體驗(yàn)網(wǎng)頁設(shè)計(jì)公司、手機(jī)網(wǎng)站建設(shè)、微信小程序

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)