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;
直接上代碼。
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();
}
注意:通過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>
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();
}
下一期計劃:通過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> <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>
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. 文件上傳相關核心類:
//改進上面的文件上傳代碼,添加一個臨時文件 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(); } } }
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. 后臺程序下載:
做網站開發時,我們有時候會獲取當前頁面的完整路徑。在網頁前端如何實現呢?
請在網頁腳本代碼段中粘貼如下代碼。
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;
}
執行該腳本后可獲取本網站及當前網頁的完整域名加路徑
*請認真填寫需求信息,我們會在24小時內與您取得聯系。