四、requet&response

一.request和response的介紹

1. request和response的作用

Web服務(wù)器收到客戶(hù)端的http請(qǐng)求,會(huì)針對(duì)每一次請(qǐng)求,分別創(chuàng)建一個(gè)用于代表請(qǐng)求的request對(duì)象、和代表響應(yīng)的response對(duì)象
request和response對(duì)象即然代表請(qǐng)求和響應(yīng),那我們要獲取客戶(hù)機(jī)提交過(guò)來(lái)的數(shù)據(jù),只需要找request對(duì)象就行了。要向客戶(hù)機(jī)輸出數(shù)據(jù),只需要找response對(duì)象就行了.


request和response.png

2. request和response的體系結(jié)構(gòu)

javax.servlet.Servlet接口中的service方法
public abstract void service(ServletRequest req, ServletResponse res)
javax.servlet.GenericServlet類(lèi)中的service方法
public abstract void service(ServletRequest req, ServletResponse res)
javax.servlet.http.HttpServlet類(lèi)中的service方法
在這個(gè)類(lèi)中對(duì)service方法進(jìn)行了重載
public void service(ServletRequest req, ServletResponse res)
protected void service(HttpServletRequest req, HttpServletResponse resp)

request和response的體系結(jié)構(gòu).png

二.response

1. response常用api簡(jiǎn)單介紹

response常用api簡(jiǎn)單介紹.png

2. response操作響應(yīng)行

在http響應(yīng)行中,包括協(xié)議,版本號(hào),以及有一個(gè)很重要的值,它叫做響應(yīng)狀態(tài)碼.響應(yīng)行中我們主要就是操作這些狀態(tài)碼,它可以有五種類(lèi)型取值:


response操作響應(yīng)行.png
  • 常用狀態(tài)碼
    200請(qǐng)求成功(其后是對(duì)GET和POST請(qǐng)求的應(yīng)答文檔。)
    302所請(qǐng)求的頁(yè)面已經(jīng)臨時(shí)轉(zhuǎn)移至新的url。
    304未按預(yù)期修改文檔。客戶(hù)端有緩沖的文檔并發(fā)出了一個(gè)條件性的請(qǐng)求(一般是提供If-Modified-Since頭表示客戶(hù)只想比指定日期更新的文檔)。服務(wù)器告訴客戶(hù),原來(lái)緩沖的文檔還可以繼續(xù)使用。
    404沒(méi)有找到文件或目錄。
    405請(qǐng)求中指定的方法不被允許
    500請(qǐng)求未完成。服務(wù)器遇到不可預(yù)知的情況

  • HttpServletResponse操作狀態(tài)碼API
    void setStatus(int sc,String sm) 設(shè)置狀態(tài)代碼
    void sendError(int sc) throws IOException設(shè)置錯(cuò)誤狀態(tài)碼
    void sendError(int sc,String msg) throws IOException設(shè)置錯(cuò)誤狀態(tài)碼及信息

3. response操作響應(yīng)頭

http響應(yīng)頭的格式是 name:value的格式,如果有多個(gè)value值,以”,”分開(kāi),
例如:
Content-Encoding: gzip
Content-Length: 123
Content-Language: zh-cn
Content-Type: text/html; charset=GB2312
Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT

  • HttpServletResponse操作響應(yīng)頭 API

    public void setHeader(String name,String value)
    用給定名稱(chēng)和值設(shè)置響應(yīng)頭。如果已經(jīng)設(shè)置了頭,則新值將重寫(xiě)以前的值

    public void addHeader(String name, String value)
    用給定名稱(chēng)和值添加響應(yīng)頭。此方法允許響應(yīng)頭有多個(gè)值

    public void setIntHeader(String name, int value)
    用給定名稱(chēng)和整數(shù)值設(shè)置響應(yīng)頭。如果已經(jīng)設(shè)置了頭,則新值將重寫(xiě)以前的值。

    public void addIntHeader(String name, int value)
    用給定名稱(chēng)和整數(shù)值添加響應(yīng)頭。此方法允許響應(yīng)頭有多個(gè)值。

    public void setDateHeader(String name, long date)
    用給定名稱(chēng)和日期值設(shè)置響應(yīng)頭。該日期根據(jù)距歷元時(shí)間的毫秒數(shù)指定。如果已經(jīng)設(shè)置了頭,則新值將重寫(xiě)以前的值。

    public void addDateHeader(String name, long date)
    用給定名稱(chēng)和日期值添加響應(yīng)頭。該日期根據(jù)距歷元時(shí)間的毫秒數(shù)指定。此方法允許響應(yīng)頭有多個(gè)值。

案例1:重定向

重定向.png

實(shí)現(xiàn):
//1.設(shè)置狀態(tài)碼
response.setStatus(302);
//2.設(shè)置相應(yīng)頭--跳轉(zhuǎn)目錄
response.setHeader(“l(fā)ocation”,”http://localhost/day09/second”);
//response.setHeader(“l(fā)ocation”,”day09/second”);

開(kāi)發(fā)中我們使用sendRedirect(url);
例如:response.sendRedirect(“day09/second”);

案例2:定時(shí)跳轉(zhuǎn)
在servlet中,我們通過(guò)response.setHeader(“refresh”,”3,url=http://localhost/day09/demo2.html”);
response.setHeader("refresh", "3;url=/day09/demo2.html");
在頁(yè)面中,我們可以通過(guò)
<meta http-equiv="refresh" content="5;url=http://localhost/day09/responseDemo3">
頁(yè)面中通過(guò)<meta http-equiv=””>方式操作時(shí),也會(huì)將標(biāo)簽內(nèi)容寫(xiě)入到http響應(yīng)中。

4. response操作響應(yīng)體

http響應(yīng)正文是我們最終在瀏覽器上看到的結(jié)果。
對(duì)于HttpServletResponse如果想要操作響應(yīng)正文,需要通過(guò)response對(duì)象獲取到輸出流,將信息寫(xiě)回到瀏覽器端.

獲得向客戶(hù)端進(jìn)行數(shù)據(jù)輸出的流對(duì)象
OutputStream out = response.getOutputStream();字節(jié)流數(shù)據(jù)輸出
PrintWriter pw = response.getWriter();字符流數(shù)據(jù)輸出

設(shè)置輸出數(shù)據(jù)的編碼格式
默認(rèn)情況下,編碼格式是ISO-8859-1
public void setCharacterEncoding(String charset)
設(shè)置發(fā)送到客戶(hù)端的響應(yīng)的字符編碼
public void setContentType(String type)
設(shè)置將發(fā)送到客戶(hù)端的響應(yīng)的內(nèi)容類(lèi)型,如果該響應(yīng)尚未提交。給定內(nèi)容類(lèi)型可能包含字符編碼規(guī)范,例如 text/html;charset=UTF-8

操作響應(yīng)正文注意事項(xiàng)

getOutputStream和getWriter方法分別用于得到輸出二進(jìn)制數(shù)據(jù)、輸出文本數(shù)據(jù)的ServletOuputStream、Printwriter對(duì)象。

getOutputStream和getWriter這兩個(gè)方法互相排斥,調(diào)用了其中的任何一個(gè)方法后,就不能再調(diào)用另一方法。

Servlet程序向ServletOutputStream或PrintWriter對(duì)象中寫(xiě)入的數(shù)據(jù)將被Servlet引擎從response里面獲取,Servlet引擎將這些數(shù)據(jù)當(dāng)作響應(yīng)消息的正文,然后再與響應(yīng)狀態(tài)行和各響應(yīng)頭組合后輸出到客戶(hù)端。

Serlvet的service方法結(jié)束后,Servlet引擎將檢查getWriter或getOutputStream方法返回的輸出流對(duì)象是否已經(jīng)調(diào)用過(guò)close方法,如果沒(méi)有,Servlet引擎tomcat將調(diào)用close方法關(guān)閉該輸出流對(duì)象。調(diào)用close的時(shí)候,會(huì)調(diào)用flushBuffer方法.

5. 生成動(dòng)態(tài)驗(yàn)證碼

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/驗(yàn)證碼
public class ImageCodeServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        / 使用java圖形界面技術(shù)繪制一張圖片

        int charNum = 4;
        int width = 30 * 4;
        int height = 30;

        / 1. 創(chuàng)建一張內(nèi)存圖片
        BufferedImage bufferedImage = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);

        / 2.獲得繪圖對(duì)象
        Graphics graphics = bufferedImage.getGraphics();

        / 3、繪制背景顏色
        graphics.setColor(Color.YELLOW);
        graphics.fillRect(0, 0, width, height);

        / 4、繪制圖片邊框
        graphics.setColor(Color.BLUE);
        graphics.drawRect(0, 0, width - 1, height - 1);

        / 5、輸出驗(yàn)證碼內(nèi)容
        graphics.setColor(Color.RED);
        graphics.setFont(new Font("宋體", Font.BOLD, 20));

        / 隨機(jī)輸出4個(gè)字符
        Graphics2D graphics2d = (Graphics2D) graphics;
         String s = "ABCDEFGHGKLMNPQRSTUVWXYZ23456789";
        Random random = new Random();
        /session中要用到
        String msg="";
        int x = 5;
        for (int i = 0; i < 4; i++) {
            int index = random.nextInt(32);
            String content = String.valueOf(s.charAt(index));
            msg+=content;
            double theta = random.nextInt(45) * Math.PI / 180;
            /讓字體扭曲
            graphics2d.rotate(theta, x, 18);
            graphics2d.drawString(content, x, 18);
            graphics2d.rotate(-theta, x, 18);
            x += 30;
        }

        / 6、繪制干擾線(xiàn)
        graphics.setColor(Color.GRAY);
        for (int i = 0; i < 5; i++) {
            int x1 = random.nextInt(width);
            int x2 = random.nextInt(width);

            int y1 = random.nextInt(height);
            int y2 = random.nextInt(height);
            graphics.drawLine(x1, y1, x2, y2);
        }

        / 釋放資源
        graphics.dispose();

        / 圖片輸出 ImageIO
        ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
    

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

常見(jiàn)的漢字:
String s = "\u7684\u4e00\u4e86\u662f\u6211\u4e0d\u5728\u4eba\u4eec\u6709\u6765\u4ed6\u8fd9\u4e0a\u7740\u4e2a\u5730\u5230\u5927\u91cc\u8bf4\u5c31\u53bb\u5b50\u5f97\u4e5f\u548c\u90a3\u8981\u4e0b\u770b\u5929\u65f6\u8fc7\u51fa\u5c0f\u4e48\u8d77\u4f60\u90fd\u628a\u597d\u8fd8\u591a\u6ca1\u4e3a\u53c8\u53ef\u5bb6\u5b66\u53ea\u4ee5\u4e3b\u4f1a\u6837\u5e74\u60f3\u751f\u540c\u8001\u4e2d\u5341\u4ece\u81ea\u9762\u524d\u5934\u9053\u5b83\u540e\u7136\u8d70\u5f88\u50cf\u89c1\u4e24\u7528\u5979\u56fd\u52a8\u8fdb\u6210\u56de\u4ec0\u8fb9\u4f5c\u5bf9\u5f00\u800c\u5df1\u4e9b\u73b0\u5c71\u6c11\u5019\u7ecf\u53d1\u5de5\u5411\u4e8b\u547d\u7ed9\u957f\u6c34\u51e0\u4e49\u4e09\u58f0\u4e8e\u9ad8\u624b\u77e5\u7406\u773c\u5fd7\u70b9\u5fc3\u6218\u4e8c\u95ee\u4f46\u8eab\u65b9\u5b9e\u5403\u505a\u53eb\u5f53\u4f4f\u542c\u9769\u6253\u5462\u771f\u5168\u624d\u56db\u5df2\u6240\u654c\u4e4b\u6700\u5149\u4ea7\u60c5\u8def\u5206\u603b\u6761\u767d\u8bdd\u4e1c\u5e2d\u6b21\u4eb2\u5982\u88ab\u82b1\u53e3\u653e\u513f\u5e38\u6c14\u4e94\u7b2c\u4f7f\u5199\u519b\u5427\u6587\u8fd0\u518d\u679c\u600e\u5b9a\u8bb8\u5feb\u660e\u884c\u56e0\u522b\u98de\u5916\u6811\u7269\u6d3b\u90e8\u95e8\u65e0\u5f80\u8239\u671b\u65b0\u5e26\u961f\u5148\u529b\u5b8c\u5374\u7ad9\u4ee3\u5458\u673a\u66f4\u4e5d\u60a8\u6bcf\u98ce\u7ea7\u8ddf\u7b11\u554a\u5b69\u4e07\u5c11\u76f4\u610f\u591c\u6bd4\u9636\u8fde\u8f66\u91cd\u4fbf\u6597\u9a6c\u54ea\u5316\u592a\u6307\u53d8\u793e\u4f3c\u58eb\u8005\u5e72\u77f3\u6ee1\u65e5\u51b3\u767e\u539f\u62ff\u7fa4\u7a76\u5404\u516d\u672c\u601d\u89e3\u7acb\u6cb3\u6751\u516b\u96be\u65e9\u8bba\u5417\u6839\u5171\u8ba9\u76f8\u7814\u4eca\u5176\u4e66\u5750\u63a5\u5e94\u5173\u4fe1\u89c9\u6b65\u53cd\u5904\u8bb0\u5c06\u5343\u627e\u4e89\u9886\u6216\u5e08\u7ed3\u5757\u8dd1\u8c01\u8349\u8d8a\u5b57\u52a0\u811a\u7d27\u7231\u7b49\u4e60\u9635\u6015\u6708\u9752\u534a\u706b\u6cd5\u9898\u5efa\u8d76\u4f4d\u5531\u6d77\u4e03\u5973\u4efb\u4ef6\u611f\u51c6\u5f20\u56e2\u5c4b\u79bb\u8272\u8138\u7247\u79d1\u5012\u775b\u5229\u4e16\u521a\u4e14\u7531\u9001\u5207\u661f\u5bfc\u665a\u8868\u591f\u6574\u8ba4\u54cd\u96ea\u6d41\u672a\u573a\u8be5\u5e76\u5e95\u6df1\u523b\u5e73\u4f1f\u5fd9\u63d0\u786e\u8fd1\u4eae\u8f7b\u8bb2\u519c\u53e4\u9ed1\u544a\u754c\u62c9\u540d\u5440\u571f\u6e05\u9633\u7167\u529e\u53f2\u6539\u5386\u8f6c\u753b\u9020\u5634\u6b64\u6cbb\u5317\u5fc5\u670d\u96e8\u7a7f\u5185\u8bc6\u9a8c\u4f20\u4e1a\u83dc\u722c\u7761\u5174\u5f62\u91cf\u54b1\u89c2\u82e6\u4f53\u4f17\u901a\u51b2\u5408\u7834\u53cb\u5ea6\u672f\u996d\u516c\u65c1\u623f\u6781\u5357\u67aa\u8bfb\u6c99\u5c81\u7ebf\u91ce\u575a\u7a7a\u6536\u7b97\u81f3\u653f\u57ce\u52b3\u843d\u94b1\u7279\u56f4\u5f1f\u80dc\u6559\u70ed\u5c55\u5305\u6b4c\u7c7b\u6e10\u5f3a\u6570\u4e61\u547c\u6027\u97f3\u7b54\u54e5\u9645\u65e7\u795e\u5ea7\u7ae0\u5e2e\u5566\u53d7\u7cfb\u4ee4\u8df3\u975e\u4f55\u725b\u53d6\u5165\u5cb8\u6562\u6389\u5ffd\u79cd\u88c5\u9876\u6025\u6797\u505c\u606f\u53e5\u533a\u8863\u822c\u62a5\u53f6\u538b\u6162\u53d4\u80cc\u7ec6";

三.request

1. request常用api簡(jiǎn)單介紹

HttpServletRequest對(duì)象用于封裝http請(qǐng)求,對(duì)于http請(qǐng)求它有三部分組成,http請(qǐng)求行,http請(qǐng)求行及請(qǐng)求正文,下圖描述了關(guān)于封裝請(qǐng)求信息方法


request常用api簡(jiǎn)單介紹.png

2. request操作請(qǐng)求行

public String getMethod()
返回用于發(fā)出此請(qǐng)求的 HTTP 方法的名稱(chēng),例如 GET、POST
public String getRequestURI()
返回此請(qǐng)求的 URL 的一部分,從協(xié)議名稱(chēng)一直到 HTTP 請(qǐng)求的第一行中的查詢(xún)字符串。
public String getProtocol()
以 protocol/majorVersion.minorVersion 的形式(例如 HTTP/1.1)返回請(qǐng)求使用的協(xié)議的名稱(chēng)和版本。
public String getQueryString()
返回包含在請(qǐng)求 URL 中路徑后面的查詢(xún)字符串。如果 URL 沒(méi)有查詢(xún)字符串,則此方法返回 null。

3. request獲取客戶(hù)信息

public String getContextPath()
返回請(qǐng)求 URI 指示請(qǐng)求上下文的那一部分。
public StringBuffer getRequestURL()
重新構(gòu)造客戶(hù)端用于發(fā)出請(qǐng)求的 URL。返回的 URL 包含一個(gè)協(xié)議、服務(wù)器名稱(chēng)、端口號(hào)、服務(wù)器路徑,但是不包含查詢(xún)字符串參數(shù)。
public String getRemoteAddr()
返回發(fā)送請(qǐng)求的客戶(hù)端或最后一個(gè)代理的 Internet Protocol (IP) 地址

4. request操作請(qǐng)求頭

public String getHeader(String name)
以 String 的形式返回指定請(qǐng)求頭的值。
public java.util.Enumeration<E> getHeaders(String name)
以 String 對(duì)象的 Enumeration 的形式返回指定請(qǐng)求頭的所有值。
public java.util.Enumeration<E> getHeaderNames()
返回此請(qǐng)求包含的所有頭名稱(chēng)的枚舉。如果該請(qǐng)求沒(méi)有頭,則此方法返回一個(gè)空枚舉。
public int getIntHeader(String name)
以 int 的形式返回指定請(qǐng)求頭的值。如果該請(qǐng)求沒(méi)有指定名稱(chēng)的頭,則此方法返回 -1。如果無(wú)法將頭轉(zhuǎn)換為整數(shù),則此方法拋出 NumberFormatException。
public long getDateHeader(String name)
以表示 Date 對(duì)象的 long 值的形式返回指定請(qǐng)求頭的值

5. request獲取請(qǐng)求參數(shù)

請(qǐng)求參數(shù)是瀏覽器發(fā)送請(qǐng)求時(shí)攜帶的信息。
對(duì)于請(qǐng)求方式GET與POST,請(qǐng)求參數(shù)存在位置不同。
GET:請(qǐng)求參數(shù)存在于請(qǐng)求的資源路徑中。
POST:請(qǐng)求參數(shù)存在于正文中

public String getParameter(String name)
以 String 形式返回請(qǐng)求參數(shù)的值,如果該參數(shù)不存在,則返回 null
public String[] getParameterValues(String name)
返回包含給定請(qǐng)求參數(shù)擁有的所有值的 String 對(duì)象數(shù)組,如果該參數(shù)不存在,則返回 null。
public java.util.Map<K, V> getParameterMap()
返回此請(qǐng)求的參數(shù)的 java.util.Map。請(qǐng)求參數(shù)是與請(qǐng)求一起發(fā)送的額外信息。對(duì)于 HTTP servlet,參數(shù)包含在查詢(xún)字符串或發(fā)送的表單數(shù)據(jù)中。
public java.util.Enumeration<E> getParameterNames()
返回包含此請(qǐng)求中所包含參數(shù)的名稱(chēng)的 String 對(duì)象的 Enumeration。如果該請(qǐng)求沒(méi)有參數(shù),則此方法返回一個(gè)空的 Enumeration。

6. request獲取參數(shù)中文出現(xiàn)亂碼

原因:
漢字在不同的編碼表中的碼值不一樣,那么在使用不同的編碼表進(jìn)行解碼與編碼操作時(shí),就會(huì)出現(xiàn)亂碼問(wèn)題.
請(qǐng)求參數(shù)中如果有中文,它是以u(píng)tf-8碼進(jìn)行了編碼。
Tomcat得到請(qǐng)求參數(shù)是使用iso8859-1進(jìn)行了解碼,封裝到了request中。
在通過(guò)request獲取請(qǐng)求信息就是亂碼。
解決:
使用iso8859-1進(jìn)行編碼
在使用utf-8進(jìn)行解碼
new String(username.getBytes(“iso8859-1”),”utf-8”);

如果請(qǐng)求方式是POST,可以直接使用request.setCharacterEncoding(“utf-8”);就可以解決。

7. request域?qū)ο蟮慕榻B

request對(duì)象同時(shí)也是一個(gè)域?qū)ο螅_(kāi)發(fā)人員通過(guò)request對(duì)象在實(shí)現(xiàn)轉(zhuǎn)發(fā)時(shí),把數(shù)據(jù)通過(guò)request對(duì)象帶給其它web資源處理.
setAttribute方法
getAttribute方法
removeAttribute方法
getAttributeNames方法

request對(duì)象提供了一個(gè)getRequestDispatcher方法,該方法返回一個(gè)RequestDispatcher對(duì)象,調(diào)用這個(gè)對(duì)象的forward方法可以實(shí)現(xiàn)請(qǐng)求轉(zhuǎn)發(fā),從而共享請(qǐng)求中的數(shù)據(jù)

8. 請(qǐng)求轉(zhuǎn)發(fā)

請(qǐng)求轉(zhuǎn)發(fā)可以實(shí)現(xiàn)路徑的跳轉(zhuǎn)操作.
ReqeustDispatcher dispatcher=request.getRequestDispatcher("路徑")
dispatcher.forward(request,response)
請(qǐng)求轉(zhuǎn)發(fā)和重定向的區(qū)別:
1.請(qǐng)求轉(zhuǎn)發(fā)是服務(wù)器內(nèi)部跳轉(zhuǎn),地址欄不會(huì)發(fā)生改變
重定向地址欄會(huì)發(fā)生改變。

2.請(qǐng)求轉(zhuǎn)發(fā),只有一次請(qǐng)求,一次響應(yīng).
重定向,有兩次請(qǐng)求,兩次響應(yīng)。

3.請(qǐng)求轉(zhuǎn)發(fā)存在request域,可以共享數(shù)據(jù).
重定向不存在request域。

4.請(qǐng)求轉(zhuǎn)發(fā)只能在服務(wù)器的內(nèi)部跳轉(zhuǎn),簡(jiǎn)單說(shuō),只能訪(fǎng)問(wèn)本站內(nèi)資源。
重定向可以訪(fǎng)問(wèn)站外資源,也可以訪(fǎng)問(wèn)站內(nèi)資源.

5.請(qǐng)求轉(zhuǎn)發(fā)是由request 發(fā)起的 . request.getRequestDispatcher().forward()
重定向是由response 發(fā)起的 response.sendRedirect();

6.請(qǐng)求轉(zhuǎn)發(fā)與重定向時(shí)路徑寫(xiě)法不一樣.
重定向要跳轉(zhuǎn)的路徑是從瀏覽器在次發(fā)起的,是瀏覽器端路徑,寫(xiě)法: /工程名/資源
請(qǐng)求轉(zhuǎn)發(fā)是服務(wù)器內(nèi)部跳轉(zhuǎn),這時(shí)它與瀏覽器無(wú)關(guān) 寫(xiě)法:/資源

9. 請(qǐng)求包含

RequestDispatcher.include()方法用于將RequestDispatcher對(duì)象封裝的資源內(nèi)容作為當(dāng)前響應(yīng)內(nèi)容的一部分包含進(jìn)來(lái),從而實(shí)現(xiàn)可編程的服務(wù)器端包含功能
被包含的Servlet程序不能改變響應(yīng)消息的狀態(tài)碼和響應(yīng)頭,如果它里面存在這樣的語(yǔ)句,這些語(yǔ)句的執(zhí)行結(jié)果將被忽略.include在程序執(zhí)行上效果類(lèi)似forward,但是使用forward只有一個(gè)程序可以生成響應(yīng),include可以由多個(gè)程序一同生成響應(yīng) ----- 常用來(lái)頁(yè)面布局

include()和forward()區(qū)別:
都表示要跳轉(zhuǎn)到其他資源,不同的是,如果使用forward跳轉(zhuǎn)則后面的response輸出則不會(huì)執(zhí)行,而用include
來(lái)跳轉(zhuǎn),則include的servlet執(zhí)行完后,再返回到原來(lái)的servlet執(zhí)行response的輸出(如果有)。如:

servlet A
RequestDispatcher disp = request.getRequestDispatcher("B");
disp.forward(request, response);
System.out.println("servlet A completed");
PrintWriter pw = response.getWriter();
pw.println("servlet A");
servlet B
PrintWriter pw = response.getWriter();
pw.println("servlet B");

輸出結(jié)果:
控制臺(tái):servlet A completed
頁(yè)面:servlet B
如果將forward換成include的話(huà),則結(jié)果為:
控制臺(tái):servlet A completed
頁(yè)面:servlet B servlet A
PS:如果在servlet B里吧pw給close掉了的話(huà),那servlet A 這里就無(wú)法輸出了,則結(jié)果就和第一個(gè)一樣。

四、完成用戶(hù)下載功能

技術(shù)分析:

  • response處理中文亂碼
    字節(jié)流:
    設(shè)置瀏覽器默認(rèn)打開(kāi)編碼
    response.setHeader("Content-Type", "text/html;charset=UTF-8");
    中文轉(zhuǎn)成字節(jié)數(shù)組編碼
    response.getOutputStream().write("王守義".getBytes("UTF-8"));
    字符流:
    設(shè)置response的緩沖區(qū)的編碼
    response.setCharacterEncoding("UTF-8");
    設(shè)置瀏覽器默認(rèn)打開(kāi)的編碼.
    response.setHeader("Content-Type", "text/html;charset=UTF-8");
    response.setContentType("text/html;charset=UTF-8");相當(dāng)于上面兩句
  • 文件下載
    一種:超鏈接方式.(不推薦)
    <a href=”aa.zip”>下載</a>
    <a href=”1.jpg”>下載</a>
    二種:手動(dòng)編碼方式完成文件下載.
    設(shè)置兩個(gè)頭和一個(gè)流:
    Content-Type:文件MIME的類(lèi)型.
    Content-Disposition:
    文件的輸入流:

DownloadServlet核心代碼:

public class DownloadServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //獲取下載文件的名稱(chēng)
        String filename = req.getParameter("name");

        //注意中文亂碼:
        filename=new String(filename.getBytes("iso8859-1"),"utf-8");

        ServletContext context = this.getServletContext();
        //文件下載
        //1.設(shè)置文件的mimeType
        String mimeType = context.getMimeType(filename);
       resp.setContentType(mimeType);

        //2.設(shè)置下載的頭信息
        //上午的
        //response.setHeader("content-disposition", "attchment;filename="+filename);

        //常見(jiàn)的瀏覽器將文件名稱(chēng)使用utf-8 不推薦 不兼容火狐
        //response.setHeader("content-disposition", "attchment;filename="+URLEncoder.encode(filename, "utf-8"));

        //方式1:通過(guò)的方式 通過(guò)工具類(lèi)編碼
        //String _filename=DownLoadUtils.getName(request.getHeader("user-agent"), filename);
        //response.setHeader("content-disposition", "attachment;filename="+_filename);

        //方式2:網(wǎng)絡(luò)上的方式 (8成好使)
       resp.setHeader("content-disposition", "attachment;filename="+new String(filename.getBytes("gbk"),"iso8859-1"));
        //3.對(duì)拷流
        //獲取輸入流
        InputStream is = context.getResourceAsStream("/download/"+filename);

        //獲取輸出流
        ServletOutputStream os =resp.getOutputStream();

        /*int len=-1;
        byte[] b=new byte[1024];

        while((len=is.read(b))!=-1){
            os.write(b, 0, len);
        }*/

        IOUtils.copy(is, os);

        os.close();
        is.close();
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,818評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,185評(píng)論 3 414
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 175,656評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 62,647評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,446評(píng)論 6 405
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 54,951評(píng)論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,041評(píng)論 3 440
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,189評(píng)論 0 287
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,718評(píng)論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,602評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,800評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,045評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,419評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,671評(píng)論 1 281
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,420評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,755評(píng)論 2 371

推薦閱讀更多精彩內(nèi)容