整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          HttpClient使用指南-GET請求

          能會用到的相關包

          import java.io.IOException;
          import java.net.URLEncoder;
          import org.apache.http.HttpEntity;
          import org.apache.http.client.ClientProtocolException;
          import org.apache.http.client.methods.CloseableHttpResponse;
          import org.apache.http.client.methods.HttpUriRequest;
          import org.apache.http.client.methods.RequestBuilder;
          import org.apache.http.client.utils.HttpClientUtils;
          import org.apache.http.impl.client.CloseableHttpClient;
          import org.apache.http.impl.client.HttpClients;
          import org.apache.http.util.EntityUtils;

          使用HttpClient發送一個普通GET請求

          直接上代碼。

          try {
                      CloseableHttpClient client = HttpClients.createDefault();
                      HttpUriRequest getRequest = RequestBuilder.get("http://localhost:9092/test.jsp")//
                              .addParameter("testIn1", URLEncoder.encode("測試", "GBK"))//
                              .addParameter("testIn2", URLEncoder.encode("測試2", "UTF-8"))//
                              .addHeader("content-type", "text/html:charset=UTF-8")//
                              .build();  
                      CloseableHttpResponse response = client.execute(getRequest);
                      HttpEntity entity = response.getEntity();
                      System.out.println(entity.getContentType().toString());
                      System.out.println(EntityUtils.toString(entity));
                      HttpClientUtils.closeQuietly(response);
          } catch (ClientProtocolException e) {
                      e.printStackTrace();
          } catch (IOException e) {
                      e.printStackTrace();
          }
          1. 創建一個請求客戶端:HttpClients.createDefault(),用來實際發起調用http請求,可以類比成瀏覽器。
          2. 創建一個GET請求:通過請求構造器RequestBuilder的get方法構造一個get請求,通過addParameter方法向get請求里追加參數,通過addHeader方法向get請求里追加請求頭信息,請求頭信息比如content-type,或者雙方約定的請求頭,比如token,通過build方法返回請求對象。
          3. 發送請求并獲得響應:通過請求客戶端的execute方法執行請求并獲得返回值請求響應。
          4. 獲取響應結果:獲取響應對象的實體HttpEntity,通過EntityUtils的toString方法將實體轉成字符串(例子里為請求的一個jsp(html)頁面,實際返回為jsp頁面里html內容),這里一般還要指定字符集,尤其是當返回的實體里沒有指定字符集時。

          注意:通過addParameter項get請求里追加參數時,要通過URLEncoder對參數進行指定字符集編碼,主要是為了解決中文亂碼問題,同樣的,接收方要通過URLDecoder對參數進行對應字符集的解碼。

          附:接收jsp樣例

          <%@page import="java.net.URLDecoder"%>
          <%@page import="java.util.HashMap"%>
          <%@page import="java.nio.charset.Charset"%>
          <%@page language="java" contentType="text/html; charset=GBK" pageEncoding="GBK"%>
          <%
          	System.out.println("默認字符集:" + Charset.defaultCharset().toString());
          	System.out.println("請求字符集:" + request.getCharacterEncoding());
          	System.out.println("請求入參testIn1(utf-8):" + URLDecoder.decode(request.getParameter("testIn1"), "UTF-8"));
          	System.out.println("請求入參testIn1:(gbk)" + URLDecoder.decode(request.getParameter("testIn1"), "GBK") );
          	System.out.println("請求入參testIn1:" + request.getParameter("testIn1"));
          	System.out.println("請求入參testIn2(utf-8):" + URLDecoder.decode(request.getParameter("testIn2"), "UTF-8"));
          	System.out.println("請求入參testIn2:(gbk)" + URLDecoder.decode(request.getParameter("testIn2"), "GBK"));
          	System.out.println("請求入參testIn2:" + request.getParameter("testIn2"));
          %>
          <!DOCTYPE html>
          <html>
          <head>
          <meta charset="GBK">
          <title>這是標題</title>
          </head>
          <body>
          	這是正文部分
          </body>
          </html>

          使用HttpClient發送一個用于文件獲取的GET請求

          try {
          			CloseableHttpClient client = HttpClients.createDefault();
          			HttpGet get = new HttpGet("https://www.baidu.com/img/PCfb_5bf082d29588c07f842ccde3f97243ea.png");
          			CloseableHttpResponse response = client.execute(get);
          			HttpEntity entity = response.getEntity();
          			FileOutputStream fos = new FileOutputStream(new File("D:/abc.png"));
          			entity.writeTo(fos);
          			fos.close();
          } catch (ClientProtocolException e) {
          			e.printStackTrace();
          } catch (IOException e) {
          			e.printStackTrace();
          }
          1. 創建一個請求客戶端:HttpClients.createDefault(),用來實際發起調用http請求,可以類比成瀏覽器。
          2. 創建一個GET請求:直接new一個HttpGet對象,并傳入文件地址,如果有額外參數,建議使用上一例子中的方式創建。
          3. 發起GET請求并獲得響應:通過請求客戶端的execute方法執行請求并獲得返回值請求響應。
          4. 獲取響應結果:獲取響應對象的實體HttpEntity,并將實體通過輸出字節流在本地生成文件,或者想要的其他效果,比如寫入數據庫blob等,可以通過entity.getContent()獲取實體的輸入字節流

          下一期計劃:通過HttpClient發送POST請求。

          您的關注是對我莫大的支持!

          . 增強HttpServletResponse對象

          1. 實現一個增強的HttpServletResponse類,需要繼承javax.servlet.http.HttpServletRequestWrapper類,通過重寫自己需要增強的方法來實現(這種模式就叫做裝飾者模式),使用該增強類在加上過濾器就可以實現無編碼轉換處理代碼。

          public class MyRequest extends HttpServletRequestWrapper{
          	private HttpServletRequest req;
          	public MyRequest(HttpServletRequest request) {
          		super(request);
          		req=request;
          	}
          	@Override
          	public String getParameter(String name) {
          		//解決編碼問題,無論是post還是get請求,都不需要在業務代碼中對編碼再處理
          		String method=req.getMethod();
          		if("get".equalsIgnoreCase(method)){
          			try {
          				String str=req.getParameter(name);
          				byte[] b=str.getBytes("iso8859-1");
          				String newStr=new String(b, "utf-8");
          				return newStr;
          			} catch (UnsupportedEncodingException e) {
          				// TODO Auto-generated catch block
          				e.printStackTrace();
          			}
          		}else if("post".equalsIgnoreCase(method)){
          			try {
          				req.setCharacterEncoding("utf-8");
          			} catch (UnsupportedEncodingException e) {
          				// TODO Auto-generated catch block
          				e.printStackTrace();
          			}
          		}
          		//絕對不能刪除此行代碼,因為此行代碼返回的就是編碼之后的數據
          		return super.getParameter(name);
          	}
          }
          

          在過濾器中應用

          public class FilterTest4 implements Filter {
          	@Override
          	public void init(FilterConfig filterConfig) throws ServletException {}
          	@Override
          	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
          			throws IOException, ServletException {
          		//生成增強的HttpServletRequest對象
          		HttpServletRequest req=(HttpServletRequest) request;
          		MyRequest myReq=new MyRequest(req);
          		//將增強的HttpServletRequest對象傳入過濾器執行鏈中,在后面傳入的request對象都會是增強的HttpServletRequest對象
          		chain.doFilter(myReq, response);
          		
          	}
          	@Override
          	public void destroy() {}
          }
          

          2. 文件上傳原理過程

          1. JavaWeb中實現文件上傳:

          • 客戶端:HTML頁面需要一個<form>表單,且必須設置表單的enctype屬性值為"multipart/form-data",以及method屬性值為"post"(因為get方式不支持大量數據提交);表單里有一個<input type="file" name="">的標簽,且name屬性值必須指定。
          <html>
           <head>
           <title>My JSP 'upload.jsp' starting page</title>
          	<meta http-equiv="pragma" content="no-cache">
          	<meta http-equiv="cache-control" content="no-cache">
          	<meta http-equiv="expires" content="0"> 
          	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
          	<meta http-equiv="description" content="This is my page">
           </head>
           
           <body>
           <form action="" method="post" enctype="multipart/form-data">
           <input type="text" name="name">
           	請選擇文件:<input type="file" name="upload">
           	<input type="submit" value="上傳">
           </form>
           </body>
          </html>
          
          • 服務端:主要進行IO讀寫操作。必須導入commons-fileupload和commons-io兩個jar包,可以通過請求request對象的getInputStream獲得一個流來讀取請求中的文件數據,但是如果客戶端上傳多個文件時,就會很麻煩,所以提供了commons-fileupload和commons-io兩個jar包來更方便的實現文件上傳。
          import java.io.FileOutputStream;
          import java.io.IOException;
          import java.io.InputStream;
          import java.io.OutputStream;
          import java.util.List;
          import javax.servlet.ServletException;
          import javax.servlet.http.HttpServlet;
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;
          import org.apache.commons.fileupload.FileItem;
          import org.apache.commons.fileupload.FileUploadException;
          import org.apache.commons.fileupload.disk.DiskFileItemFactory;
          import org.apache.commons.fileupload.servlet.ServletFileUpload;
          public class UploadServlet extends HttpServlet{
          	@Override
          	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          		/**
          		 * 1. 創建磁盤文件項工廠類 DiskFileItemFactory
          		 * 2. 創建核心解析Request類 ServletFileUpload
          		 * 3. 開始解析Request對象中的數據,并返回一個List集合
          		 * 4. List中包含表單中提交的內容
          		 * 5. 遍歷集合,獲取內容
          		 */
          		DiskFileItemFactory fac=new DiskFileItemFactory();
          		
          		ServletFileUpload upload=new ServletFileUpload(fac);
          		upload.setHeaderEncoding("utf-8");//防止中文的文件名亂碼
          		try {
          			List<FileItem> fileItems = upload.parseRequest(req);
          			for(FileItem item:fileItems){
          				//有可能是普通文本項,比如<input type="text">標簽提交上來的字符串
          				//也有可能是<input type="submit" value="上傳">上傳的文件
          				//文件項與普通項有不同的API來處理
          				//首先判斷是普通文本項還是文件項,
          				if(item.isFormField()){
          					//true表示普通文本項
          					//獲取文本項的name屬性值
          					String name=item.getFieldName();
          					//獲取對應的文本
          					String value=item.getString("utf-8");//防止中文亂碼
          					System.out.println(name+":"+value);
          				}else{
          					//false表示文件項
          					//先獲取文件名稱
          					String name=item.getName();
          					//獲取文件項的輸入流
          					InputStream in=item.getInputStream();
          					//獲取服務器端文件存儲的目標磁盤路徑
          					String path=getServletContext().getRealPath("/upload");
          					System.out.println(path);
          					//獲取輸出流,輸出到本地文件中
          					OutputStream out=new FileOutputStream(path+"/"+name);
          					//寫入數據
          					int len=0;
          					byte[] b=new byte[1024];
          					while((len=in.read(b))!=-1){
          						out.write(b,0,len);
          					}
          					in.close();
          					out.close();
          					
          				}
          			}
          		} catch (FileUploadException e) {
          			// TODO Auto-generated catch block
          			e.printStackTrace();
          		}
          	}
          }
          

          注意:在文件上傳時,會將form表單的屬性enctype屬性值為"multipart/form-data",當提交到服務端后,無法使用 req.getParameter(name) 方法來獲取到內容,只有通過上面的方法來獲取文本項。

          2. 文件上傳相關核心類:

          • DiskFileItemFactory:相關API如下
          • public DiskFileItemFactory():無參構造器
          • public DiskFileItemFactory(int sizeThreshold, File repository):構造器,sizeThreshold設置緩沖區大小,默認10240 byte;repository表示如果過緩沖區空間小于上傳文件空間,那么會生成臨時文件,repository就是指定該臨時文件的保存路徑,如果過未上傳完成就中斷,繼續上傳時就可以通過這個臨時文件來繼續上傳。
          • public void setSizeThreshold(int sizeThreshold):設置緩沖區大小
          • public void setRepository(File repository):指定該臨時文件的保存路徑
          //改進上面的文件上傳代碼,添加一個臨時文件
          public class UploadServlet extends HttpServlet{
          	@Override
          	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          		DiskFileItemFactory fac=new DiskFileItemFactory();
          		fac.setSizeThreshold(1024*1024);//設置緩沖區為1mb
          		//設置臨時文件的本地磁盤存儲路徑
          		File repository=new File(getServletContext().getRealPath("/temp"));
          		fac.setRepository(repository);
          		ServletFileUpload upload=new ServletFileUpload(fac);
          		upload.setHeaderEncoding("utf-8");//防止中文的文件名亂碼
          		try {
          			List<FileItem> fileItems = upload.parseRequest(req);
          			for(FileItem item:fileItems){
          				if(item.isFormField()){
          					String name=item.getFieldName();
          					String value=item.getString();
          					String value=item.getString("utf-8");//防止中文亂碼
          					System.out.println(name+":"+value);
          				}else{
          					String name=item.getName();
          					InputStream in=item.getInputStream();
          					String path=getServletContext().getRealPath("/upload");
          					System.out.println(path);
          					OutputStream out=new FileOutputStream(path+"/"+name);
          					int len=0;
          					byte[] b=new byte[1024];
          					while((len=in.read(b))!=-1){
          						out.write(b,0,len);
          					}
          					in.close();
          					out.close();
          					
          				}
          			}
          		} catch (FileUploadException e) {
          			// TODO Auto-generated catch block
          			e.printStackTrace();
          		}
          	}
          }
          
          • ServletFileUpload:相關API如下
          • public static final boolean isMultipartContent( HttpServletRequest request) :判斷表單提交上來的數據內容是否是multipart類型的數據,即 form表單的 enctype="multipart/form-data",是則返回true,否則返回false
          • public List /* FileItem */ parseRequest(HttpServletRequest request):解析request對象,返回一個泛型為FileItem 的List集合
          • public void setFileSizeMax(long fileSizeMax):設置單個文件的空間大小的最大值
          • public void setSizeMax(long sizeMax):設置所有文件空間大小之和的最大值
          • public void setHeaderEncoding(String encoding):解決上傳文件名的亂碼問題
          • public void setProgressListener(ProgressListener pListener):上傳時的進度條。
          • FileItem:封裝表單中提交的數據
          • boolean isFormField():判斷當前FileItem對象是表單中提交的文本數據項,還是文件數據項
          • String getFieldName():獲取文本項類型FileItem對象的name屬性值,即相當于表單中的 <input type="text" name="name">
          • String getString( String encoding ):獲取文本項類型FileItem對象的value值,可以指定編碼格式,也可以省略encoding不寫
          • String getName():應用于文件項類型的FileItem對象,用于獲取文件的名稱,包括后綴名
          • InputStream getInputStream():獲取輸入流
          • void delete():刪除臨時緩存文件(在輸入以及輸出流關閉后執行)

          3. 實現多文件上傳(需要js技術):主要是更改jsp頁面,通過js代碼來添加多個文件進行上傳,服務器代碼無需更改

          <%@ page language="java" import="java.util.*" pageEncoding="UTF-8" contentType="text/html; charset=utf-8"%>
          <%
          String path = request.getContextPath();
          String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
          %>
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
          <html>
           <head>
           <base href="<%=basePath%>">
           <title>My JSP 'upload.jsp' starting page</title>
          	<meta http-equiv="pragma" content="no-cache">
          	<meta http-equiv="cache-control" content="no-cache">
          	<meta http-equiv="expires" content="0"> 
          	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
          	<meta http-equiv="description" content="This is my page">
           </head>
           
           <body>
           <script type="text/javascript">
           	function run(){
           		var div=document.getElementById("divId");
           		 div.innerHTML+=
           		 "<div><input type='file' name='upload'><input type='button' value='刪除' onclick='del(this)'></div>"
           	}
           	function del(presentNode){
           		var div=document.getElementById("divId");
           		div.removeChild(presentNode.parentNode);
           	}
           </script>
           <div>
           	多文件上傳<br/>
           <form action="/Servlet/upload" method="post" enctype="multipart/form-data">
           	<input type="button" value="添加" onclick="run()"><br/>
           	<div id="divId">
           	
           	</div>
           	
           	<input type="submit" value="上傳">
           </form>
           </div>
           </body>
          </html>
          

          4. 關于文件上傳的一些問題:

          • 文件重名可能會產生覆蓋效果,可以在處理文件名時生成一個唯一的文件名
          • 如果所有的文件都儲存在一個文件夾中,會導致文件夾下文件過多,可以一個用戶一個文件夾,或者利用算法目錄分離等方法。

          3. 文件下載

          1. 傳統文件下載方式有超鏈接下載或者后臺程序下載兩種方式。通過超鏈接下載時,如果瀏覽器可以解析,那么就會直接打開,如果不能解析,就會彈出下載框;而后臺程序下載就必須通過兩個響應頭和一個文件的輸入流。

          2. 后臺程序下載:

          • 兩個響應頭:
          • Content-Type:其值有比如 text/html;charset=utf-8
          • Content-Disposition:其值為 attachment;filename=文件名 以附件形式打開
          • 流:需要獲取文件的輸入流,然后通過response對象的輸出流輸出到客戶端。

          做網站開發時,我們有時候會獲取當前頁面的完整路徑。在網頁前端如何實現呢?

          請在網頁腳本代碼段中粘貼如下代碼。


          function getRootPath() {
                      //獲取當前網址,如: http://localhost:8083/uimcardprj/share/meun.jsp  
                      var curWwwPath = window.document.location.href;
                      //獲取主機地址之后的目錄,如: /uimcardprj/share/meun.jsp  
                      var pathName = window.document.location.pathname;
                      var pos = curWwwPath.indexOf(pathName);
                      //獲取主機地址,如: http://localhost:8083  
                      var localhostPath = curWwwPath.substring(0, pos);
                      //獲取帶"/"的項目名,如:/uimcardprj  
                      var projectName = pathName.substring(0, pathName.substr(1).indexOf('/') + 1);
                      return   localhostPath;
                  }
          
          

          執行該腳本后可獲取本網站及當前網頁的完整域名加路徑


          主站蜘蛛池模板: 中文字幕一区二区人妻| 无码人妻精品一区二区三区在线 | 无码人妻精品一区二区三区不卡 | 精品欧洲AV无码一区二区男男 | 国产乱子伦一区二区三区| 精品一区精品二区| 亚洲一区二区三区影院 | 熟女少妇精品一区二区| 久久久久一区二区三区| 中文字幕AV无码一区二区三区| 午夜视频在线观看一区| 国产av福利一区二区三巨| 精品一区二区三区中文字幕| 亚洲日韩国产欧美一区二区三区| 精品日韩一区二区三区视频| 精品国产一区二区三区2021| 在线视频一区二区三区| 国产一区二区三区不卡在线看| 亚洲永久无码3D动漫一区| 冲田杏梨AV一区二区三区| 精品一区二区三区免费视频| 性无码一区二区三区在线观看| 精品国产一区二区三区久久狼| 亲子乱AV视频一区二区| 色婷婷av一区二区三区仙踪林| 国产福利电影一区二区三区,日韩伦理电影在线福 | 无遮挡免费一区二区三区| 日本不卡一区二区三区| 春暖花开亚洲性无区一区二区| 中文字幕人妻无码一区二区三区| 日本在线视频一区二区| 中文字幕在线视频一区| 亚洲av无码一区二区三区天堂古代 | 无码人妻精品一区二区三区久久| 国产一区二区三区视频在线观看| 一区二区中文字幕| 中文国产成人精品久久一区| 日韩在线一区二区三区视频| 亚洲av鲁丝一区二区三区| 无码毛片一区二区三区视频免费播放| 无码人妻少妇色欲AV一区二区|