HttpServletResponse對象(二)之常見應用

---恢復內容開始---javascript

1. 使用HttpServletResponse對象實現文件下載css

文件下載功能是web開發中常常使用到的功能,使用HttpServletResponse對象就能夠實現文件的下載。文件下載功能的實現思路:java

  1.獲取要下載的文件的絕對路徑程序員

  2.獲取要下載的文件名web

  3.設置content-disposition響應頭控制瀏覽器如下載的形式打開文件瀏覽器

  4.獲取要下載的文件輸入流緩存

  5.建立數據緩衝區服務器

  6.經過response對象獲取OutputStream流微信

  7.將FileInputStream流寫入到buffer緩衝區app

  8.使用OutputStream將緩衝區的數據輸出到客戶端瀏覽器

示例代碼以下:

package myTest;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FileDownload extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
    	//下載文件,經過OutputStream流
        downloadFileByOutputStream(response);
    }

    private void downloadFileByOutputStream(HttpServletResponse response)
            throws FileNotFoundException, IOException {
        //1.獲取要下載的文件的絕對路徑
        String realPath = this.getServletContext().getRealPath("/download/1.png");
        //2.獲取要下載的文件名
        String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);
        //3.設置content-disposition響應頭控制瀏覽器如下載的形式打開文件
        response.setHeader("content-disposition", "attachment;filename="+fileName);
        //4.獲取要下載的文件輸入流
        InputStream in = new FileInputStream(realPath);
        int len = 0;
        //5.建立數據緩衝區
        byte[] buffer = new byte[1024];
        //6.經過response對象獲取OutputStream流
        OutputStream out = response.getOutputStream();
        //7.將FileInputStream流寫入到buffer緩衝區
        while ((len = in.read(buffer)) > 0) {
        //8.使用OutputStream將緩衝區的數據輸出到客戶端瀏覽器
            out.write(buffer,0,len);
        }
        in.close();
    }

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

 上述代碼中:

  1. getServletContext():返回對調用者正在執行的ServletContext的引用;

  2. substring(int beginIndex):返回一個字符串,該字符串是此字符串的子字符串。 子串以指定索引處的字符開頭,並延伸到此字符串的末尾。例如:"unhappy".substring(2) returns "happy","Harbison".substring(3) returns "bison","emptiness".substring(9) returns "" (an empty string);

編輯web.xml文件,運行後顯示:

點擊保存便可從服務器將該文件下載下來。

下載中文文件時,須要注意的地方就是中文文件名要使用URLEncoder.encode方法進行編碼(URLEncoder.encode(fileName, "字符編碼")),以下,不然會出現文件名亂碼。

response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(fileName,UTF-8));

編寫文件下載功能時推薦使用OutputStream流,避免使用PrintWriter流,由於OutputStream流是字節流,能夠處理任意類型的數據,而PrintWriter流是字符流,只能處理字符數據,若是用字符流處理字節數據,會致使數據丟失。

2. 生成驗證碼

生成隨機圖片用做驗證碼

生成圖片主要用到了一個BufferedImage類。

示例代碼以下:

package myTest;

import java.awt.Color;
import java.awt.Font;
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 ImageDemo extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
    	//設置refresh響應頭控制瀏覽器每隔5秒鐘刷新一次
        response.setHeader("refresh", "5");
        //1.在內存中建立一張圖片
        BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
        //2.獲得圖片
        //Graphics g = image.getGraphics();
        Graphics2D g = (Graphics2D)image.getGraphics();
        g.setColor(Color.WHITE);//設置圖片的背景色
        g.fillRect(0, 0, 80, 20);//填充背景色
        //3.向圖片上寫數據
        g.setColor(Color.BLUE);//設置圖片上字體的顏色
        g.setFont(new Font(null, Font.BOLD, 20));
        g.drawString(makeNum(), 0, 20);
        //4.設置響應頭控制瀏覽器瀏覽器以圖片的方式打開
        response.setContentType("image/jpeg");//等同於response.setHeader("Content-Type", "image/jpeg");
        //5.設置響應頭控制瀏覽器不緩存圖片數據
        response.setDateHeader("expries", -1);
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Pragma", "no-cache");
        //6.將圖片寫給瀏覽器
        ImageIO.write(image, "jpg", response.getOutputStream());
    }

    /**
     * 生成隨機數字
     * @return
     */
    private String makeNum(){
        Random random = new Random();
        String num = random.nextInt(9999999)+"";
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 7-num.length(); i++) {
            sb.append("0");
        }
        num = sb.toString()+num;
        return num;
    }
    
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

 配置xml.web文件,運行後顯示結果:

由於設置了每5秒刷新一次,response.setHeader("refresh", "5"); 因此每隔5秒鐘隨機生成一個驗證碼。

3. 設置響應頭控制瀏覽器的行爲

3.1 設置http響應頭控制瀏覽器禁止緩存當前文檔內容

response.setDateHeader("expries", -1);
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");

3.2 設置http響應頭控制瀏覽器定時刷新網頁(refresh)

//設置refresh響應頭控制瀏覽器每隔5秒鐘刷新一次 
response.setHeader("refresh", "5");

3.3 經過response實現請求重定向

一個web資源收到客戶端請求後,通知客戶端去訪問另一個web資源,這稱之爲請求重定向。好比配合302狀態實現重定向。

response.setStatue(302);
response.setHeader(「location」,」/day06/index.jsp」)

 或者sendRedirect(String location)實現重定向。

response.sendRedirect(「/day06/index.jsp」);

請求重定向會致使服務器接受兩次請求,加劇服務器的負擔。因此通常不推薦使用(通常推薦轉發方式)。可是在製做登陸後跳轉到首頁這一功能的時候必須使用請求重定向,這可使地址欄發生變化,主要是起到提示用戶已跳轉到首頁的做用。還有購物的時候點擊購物按鈕跳轉到購物車顯示頁面的時候須要使用請求重定向,它能夠避免轉發時點擊刷新形成的屢次夠買的錯誤。

示例代碼以下:

package myTest;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class sendRedirectDemo extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.sendRedirect("/JavaWeb_HttpServletResponse_Study_20140615/index.jsp");
    }

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

sendRedirect內部的實現原理是使用response設置302狀態碼和設置location響應頭實現重定向,sendRedirect方法內部調用瞭如下兩個方法

response.setHeader("Location", "/JavaWeb_HttpServletResponse_Study_20140615/index.jsp");
response.setStatus(HttpServletResponse.SC_FOUND);//設置302狀態碼,等同於response.setStatus(302);

4. web工程中URL地址的推薦寫法

在JavaWeb開發中,只要是寫URL地址,那麼建議最好以"/"開頭,也就是使用絕對路徑的方式,若是"/"是給服務器用的,則表明當前的web工程,若是"/"是給瀏覽器用的,則表明webapps目錄。

4.1 "/"表明當前web工程的常見應用場景

①.ServletContext.getRealPath(String path)獲取資源的絕對路徑

this.getServletContext().getRealPath("/download/1.JPG");//表示的就是讀取web工程下的download文件夾中的1.JPG這個資源

 ②.在服務器端forward到其餘頁面

客戶端請求某個web資源,服務器跳轉到另一個web資源,這個forward也是給服務器用的,那麼這個"/"就是給服務器用的,因此此時"/"表明的就是web工程。

this.getServletContext().getRequestDispatcher("/index.jsp").forward(request, response);

 ③.使用include指令或者<jsp:include>標籤引入頁面

<%@include file="/jspfragments/head.jspf" %>
<jsp:include page="/jspfragments/demo.jsp" />

4.2 "/"表明webapps目錄的常見應用場景

①.使用sendRedirect實現請求重定向

response.sendRedirect("/JavaWeb_HttpServletResponse_Study_20140615/index.jsp");

服務器發送一個URL地址給瀏覽器,瀏覽器拿到URL地址以後,再去請求服務器,因此這個"/"是給瀏覽器使用的,此時"/"表明的就是webapps目錄,"/JavaWeb_HttpServletResponse_Study_20140615/index.jsp"這個地址指的就是"webapps\JavaWeb_HttpServletResponse_Study_20140615\index.jsp"

response.sendRedirect("/項目名稱/文件夾目錄/頁面");這種寫法是將項目名稱寫死在程序中的作法,不靈活,萬一哪天項目名稱變了,此時就得改程序,因此推薦使用下面的靈活寫法:

將上面這種寫法改爲:

response.sendRedirect(request.getContextPath()+"/index.jsp");

request.getContextPath()獲取到的內容就是"/JavaWeb_HttpServletResponse_Study_20140615",這樣就比較靈活了,使用request.getContextPath()代替"/項目名稱",推薦使用這種方式,靈活方便!

.使用超連接跳轉

<a href="/JavaWeb_HttpServletResponse_Study_20140615/index.jsp">跳轉到首頁</a>

這是客戶端瀏覽器使用的超連接跳轉,這個"/"是給瀏覽器使用的,此時"/"表明的就是webapps目錄。

使用超連接訪問web資源,絕對路徑的寫法推薦使用下面的寫法改進:

<a href="${pageContext.request.contextPath}/index.jsp">跳轉到首頁</a>

這樣就能夠避免在路徑中出現項目的名稱,使用${pageContext.request.contextPath}取代"/JavaWeb_HttpServletResponse_Study_20140615"

.Form表單提交

<form action="/JavaWeb_HttpServletResponse_Study_20140615/servlet/CheckServlet" method="post">    
        <input type="submit" value="提交">
</form>

這是客戶端瀏覽器將form表單提交到服務器,因此這個"/"是給瀏覽器使用的,此時"/"表明的就是webapps目錄。

對於form表單提交中action屬性絕對路徑的寫法,也推薦使用以下的方式改進:

<form action="${pageContext.request.contextPath}/servlet/CheckServlet" method="post">
         <input type="submit" value="提交">
</form>

${pageContext.request.contextPath}獲得的就是"/JavaWeb_HttpServletResponse_Study_20140615",${pageContext.request.contextPath}的效果等同於request.getContextPath(),二者獲取到的都是"/項目名稱"。

④.js腳本和css樣式文件的引用

 <%--使用絕對路徑的方式引用js腳本--%>
 <script type="text/javascript" src="${pageContext.request.contextPath}/js/index.js"></script>
 <%--${pageContext.request.contextPath}與request.getContextPath()寫法是獲得的效果是同樣的--%>
 <script type="text/javascript" src="<%=request.getContextPath()%>/js/login.js"></script>
 <%--使用絕對路徑的方式引用css樣式--%>
 <link rel="stylesheet" href="${pageContext.request.contextPath}/css/index.css" type="text/css"/>

 

歡迎搜索微信公衆號「程序員考拉」,關注更多精彩內容!

相關文章
相關標籤/搜索