Response

1.HttpServletResponse概述

咱們在建立Servlet時會覆蓋service()方法,或doGet()/doPost(),這些方法都有兩個參數,一個爲表明請求的request和表明響應response。javascript

service方法中的response的類型是ServletResponse,而doGet/doPost方法的response的類型是HttpServletResponse,HttpServletResponse是ServletResponse的子接口,功能和方法更增強大html

response的運行過程java

1.經過response設置響應行

設置響應行的狀態碼web

setStatus(int sc)api

2.經過response設置響應頭

addHeader(String name, String value)瀏覽器

addIntHeader(String name, int value)緩存

addDateHeader(String name, long date)tomcat

setHeader(String name, String value)服務器

setDateHeader(String name, long date)session

setIntHeader(String name, int value)

其中,add表示添加,而set表示設置(不一樣之處)

重定向:狀態碼302 響應頭location 表明重定向的地址

//        response.getWriter().write("doGet runing...");
//        response.setStatus(302);
//        response.setHeader("location", "/web14/redirect2");
        //封裝成一個重定向的方法
        response.sendRedirect("/web/redirect2");
重定向

定時刷新:response.setHeader("refresh", "5;url=https://www.baidu.com");

js完成頁面成功跳轉

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
    window.onload = function(){
        var time = 5;
        var secondEle = document.getElementById("second");
        var timer = setInterval(function(){
            secondEle.innerHTML = time;
            time--;
            if(time==0){
                clearInterval(timer);
                location.href="http://www.baidu.com";
            }
                
        },1000);
    }
</script>
</head>
<body>
    恭喜你,註冊成功,<span style="color:red" id="second">5</span>秒鐘後跳轉,如不跳轉點擊<a href="http://www.baidu.com">這裏</a>!
</body>
</html>
View Code

 

設置響應體

(1)響應體設置文本

PrintWriter getWriter()

得到字符流,經過字符流的write(String s)方法能夠將字符串設置到response   緩衝區中,隨後Tomcat會將response緩衝區中的內容組裝成Http響應返回給瀏覽   器端。

 

關於設置中文的亂碼問題

 

緣由:response緩衝區的默認編碼是iso8859-1,此碼錶中沒有中文,能夠經過     response的setCharacterEncoding(String charset) 設置response的編碼

但咱們發現客戶端仍是不能正常顯示文字

緣由:咱們將response緩衝區的編碼設置成UTF-8,但瀏覽器的默認編碼是本地系     統的編碼,由於咱們都是中文系統,因此客戶端瀏覽器的默認編碼是GBK,咱們能夠   手動修改瀏覽器的編碼是UTF-8。

咱們還能夠在代碼中指定瀏覽器解析頁面的編碼方式,

經過response的setContentType(String type)方法指定頁面解析時的編碼是UTF-8

response.setContentType("text/html;charset=UTF-8");

上面的代碼不只能夠指定瀏覽器解析頁面時的編碼,同時也內含            setCharacterEncoding的功能,因此在實際開發中只要編寫      response.setContentType("text/html;charset=UTF-8");就能夠解決頁面輸出中文亂碼問題。

 

使用response的outputstream輸出圖片,完成outstream

ServletOutputStream  getOutputStream()

得到字節流,經過該字節流的write(byte[] bytes)能夠向response緩衝區中寫入字 節,在由Tomcat服務器將字節內容組成Http響應返回給瀏覽器。

package com.heima.content;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;


import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;



public class ByteServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        //使用response得到字節輸出流
        ServletOutputStream out = response.getOutputStream();
        //得到服務器上的圖片
        String realPath = this.getServletContext().getRealPath("a.jpg");//圖片在WebContent下
        System.out.println(realPath);
        InputStream in =new FileInputStream(realPath);
        int len=0;
        byte[] buffer=new byte[1024];
        while((len=in.read(buffer))>0){
            out.write(buffer,0,len);
        }
        in.close();
        out.close();
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

}
response圖片

文件下載

1什麼狀況下回文件下載?瀏覽器不能解析的文件

2什麼狀況下須要在服務器端編寫文件下載的代碼?  瀏覽器能夠解析的代碼須要編寫文件下載代碼。實際上,只要是下載的文件都編寫下載代碼

package com.heima.content;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class DownloadServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        String filename=request.getParameter("filename");
        //在響應頭中設置要的這個文件的類型,客戶端經過文件的mime類型去區分類型
        response.setContentType(this.getServletContext().getMimeType(filename));
        //告訴客戶端該文件不是直接解析 而是以附件形式打開下載
        response.setHeader("Content-Disposition","attachment;filename="+filename);
        
        String path=this.getServletContext().getRealPath("download/"+filename);
        //得到文件的輸入流
        InputStream in = new FileInputStream(path);
        //得到輸出流--經過response得到的輸出流 用於向客戶端寫內容
        ServletOutputStream out = response.getOutputStream();
        //文件拷貝的模板代碼
        int len=0;
        byte[] buffer=new byte[1024];
        while((len=in.read(buffer))>0){
            out.write(buffer,0,len);
        }
        in.close();
        out.close();
        
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

}
/web14/src/com/heima/content/DownloadServlet.java

文件下載代碼解析過程問題:

1。url傳遞參數filename,reques方法得到,結合filename得到文件絕對路徑path,根據文件路徑得到輸入流FileInputStream

2.response對象方法 得到輸出流,response響應體,  從輸入流到輸出流文件拷貝。

3.response傳遞文件初步完成,存在問題:客戶端會對圖片自動解析,對其餘類型會下載。(需求:全部類型文件下載)

4.告訴客戶端文件非解析,是一附件形式下載----》客戶端文件下載須要告知文件類型---->客戶端經過MIME類型(例子Content-type: text/html)區分

//在響應頭中設置要的這個文件的類型,客戶端經過文件的mime類型去區分類型
        response.setContentType(this.getServletContext().getMimeType(filename));
        //告訴客戶端該文件不是直接解析 而是以附件形式打開下載
        response.setHeader("Content-Disposition","attachment;filename="+filename);
1.告訴瀏覽器設置下載而不是解析打開2.告訴客戶端文件類型MIME

 

中文文件下載過程分析:

1.其餘過程與上面文件下載相同   本地eclipse中文文件參數filename不能解析出來,顯示亂碼,經過string轉碼解決

2.瀏覽器收到respose中的中文文件名進行解碼,各個瀏覽器解碼不一樣,解碼亂碼.  表現爲,下載文件沒有文件名,下載後沒有文件名(文件內容)

3.解決辦法,根據reques中的參數agent進行區分客戶端瀏覽器, 對文件編碼採起和瀏覽器相同的編碼方式,再次編碼.  response

//得到要下載的文件的名稱
        String filename = request.getParameter("filename");//????.jpg
        //解決得到中文參數的亂碼----下節課講
        filename = new String(filename.getBytes("ISO8859-1"),"UTF-8");//美女.jpg

        
        //得到請求頭中的User-Agent
        String agent = request.getHeader("User-Agent");
        //根據不一樣瀏覽器進行不一樣的編碼
        String filenameEncoder = "";
        if (agent.contains("MSIE")) {
            // IE瀏覽器
            filenameEncoder = URLEncoder.encode(filename, "utf-8");
            filenameEncoder = filenameEncoder.replace("+", " ");
        } else if (agent.contains("Firefox")) {
            // 火狐瀏覽器
            BASE64Encoder base64Encoder = new BASE64Encoder();
            filenameEncoder = "=?utf-8?B?"
                    + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
        } else {
            // 其它瀏覽器
            filenameEncoder = URLEncoder.encode(filename, "utf-8");                
        }
中文亂碼問題
package com.heima.content;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import sun.misc.BASE64Encoder;

public class DownloadServlet2 extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String filename=request.getParameter("filename");//美女.jpg亂碼
        filename = new String(filename.getBytes("ISO8859-1"),"UTF-8");//轉碼
        System.out.println(filename);
        
        //得到請求頭中的User-Agent
                String agent = request.getHeader("User-Agent");
                System.out.println(agent);
                //根據不一樣瀏覽器進行不一樣的編碼
                String filenameEncoder = "";
                if (agent.contains("MSIE")) {
                    // IE瀏覽器
                    filenameEncoder = URLEncoder.encode(filename, "utf-8");
                    filenameEncoder = filenameEncoder.replace("+", " ");
                } else if (agent.contains("Firefox")) {
                    // 火狐瀏覽器
                    BASE64Encoder base64Encoder = new BASE64Encoder();
                    filenameEncoder = "=?utf-8?B?"
                            + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
                } else {
                    // 其它瀏覽器
                    filenameEncoder = URLEncoder.encode(filename, "utf-8");                
                }
        
        
        //在響應頭中設置要的這個文件的類型,客戶端經過文件的mime類型去區分類型
        response.setContentType(this.getServletContext().getMimeType(filename));
        //告訴客戶端該文件不是直接解析 而是以附件形式打開下載
        response.setHeader("Content-Disposition","attachment;filename="+filenameEncoder);
        
        String path=this.getServletContext().getRealPath("download/"+filename);
        //得到文件的輸入流
        InputStream in = new FileInputStream(path);
        //得到輸出流--經過response得到的輸出流 用於向客戶端寫內容
        ServletOutputStream out = response.getOutputStream();
        //文件拷貝的模板代碼
        int len=0;
        byte[] buffer=new byte[1024];
        while((len=in.read(buffer))>0){
            out.write(buffer,0,len);
        }
        in.close();
        out.close();
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

}
View Code

response細節:

1.response得到的流不須要手動關閉,tomcat容器會幫咱們關閉

2.getWrite 和 getOutputStream不能同時調用

 

實現驗證碼功能

package com.itheima.checkimg;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
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 CheckImgServlet extends HttpServlet {

    // 集合中保存全部成語
    private List<String> words = new ArrayList<String>();

    @Override
    public void init() throws ServletException {
        // 初始化階段,讀取new_words.txt
        // web工程中讀取 文件,必須使用絕對磁盤路徑
        String path = getServletContext().getRealPath("/WEB-INF/new_words.txt");
        try {
            BufferedReader reader = new BufferedReader(new FileReader(path));
            String line;
            while ((line = reader.readLine()) != null) {
                words.add(line);
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 禁止緩存
        // response.setHeader("Cache-Control", "no-cache");
        // response.setHeader("Pragma", "no-cache");
        // response.setDateHeader("Expires", -1);

        int width = 120;
        int height = 30;

        // 步驟一 繪製一張內存中圖片
        BufferedImage bufferedImage = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);

        // 步驟二 圖片繪製背景顏色 ---經過繪圖對象
        Graphics graphics = bufferedImage.getGraphics();// 獲得畫圖對象 --- 畫筆
        // 繪製任何圖形以前 都必須指定一個顏色
        graphics.setColor(getRandColor(200, 250));
        graphics.fillRect(0, 0, width, height);

        // 步驟三 繪製邊框
        graphics.setColor(Color.WHITE);
        graphics.drawRect(0, 0, width - 1, height - 1);

        // 步驟四 四個隨機數字
        Graphics2D graphics2d = (Graphics2D) graphics;
        // 設置輸出字體
        graphics2d.setFont(new Font("宋體", Font.BOLD, 18));

        Random random = new Random();// 生成隨機數
        int index = random.nextInt(words.size());
        String word = words.get(index);// 得到成語

        // 定義x座標
        int x = 10;
        for (int i = 0; i < word.length(); i++) {
            // 隨機顏色
            graphics2d.setColor(new Color(20 + random.nextInt(110), 20 + random
                    .nextInt(110), 20 + random.nextInt(110)));
            // 旋轉 -30 --- 30度
            int jiaodu = random.nextInt(60) - 30;
            // 換算弧度
            double theta = jiaodu * Math.PI / 180;

            // 得到字母數字
            char c = word.charAt(i);

            // 將c 輸出到圖片
            graphics2d.rotate(theta, x, 20);
            graphics2d.drawString(String.valueOf(c), x, 20);
            graphics2d.rotate(-theta, x, 20);
            x += 30;
        }

        // 將驗證碼內容保存session
        request.getSession().setAttribute("checkcode_session", word);

        // 步驟五 繪製干擾線
        graphics.setColor(getRandColor(160, 200));
        int x1;
        int x2;
        int y1;
        int y2;
        for (int i = 0; i < 30; i++) {
            x1 = random.nextInt(width);
            x2 = random.nextInt(12);
            y1 = random.nextInt(height);
            y2 = random.nextInt(12);
            graphics.drawLine(x1, y1, x1 + x2, x2 + y2);
        }

        // 將上面圖片輸出到瀏覽器 ImageIO
        graphics.dispose();// 釋放資源
        
        //將圖片寫到response.getOutputStream()中
        ImageIO.write(bufferedImage, "jpg", response.getOutputStream());

    }

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

    /**
     * 取其某一範圍的color
     * 
     * @param fc
     *            int 範圍參數1
     * @param bc
     *            int 範圍參數2
     * @return Color
     */
    private Color getRandColor(int fc, int bc) {
        // 取其隨機顏色
        Random random = new Random();
        if (fc > 255) {
            fc = 255;
        }
        if (bc > 255) {
            bc = 255;
        }
        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return new Color(r, g, b);
    }

}
servlet
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
    window.onload = function(){
        
    }
    
    function changeImg(obj){
        obj.src="/WEB14/checkImg?time="+new Date().getTime();
    }

    
</script>

</head>
<body>    
    <form action="/WEB13/login" method="post">
        用戶名:<input type="text" name="username"><br/>
        密碼:<input type="password" name="password"><br/>
        驗證碼:<input type="text" name="username"><img onclick="changeImg(this)" src="/WEB14/checkImg"><br/>
        <input type="submit" value="登陸"><br/>
    </form>
</body>
</html>
html
相關文章
相關標籤/搜索