四闪萄、requet&response

一.request和response的介紹

1. request和response的作用

Web服務器收到客戶端的http請求,會針對每一次請求指巡,分別創(chuàng)建一個用于代表請求的request對象锋叨、和代表響應的response對象
request和response對象即然代表請求和響應,那我們要獲取客戶機提交過來的數(shù)據(jù),只需要找request對象就行了奥裸。要向客戶機輸出數(shù)據(jù),只需要找response對象就行了.


request和response.png

2. request和response的體系結構

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

request和response的體系結構.png

二.response

1. response常用api簡單介紹

response常用api簡單介紹.png

2. response操作響應行

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


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

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

3. response操作響應頭

http響應頭的格式是 name:value的格式,如果有多個value值鹃骂,以”,”分開,
例如:
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操作響應頭 API

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

    public void addHeader(String name, String value)
    用給定名稱和值添加響應頭畏线。此方法允許響應頭有多個值

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

    public void addIntHeader(String name, int value)
    用給定名稱和整數(shù)值添加響應頭蒿叠。此方法允許響應頭有多個值明垢。

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

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

案例1:重定向

重定向.png

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

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

案例2:定時跳轉
在servlet中,我們通過response.setHeader(“refresh”,”3,url=http://localhost/day09/demo2.html”);
response.setHeader("refresh", "3;url=/day09/demo2.html");
在頁面中,我們可以通過
<meta http-equiv="refresh" content="5;url=http://localhost/day09/responseDemo3">
頁面中通過<meta http-equiv=””>方式操作時谷醉,也會將標簽內(nèi)容寫入到http響應中致稀。

4. response操作響應體

http響應正文是我們最終在瀏覽器上看到的結果。
對于HttpServletResponse如果想要操作響應正文俱尼,需要通過response對象獲取到輸出流豺裆,將信息寫回到瀏覽器端.

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

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

操作響應正文注意事項

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

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

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

Serlvet的service方法結束后掖桦,Servlet引擎將檢查getWriter或getOutputStream方法返回的輸出流對象是否已經(jīng)調(diào)用過close方法本昏,如果沒有,Servlet引擎tomcat將調(diào)用close方法關閉該輸出流對象枪汪。調(diào)用close的時候涌穆,會調(diào)用flushBuffer方法.

5. 生成動態(tài)驗證碼

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;

/驗證碼
public class ImageCodeServlet extends HttpServlet {

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

        / 使用java圖形界面技術繪制一張圖片

        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.獲得繪圖對象
        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宿稀、輸出驗證碼內(nèi)容
        graphics.setColor(Color.RED);
        graphics.setFont(new Font("宋體", Font.BOLD, 20));

        / 隨機輸出4個字符
        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、繪制干擾線
        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);
    }

}

常見的漢字:
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簡單介紹

HttpServletRequest對象用于封裝http請求赖捌,對于http請求它有三部分組成祝沸,http請求行,http請求行及請求正文,下圖描述了關于封裝請求信息方法


request常用api簡單介紹.png

2. request操作請求行

public String getMethod()
返回用于發(fā)出此請求的 HTTP 方法的名稱罩锐,例如 GET奉狈、POST
public String getRequestURI()
返回此請求的 URL 的一部分,從協(xié)議名稱一直到 HTTP 請求的第一行中的查詢字符串唯欣。
public String getProtocol()
以 protocol/majorVersion.minorVersion 的形式(例如 HTTP/1.1)返回請求使用的協(xié)議的名稱和版本。
public String getQueryString()
返回包含在請求 URL 中路徑后面的查詢字符串搬味。如果 URL 沒有查詢字符串境氢,則此方法返回 null。

3. request獲取客戶信息

public String getContextPath()
返回請求 URI 指示請求上下文的那一部分碰纬。
public StringBuffer getRequestURL()
重新構造客戶端用于發(fā)出請求的 URL萍聊。返回的 URL 包含一個協(xié)議、服務器名稱悦析、端口號寿桨、服務器路徑,但是不包含查詢字符串參數(shù)强戴。
public String getRemoteAddr()
返回發(fā)送請求的客戶端或最后一個代理的 Internet Protocol (IP) 地址

4. request操作請求頭

public String getHeader(String name)
以 String 的形式返回指定請求頭的值亭螟。
public java.util.Enumeration<E> getHeaders(String name)
以 String 對象的 Enumeration 的形式返回指定請求頭的所有值。
public java.util.Enumeration<E> getHeaderNames()
返回此請求包含的所有頭名稱的枚舉骑歹。如果該請求沒有頭预烙,則此方法返回一個空枚舉。
public int getIntHeader(String name)
以 int 的形式返回指定請求頭的值道媚。如果該請求沒有指定名稱的頭扁掸,則此方法返回 -1。如果無法將頭轉換為整數(shù)最域,則此方法拋出 NumberFormatException谴分。
public long getDateHeader(String name)
以表示 Date 對象的 long 值的形式返回指定請求頭的值

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

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

public String getParameter(String name)
以 String 形式返回請求參數(shù)的值薄翅,如果該參數(shù)不存在钞馁,則返回 null
public String[] getParameterValues(String name)
返回包含給定請求參數(shù)擁有的所有值的 String 對象數(shù)組,如果該參數(shù)不存在匿刮,則返回 null僧凰。
public java.util.Map<K, V> getParameterMap()
返回此請求的參數(shù)的 java.util.Map。請求參數(shù)是與請求一起發(fā)送的額外信息熟丸。對于 HTTP servlet训措,參數(shù)包含在查詢字符串或發(fā)送的表單數(shù)據(jù)中。
public java.util.Enumeration<E> getParameterNames()
返回包含此請求中所包含參數(shù)的名稱的 String 對象的 Enumeration。如果該請求沒有參數(shù)绩鸣,則此方法返回一個空的 Enumeration怀大。

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

原因:
漢字在不同的編碼表中的碼值不一樣,那么在使用不同的編碼表進行解碼與編碼操作時呀闻,就會出現(xiàn)亂碼問題.
請求參數(shù)中如果有中文化借,它是以utf-8碼進行了編碼。
Tomcat得到請求參數(shù)是使用iso8859-1進行了解碼捡多,封裝到了request中蓖康。
在通過request獲取請求信息就是亂碼。
解決:
使用iso8859-1進行編碼
在使用utf-8進行解碼
new String(username.getBytes(“iso8859-1”),”utf-8”);

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

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

request對象同時也是一個域?qū)ο笏夂福_發(fā)人員通過request對象在實現(xiàn)轉發(fā)時,把數(shù)據(jù)通過request對象帶給其它web資源處理.
setAttribute方法
getAttribute方法
removeAttribute方法
getAttributeNames方法

request對象提供了一個getRequestDispatcher方法科贬,該方法返回一個RequestDispatcher對象泳梆,調(diào)用這個對象的forward方法可以實現(xiàn)請求轉發(fā),從而共享請求中的數(shù)據(jù)

8. 請求轉發(fā)

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

2.請求轉發(fā),只有一次請求憎账,一次響應.
重定向鳞溉,有兩次請求,兩次響應鼠哥。

3.請求轉發(fā)存在request域熟菲,可以共享數(shù)據(jù).
重定向不存在request域。

4.請求轉發(fā)只能在服務器的內(nèi)部跳轉朴恳,簡單說抄罕,只能訪問本站內(nèi)資源。
重定向可以訪問站外資源于颖,也可以訪問站內(nèi)資源.

5.請求轉發(fā)是由request 發(fā)起的 . request.getRequestDispatcher().forward()
重定向是由response 發(fā)起的 response.sendRedirect();

6.請求轉發(fā)與重定向時路徑寫法不一樣.
重定向要跳轉的路徑是從瀏覽器在次發(fā)起的呆贿,是瀏覽器端路徑,寫法: /工程名/資源
請求轉發(fā)是服務器內(nèi)部跳轉森渐,這時它與瀏覽器無關 寫法:/資源

9. 請求包含

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

include()和forward()區(qū)別:
都表示要跳轉到其他資源,不同的是耐齐,如果使用forward跳轉則后面的response輸出則不會執(zhí)行浪秘,而用include
來跳轉蒋情,則include的servlet執(zhí)行完后,再返回到原來的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");

輸出結果:
控制臺:servlet A completed
頁面:servlet B
如果將forward換成include的話棵癣,則結果為:
控制臺:servlet A completed
頁面:servlet B servlet A
PS:如果在servlet B里吧pw給close掉了的話,那servlet A 這里就無法輸出了夺衍,則結果就和第一個一樣狈谊。

四、完成用戶下載功能

技術分析:

  • response處理中文亂碼
    字節(jié)流:
    設置瀏覽器默認打開編碼
    response.setHeader("Content-Type", "text/html;charset=UTF-8");
    中文轉成字節(jié)數(shù)組編碼
    response.getOutputStream().write("王守義".getBytes("UTF-8"));
    字符流:
    設置response的緩沖區(qū)的編碼
    response.setCharacterEncoding("UTF-8");
    設置瀏覽器默認打開的編碼.
    response.setHeader("Content-Type", "text/html;charset=UTF-8");
    response.setContentType("text/html;charset=UTF-8");相當于上面兩句
  • 文件下載
    一種:超鏈接方式.(不推薦)
    <a href=”aa.zip”>下載</a>
    <a href=”1.jpg”>下載</a>
    二種:手動編碼方式完成文件下載.
    設置兩個頭和一個流:
    Content-Type:文件MIME的類型.
    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 {
        //獲取下載文件的名稱
        String filename = req.getParameter("name");

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

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

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

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

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

        //方式2:網(wǎng)絡上的方式 (8成好使)
       resp.setHeader("content-disposition", "attachment;filename="+new String(filename.getBytes("gbk"),"iso8859-1"));
        //3.對拷流
        //獲取輸入流
        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();
    }
}
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末沟沙,一起剝皮案震驚了整個濱河市河劝,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌尝胆,老刑警劉巖丧裁,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件护桦,死亡現(xiàn)場離奇詭異含衔,居然都是意外死亡,警方通過查閱死者的電腦和手機二庵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門贪染,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人催享,你說我怎么就攤上這事杭隙。” “怎么了因妙?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵痰憎,是天一觀的道長。 經(jīng)常有香客問我攀涵,道長铣耘,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任以故,我火速辦了婚禮蜗细,結果婚禮上,老公的妹妹穿的比我還像新娘怒详。我一直安慰自己炉媒,他們只是感情好,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布昆烁。 她就那樣靜靜地躺著吊骤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪静尼。 梳的紋絲不亂的頭發(fā)上水援,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天密强,我揣著相機與錄音,去河邊找鬼蜗元。 笑死或渤,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的奕扣。 我是一名探鬼主播薪鹦,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼惯豆!你這毒婦竟也來了池磁?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤楷兽,失蹤者是張志新(化名)和其女友劉穎地熄,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體芯杀,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡端考,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了揭厚。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片却特。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖筛圆,靈堂內(nèi)的尸體忽然破棺而出裂明,到底是詐尸還是另有隱情,我是刑警寧澤太援,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布闽晦,位于F島的核電站,受9級特大地震影響提岔,放射性物質(zhì)發(fā)生泄漏仙蛉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一唧垦、第九天 我趴在偏房一處隱蔽的房頂上張望捅儒。 院中可真熱鬧,春花似錦振亮、人聲如沸巧还。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽麸祷。三九已至,卻和暖如春褒搔,著一層夾襖步出監(jiān)牢的瞬間阶牍,已是汗流浹背喷面。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留走孽,地道東北人惧辈。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像磕瓷,于是被迫代替她去往敵國和親盒齿。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

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