1. 程式人生 > >使用httpclient實現上傳下載(javaWeb系統資料傳輸http實現)

使用httpclient實現上傳下載(javaWeb系統資料傳輸http實現)

目的:專案被拆分為兩個javaWeb專案,實現專案之間資料傳輸以及上傳、下載功能。

前臺展示專案A,後臺提供資料支援專案B

題外話:

兩個javaWeb傳輸之間使用json比較方便,如果恰好使用SpringMVC,配置相關JSON轉換工具(功能很強大非常好用),在@Controller層加上@ResponseBody自動將返回值轉化成json格式

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager">
		<mvc:message-converters register-defaults="true">
			<!-- 將StringHttpMessageConverter的預設編碼設為UTF-8 -->
			<bean class="org.springframework.http.converter.StringHttpMessageConverter">
		    	<constructor-arg value="UTF-8" />
			</bean>
			<!-- 將Jackson2HttpMessageConverter的預設格式化輸出設為true -->
			<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="prettyPrint" value="true"/>
                <property name="objectMapper">  
                    <bean class="com.fasterxml.jackson.databind.ObjectMapper">  
                        <property name="dateFormat">
                            <bean class="java.text.SimpleDateFormat">  
                                <constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss" />  
                            </bean>  
                        </property>  
                    </bean>
                </property>  
            </bean>
  		</mvc:message-converters>
	</mvc:annotation-driven>

	<!-- REST中根據URL字尾自動判定Content-Type及相應的View -->
	<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
	    <property name="ignoreAcceptHeader" value="true" />
            <property name="defaultContentType" value="application/json" />
		    <property name="mediaTypes" >
		        <value>
		            json=application/json
		            xml=application/xml
		        </value>
		    </property>
	</bean>
	
	<!-- jsp配置檢視解析 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/page/"/>
		<property name="suffix" value=".jsp"/>
	</bean>

進入正題:

上傳程式碼: A呼叫上傳工具類(最頭疼的問題就是檔名亂碼)

	
/**
     * 檔案上傳
     * @param is
     * @param fileName
     * @param url
     * @return
     */
    public static String uploadFile(InputStream is ,String fileName ,String url){
        String result = null;
        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost(url);
        //防止檔名亂碼
        InputStreamBody fileis = new InputStreamBody(is,ContentType.create("text/plain", Consts.UTF_8),fileName);
        HttpEntity reqEntity = null;
        HttpResponse responses = null;
        try {
            //BROWSER_COMPATIBLE 設定瀏覽器為相容模式  隨便設定編碼防止亂碼
            reqEntity = MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
                    .addPart("Filedata", fileis).setCharset(CharsetUtils.get("utf-8")).build();
            httppost.setEntity(reqEntity);
            // 如果需要登陸加上sessionId
            httppost.addHeader(new BasicHeader("Cookie", "sessionId=" + clientUser.getSessionId()));
            responses = httpclient.execute(httppost);
            HttpEntity entity = responses.getEntity();
            if(entity != null){
                result = EntityUtils.toString(entity, Charset.forName("utf-8"));
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        return result;
    }

B使用SpringMvc方便得到傳入的檔案。

@RequestMapping(value="/upload",method=RequestMethod.POST)
	@ResponseBody
	public ModelMap upload(MultipartRequest request){

		ModelMap model = new ModelMap();
		MultipartFile file = request.getFile("Filedata");

		
		String realName= null;
		realName = new Date().getTime() + "_" +file.getOriginalFilename();

		File targetFile = new File(UPLOAD_PATH, realName);
		if (!targetFile.exists()) {
			targetFile.mkdirs();
		}
              //生成檔案<pre name="code" class="java">               file.transferTo(targetFile);
return model;} ------------------------------------------------------------------------------------

下載

A呼叫下載  上程式碼

	/**
	 * 檔案下載
	 * @param url
	 * @param fileName
	 * @return
	 */
	public static InputStream fileDownload(String url,String fileName){
		CloseableHttpClient  httpclient = new HttpUtils().buildHttpClient();
		HttpPost httppost = new HttpPost(url);
		StringEntity sEntity = new StringEntity(fileName, Charset.forName("utf-8"));
//		BasicNameValuePair basicNameValuePair = new BasicNameValuePair("fileName",fileName);
//		List<NameValuePair> list = new ArrayList<NameValuePair>(); 
//		list.add(basicNameValuePair);
//		UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(list, Charset.forName("utf-8"));
//   	httppost.setEntity(formEntity);
		httppost.setEntity(sEntity);

		httppost.addHeader(new BasicHeader("Cookie", "sessionId=" + clientUser.getSessionId()));
		httppost.addHeader("Content-Type", "application/xml;charset=utf-8");
		try {
			CloseableHttpResponse responses = httpclient.execute(httppost);
			HttpEntity entity = responses.getEntity();
			InputStream content = entity.getContent();
			return content;
		} catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return null;
	}

B服務端程式碼:遮蔽了response.set部分程式碼,不然會報一個奇怪的錯,無法解決。
	    @RequestMapping(value="/fileDownload",method=RequestMethod.POST)
    @ResponseBody
    public void fileDownload(HttpServletRequest request,HttpServletResponse response){
             // getXmlContent獲取流傳輸的檔名,當然也可以使用request.getAttribute獲取檔名,需要httpclient做一些設定
        String fileName = getXmlContent(request).trim();
        System.out.println("開始下載檔案....."  + fileName);
        try {
            File file = new File(DOWNLOAD_PATH + fileName);
            if(!file.exists() ||  !file.isFile()){
                System.out.println("檔案不存在。。" + fileName );
                return;
            }
            //response.setCharacterEncoding("utf-8");
            //response.setContentType("multipart/form-data");
            //response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
            InputStream inputStream = new FileInputStream(file);
            OutputStream os = response.getOutputStream();
            byte[] b = new byte[1024];
            int length;
            while ((length = inputStream.read(b)) > 0) {
                os.write(b, 0, length);
            }
//            Long filelength = file.length();
//            byte[] b = new byte[filelength.intValue()];
//            inputStream.read(b);
//            os.write(b, 0, filelength.intValue());
            inputStream.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

如果服務端A的下載檔案為中文名,需要轉碼

	try {
			fileName =  new String(fileName.getBytes("iso8859-1"),"UTF-8");
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}


--------------------------------------------------------------------------------無敵大冬瓜-------------------------------------------------------------------------------------------------------------------------

貼段程式碼


import java.io.IOException;
import java.nio.charset.Charset;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
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.config.ConnectionConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.config.SocketConfig;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;


public class HttpUtils {
	
	public static String defaultEncoding= "utf-8";
	
	public static void main(String[] args) {
		HttpUtils httpUtils = new HttpUtils();
		//String result = httpUtils.postRequest("https://zeustracker.abuse.ch/monitor.php?filter=all");
		String result = httpUtils.getRequest("https://hgcg.customs.gov.cn/hgcg/cggg/004001/MoreInfo.aspx?CategoryNum=004001");
		//String result = httpUtils.getRequest("http://www.baidu.com");
		System.out.println("result="+result);
	}
	
	/**
	 * post方式傳送xml資料
	 * @param url
	 * @param xmlData
	 * @return
	 */
	public String sendXMLDataByPost(String url, String xmlData, String sessionId){
		Map<String, String> headersMap = new HashMap<String, String>();
		headersMap.put("Content-Type", "application/xml;charset=utf-8");
		if(StringUtils.isNotBlank(sessionId)){
			headersMap.put("Cookie", "sessionId="+sessionId);
		}
		return this.postRequest(url, headersMap, xmlData);
	}
	
	/**
	 * 傳送http post請求,並返回響應實體
	 * @param url 請求地址
	 * @return url響應實體
	 */
	public String postRequest(String url){
		return postRequest(url, null, "");
	}
	
	/**
	 * 傳送http post請求,並返回響應實體
	 * @param url 請求的url
	 * @param headersMap 請求需要新增的請求頭
	 * @return url響應實體
	 */
	public String postRequest(String url, Map<String, String> headersMap){
		return postRequest(url, headersMap, "");
	}
	
	/**
	 * 傳送http post請求,並返回響應實體
	 * @param url 訪問的url
	 * @param headersMap 請求需要新增的請求頭
	 * @param paramsMap	請求的引數
	 * @return
	 */
	public String postRequest(String url, Map<String, String> headersMap, Map<String, String> paramsMap){
		String result = null;
		CloseableHttpClient httpClient = buildHttpClient();
		HttpPost httpPost = new HttpPost(url);
		if(null != headersMap && headersMap.size() > 0){
			for (Entry<String, String> entry : headersMap.entrySet()) {
				String key = entry.getKey();
				String value = entry.getValue();
				httpPost.addHeader(new BasicHeader(key, value));
			}
		}
		List<NameValuePair> list = new ArrayList<NameValuePair>(paramsMap.size());
		if(null != paramsMap && paramsMap.size() > 0){
			for (Entry<String, String> entry : paramsMap.entrySet()) {
				list.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
			}
		}
		try{
			UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(list, Charset.forName(defaultEncoding));
			httpPost.setEntity(formEntity);
			CloseableHttpResponse response = httpClient.execute(httpPost);
			try{
				HttpEntity entity = response.getEntity();
				if(entity != null){
					result = EntityUtils.toString(entity, Charset.forName(defaultEncoding));
				}
			}finally{
				response.close();
			}
		}catch(Exception ex){
			ex.printStackTrace();
		}finally{
			try {
				httpClient.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		return result;
	}
	
	/**
	 * 傳送http post請求,並返回響應實體
	 * @param url 訪問的url
	 * @param headersMap 請求需要新增的請求頭
	 * @param paramsMap	請求實體內容
	 * @return
	 */
	public String postRequest(String url, Map<String, String> headersMap, String content){
		String result = null;
		CloseableHttpClient httpClient = buildHttpClient();
		HttpPost httpPost = new HttpPost(url);
		if(null != headersMap && headersMap.size() > 0){
			for (Entry<String, String> entry : headersMap.entrySet()) {
				String key = entry.getKey();
				String value = entry.getValue();
				httpPost.addHeader(new BasicHeader(key, value));
			}
		}
		try{
			if(StringUtils.isNotBlank(content)){
				httpPost.setEntity(new StringEntity(content, Charset.forName(defaultEncoding)));
			}
			CloseableHttpResponse response = httpClient.execute(httpPost);
			try{
				HttpEntity entity = response.getEntity();
				if(entity != null){
					result = EntityUtils.toString(entity, Charset.forName(defaultEncoding));
				}
			}finally{
				response.close();
			}
		}catch(Exception ex){
			ex.printStackTrace();
		}finally{
			try {
				httpClient.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		return result;
	}
	
	/**
	 * 傳送http get請求
	 * @param url 請求url
	 * @return url返回內容
	 */
	public String getRequest(String url){
		return getRequest(url, "");
	}
	
	/**
	 * 傳送http get請求
	 */
	public String getRequest(String url, String sessionId) {
		Map<String, String> headersMap = new HashMap<String, String>();
		headersMap.put("Content-Type", "application/xml;charset=utf-8");
		if(StringUtils.isNotBlank(sessionId)){
			headersMap.put("Cookie", "sessionId="+sessionId);
		}
		return getRequest(url, headersMap);
	}
	
	/**
	 * 傳送http get請求
	 * @param url 請求的url
	 * @param headersMap 請求頭
	 * @return
	 */
	public String getRequest(String url, Map<String, String> headersMap){
		String result = null;
		CloseableHttpClient httpClient = buildHttpClient();
		try{
			
			HttpGet httpGet = new HttpGet(url);
			if(null != headersMap && headersMap.size() > 0){
				for (Entry<String, String> entry : headersMap.entrySet()) {
					String key = entry.getKey();
					String value = entry.getValue();
					httpGet.addHeader(new BasicHeader(key, value));
				}
			}
			CloseableHttpResponse response = httpClient.execute(httpGet);
			try{
				HttpEntity entity = response.getEntity();
				if(null != entity){
					result = EntityUtils.toString(entity, defaultEncoding);
				}
			}finally{
				response.close();
			}
		} catch (ClientProtocolException e) {  
            e.printStackTrace();  
        } catch (ParseException e) {
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }finally{
			try {
				httpClient.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return result;
	}
	
	/**
	 * 建立httpclient
	 * @return
	 */
	public CloseableHttpClient buildHttpClient() {
		try {
			RegistryBuilder<ConnectionSocketFactory> builder = RegistryBuilder.create();
			ConnectionSocketFactory factory = new PlainConnectionSocketFactory();
			builder.register("http", factory);
			KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
			SSLContext context = SSLContexts.custom().useTLS().loadTrustMaterial(trustStore, new TrustStrategy() {
				@Override
				public boolean isTrusted(X509Certificate[] chain, String authType)
						throws CertificateException {
					return true;
				}
			}).build();
			//LayeredConnectionSocketFactory sslFactory = new SSLConnectionSocketFactory(context, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
			LayeredConnectionSocketFactory sslFactory = new SSLConnectionSocketFactory(context, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER){
				protected void prepareSocket(SSLSocket socket) throws IOException {
				    // Workaround to use different order of CipherSuites used by Java6 in order
			        // to avoid the the problem of java7 "Could not generate DH keypair"
			        String[] enabledCipherSuites = socket.getEnabledCipherSuites();

			        // but to avoid hardcoding a new list, we just remove the entries
			        // which cause the exception (via TrialAndError)
			        List<String> asList = new ArrayList<String>(Arrays.asList(enabledCipherSuites));

			        // we identified the following entries causeing the problems
			        // "Could not generate DH keypair"
			        // and "Caused by: java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive)"
			        asList.remove("TLS_DHE_RSA_WITH_AES_128_CBC_SHA");
			        asList.remove("SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA");
			        asList.remove("TLS_DHE_RSA_WITH_AES_256_CBC_SHA");
			        String[] array = asList.toArray(new String[0]);
			        socket.setEnabledCipherSuites(array);
			    };
			};
			
			builder.register("https", sslFactory);
			Registry<ConnectionSocketFactory> registry = builder.build();
			
			PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager(registry);
			ConnectionConfig connConfig = ConnectionConfig.custom().setCharset(Charset.forName(defaultEncoding)).build();
			SocketConfig socketConfig = SocketConfig.custom().setSoTimeout(100000).build();
			manager.setDefaultConnectionConfig(connConfig);
			manager.setDefaultSocketConfig(socketConfig);
			return HttpClientBuilder.create().setConnectionManager(manager).build();
		} catch (KeyStoreException e) {
			e.printStackTrace();
		} catch (KeyManagementException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return null;
	}
}