Java第三階段學習(十二、HttpServletRequest與HttpServletResponse)


一、HttpServletRequest

1、概述:

我們在創建Servlet時會覆蓋service()方法doGet()/doPost(),這些方法都有兩個參數,一個為代表請求的request代表的響應response

service方法中request的類型是ServletRequest,而doGet/doPost方法request的類型是HttpServletRequest,HttpServletRequest是ServletRequest的子接口,功能和方法更加強大,今天我們學習HttpServletRequest。

2、request的運行流程

 

3、通過抓包工具抓取Http請求

因為request代表請求,所以我們可以通過該對象分別獲得Http請求的請求行,請求頭和請求體

4、通過request獲得請求行

獲得客戶端的請求方式:String getMethod()

獲得請求的資源:

String getRequestURI()  獲得請求地址

StringBuffer getRequestURL()       獲得網絡地址

String getContextPath() ---獲得web應用的名稱

String getQueryString() ----只能獲得 get方式提交url地址后的參數字符串 如:username=zhangsan&password=123

注意:request獲得客戶機(客戶端)的一些信息

request.getRemoteAddr() --- 獲得訪問的客戶端IP地址

5、通過request獲得請求頭

long getDateHeader(String name)

String getHeader(String name)

Enumeration getHeaderNames()

Enumeration getHeaders(String name)

int getIntHeader(String name)

referer頭的作用:執行該此訪問的的來源,做防盜鏈 (referer的內容為訪問的網絡地址)

 

package com.oracle.demo01;

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 RefererServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //獲取referer請求頭
        String referer=request.getHeader("referer");
        //對該訪問的來源進行判斷
            //如果判斷成功,代表我自己的域名,就可以訪問
        if(referer!=null&&referer.startsWith("http://localhost:8080")){
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().write("習大大擘畫新時代黨的組織路線圖");
        }else{
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().write("你是盜鏈者,丟不丟人");
        }
    }
    

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

 

Jsp代碼:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <a href="/WEB04/RefererServlet">習大大說新時代</a>
    <form action="/WEB04/LoginServlet" method="get">
        用戶名:<input type="text" name="username"><br>
        密碼:<input type="password" name="pwd"><br>
        <input type="submit" value="登陸"><br>
        <input type="reset" value="重置">
    </form>
</body>
</html>

 

代碼演示:

package com.oracle.demo01;

import java.io.IOException;
import java.util.Enumeration;

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

public class LoginServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//獲取請求行里信息的方法    
        //獲取請求方式
        String method=request.getMethod();
        System.out.println(method);
        //獲取請求資源的相關內容
        String requestURI=request.getRequestURI();
        StringBuffer requestURL=request.getRequestURL();
        System.out.println("requestURI:"+requestURI);
        System.out.println("requestURL:"+requestURL);
        //獲取WEB應用的名稱
        String name=request.getContextPath();
        System.out.println(name);
        //獲取get方式提交后url地址后的字符串
        String queryString=request.getQueryString();
        System.out.println(queryString);
        //獲取客戶機的信息----獲取訪問者的IP地址
        String ip=request.getRemoteAddr();
        System.out.println(ip);
//獲取請求頭中的內容
        //獲取指定頭
        String header=request.getHeader("User-Agent");
        System.out.println(header);
        //獲得所有頭的名稱
        Enumeration<String> en=request.getHeaderNames();   //以鍵值對的形式獲得,並保存在集合中
        while(en.hasMoreElements()){   //遍歷,獲得鍵和值
            String headerName=en.nextElement();
            String headerValue=request.getHeader(headerName);
            System.out.println(headerName+":"+headerValue);
        }
    }

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

6、通過request獲取請求體

String getParameter(String name)

String[] getParameterValues(String name)

Enumeration getParameterNames()

Map<String,String[]> getParameterMap()

      注意:get請求方式的請求參數 上述的方法一樣可以獲得

      解決post提交方式的亂碼:request.setCharacterEncoding("UTF-8");

      解決get提交的方式的亂碼: parameter = new String(parameter.getbytes("iso8859-1"),"utf-8");

7、request的其他功能

(1)request是一個域對象

request對象也是一個存儲數據的區域對象,所以也具有如下方法:

setAttribute(String name, Object o)

getAttribute(String name)

removeAttribute(String name)

注意:request域的作用范圍:一次請求中

(2)request完成請求轉發

獲得請求轉發器----path是轉發的地址

RequestDispatcher getRequestDispatcher(String path)

通過轉發器對象轉發

requestDispathcer.forward(ServletRequest request, ServletResponse response)

注意:ServletContext域與Request域的生命周期比較?

    ServletContext

      創建:服務器啟動

      銷毀:服務器關閉

      域的作用范圍:整個web應用

    request

      創建:訪問時創建request

      銷毀:響應結束request銷毀

      域的作用范圍:一次請求中

注意:轉發與重定向的區別?

      1)重定向兩次請求,轉發一次請求

      2)重定向地址欄的地址變化,轉發地址不變

      3)重新定向可以訪問外部網站 轉發只能訪問內部資源

      4)轉發的性能要優於重定向 

代碼演示:  

 

package com.oracle.demo02;

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 Servlet01 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //向request域中存值
        request.setAttribute("name", "wang");
        //請求轉發
        //獲得轉發器對象,並調用轉發方法
        request.getRequestDispatcher("/Servlet02").forward(request, response);
        
    }

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

 

 

 

總結:

request獲得行的內容

       request.getMethod()

       request.getRequestURI()

       request.getRequestURL()

       request.getContextPath()

       request.getRemoteAddr()

request獲得頭的內容

       request.getHeader(name)

request獲得體(請求參數)

       String request.getParameter(name)

       Map<String,String[]> request.getParameterMap();

       String[] request.getParameterValues(name);

       注意:客戶端發送的參數 到服務器端都是字符串

獲得中文亂碼的解決:

       post:request.setCharacterEncoding(“UTF-8”);

       get:parameter = new String(parameter.getBytes(“iso8859-1”),”UTF-8”);

request轉發和域

       request.getRequestDispatcher(轉發的地址).forward(req,resp);

       request.setAttribute(name,value)

       request.getAttribute(name)

 二、HttpServletResponse

1.HttpServletResponse概述

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

service方法中的response的類型是ServletResponse,而doGet/doPost方法的response的類型是HttpServletResponse,HttpServletResponse是ServletResponse的子接口,功能和方法更加強大,今天我們學習HttpServletResponse。

2. Response運行流程

3. 通過抓包工具獲取Http響應

因為response代表響應,所以我們可以通過該對象分別設置Http響應的響應行,響應頭和響應體

4.通過response設置響應行

設置響應行的狀態碼:  setStatus(int sc)

 代碼演示:

package com.oracle.demo01;

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 Servlet01 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //設置響應行的狀態碼:response.setStatus(int類型的數值);當響應成功后的狀態碼就是你設置的
        response.setStatus(404);
        response.getWriter().write("hello dandan...");
    }

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

 

 

5.通過response設置響應頭

addHeader(String name, String value)

addIntHeader(String name, int value)

addDateHeader(String name, long date)

setHeader(String name, String value) 重定向

setDateHeader(String name, long date)

setIntHeader(String name, int value)

其中,add表示添加,而set表示設置

重定向需要:1.狀態碼:302

                     2.響應頭:location 代表重定向地址

重定向代碼演示:

package com.oracle.demo01;

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 Servlet02 extends HttpServlet {
    //重定向:
    //1.服務器訪問兩次
    //2.地址欄地址會有變化
    //當訪問第一個Servletet02的時候,第一個沒有資源,但是會返回一個響應,告知客戶端Servlet03有資源
    //客戶端就會自己跳轉到Servlet03的頁面
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//        //1.設置狀態碼
//        response.setStatus(302);
//        //2.設置響應頭Location,重定向
//        response.setHeader("Location", "/WEB03/Servlet03");
        //開發中上面的方法一般不用,會使用下面封裝好的方法
        //開發中封裝好的   專門用於重定向的方法:response.sendRedirect();
        response.sendRedirect("/WEB03/Servlet03");
    }

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

 

 

 

6.通過response設置響應體

(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");就可以解決頁面輸出中文亂碼問題。

解決中文亂碼代碼演示:

 

package com.oracle.demo01;

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 Servlet04 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //解決中文亂碼的問題
        //設置緩沖區的編碼為UTF-8
//        response.setCharacterEncoding("UTF-8");
//        //告知客戶端給我用UTF-8解碼
//        response.setHeader("Content-Type", "text/html;charset=UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().write("中國");
    }

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

 

 

 

(2)響應頭設置字節

ServletOutputStream  getOutputStream()   在瀏覽器上輸出一個文件,前提是瀏覽器可以解析,不能解析就是提供下載

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

 響應頭設置時間自動跳轉:

package com.oracle.demo01;

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 Servlet03 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //定時刷新的響應頭:定時刷新跳轉到另一個網頁
        response.setHeader("refresh", "5;url=http:///www.baidu.com");
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

 

Jsp代碼:

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
    var time=5;
    //全局函數,當全部頁面加載完成后才會執行的函數
    window.onload=function(){
        var second=document.getElementById("second");
        timer=setInterval(function(){   //定時器函數
            second.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>

練習題:

1. 文件的下載

package com.oracle.demo02;

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 DownloadServlet extends HttpServlet {
//服務器提供文件下載的方法
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.獲得下載的文件的名稱
        String filename=request.getParameter("filename");
            //解決中文亂碼的問題
        filename=new String(filename.getBytes("ISO8859-1"),"UTF-8");
            //獲取瀏覽器的請求頭User-Agent
        String agent=request.getHeader("User-Agent");
        String filenameEncoding="";
            //根據不同的瀏覽器進行編碼(模板代碼復制即可,不需要記憶)
        if (agent.contains("MSIE")) {
            // IE瀏覽器
            filenameEncoding = URLEncoder.encode(filename, "utf-8");
            filenameEncoding = filename.replace("+", " ");
        }
//        else if (agent.contains("Firefox")) {
//            // 火狐瀏覽器
//            BASE64Encoder base64Encoder = new BASE64Encoder();
//            filenameEncoding = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
//        } 
        else {
            // 其它瀏覽器
            filenameEncoding = URLEncoder.encode(filename, "utf-8");
        }
        //2.設置要下載的文件的類型----客戶端通過文件的MIME類型區分文件的類型
        response.setContentType(this.getServletContext().getMimeType(filename));
        //3.告訴你的客戶端該文件不能直接解析,而是以附件的形式打開(下載)
        response.setHeader("Content-Disposition", "attachment;filename="+filenameEncoding);
        //4.獲取文件的絕對路徑
        String path=this.getServletContext().getRealPath("download/"+filename);
        //5.創建輸入流
        InputStream in=new FileInputStream(path);
        //6.獲取輸出流--通過response獲得輸出流
        ServletOutputStream out=response.getOutputStream();
        //7.文件復制的模板代碼
        int len=0;
        byte[] bytes=new byte[1024];
        while((len=in.read(bytes))!=-1){
            out.write(bytes,0,len);   //輸出到瀏覽器上
        }
        //8.釋放資源
        in.close();
    }

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

 

Jsp代碼:

 

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
    <h1>使用a標簽直接指向服務器上的資源提供下載功能</h1>
    <a href="/WEB03/download/中國.txt">中國.txt</a>
    <a href="/WEB03/download/commons.zip">commons.zip</a>
    <a href="/WEB03/download/dameinv.jpg">dameinv.jpg</a>
    <h1>使用服務器端編碼的方式實現下載功能</h1>
    <a href="/WEB03/DownloadServlet?filename=中國.txt">中國.txt</a>
    <a href="/WEB03/DownloadServlet?filename=commons.zip">commons.zip</a>
    <a href="/WEB03/DownloadServlet?filename=dameinv.jpg">dameinv.jpg</a>
</body>
</html>

 

 

 

2. 將圖片輸出到頁面:

package com.oracle.demo02;

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 MyServlet01 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //使用response獲取字節輸出流,負責寫給客戶端的
         ServletOutputStream out=response.getOutputStream();
        //確定數據源,將圖片讀到程序中
         String realPath=this.getServletContext().getRealPath("dameinv.jpg");  //獲取圖片路徑
         InputStream in=new FileInputStream(realPath);
         int len=0;
         byte[] bytes=new byte[1024];
         while((len=in.read(bytes))!=-1){
             //將程序中的字節數組寫到客戶端
             out.write(bytes,0,len);
         }
        //釋放資源
         in.close();
    }

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

 

 

3. 注冊到數據庫:

dao層代碼:

package com.oracle.demo02;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class Dao {
    public int dao(String username,String pwd) throws SQLException{
        Connection conn=JDBCUtils.getConnection();
        String sql="insert into user (username,password) values(?,?)";
        PreparedStatement pst=conn.prepareStatement(sql);
        pst.setString(1, username);
        pst.setString(2, pwd);
        int row=pst.executeUpdate();
        JDBCUtils.close(pst, conn);
        return row;
    }
}

 

service層代碼:

package com.oracle.demo02;

import java.sql.SQLException;

public class Service {
    public String service(String username,String pwd) throws SQLException{
        Dao d=new Dao();
        int count=d.dao(username, pwd);
        String mes="";
        if(count>0){
            mes="注冊成功";
        }else{
            mes="注冊失敗";
        }
        return mes;
        
    }
}

 

servlet層代碼:

package com.oracle.demo02;

import java.io.IOException;
import java.sql.SQLException;

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

public class InsertServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        String username=request.getParameter("username");
        String pwd=request.getParameter("pwd");
        Service s=new Service();
        try {
            String mes=s.service(username, pwd);
            response.getWriter().write(mes);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }

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

 

JDButils代碼:

package com.oracle.demo02;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class JDBCUtils {
    public static Connection getConnection(){
        try{
            //注冊驅動
            Class.forName("com.mysql.jdbc.Driver");
            String username="root";
            String password="123456";
            String url="jdbc:mysql://localhost:3306/goods?characterEncoding=utf-8";
            //獲得連接
            Connection conn=DriverManager.getConnection(url,username,password);
            return conn;
        }catch(Exception ex){
            throw new RuntimeException(ex+"數據庫連接失敗");
        }
    }

    //關閉數據庫的方法
    public static void close(ResultSet rs,Statement sta,Connection conn){
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(sta!=null){
            try {
                sta.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
        public static void close(Statement sta,Connection conn){
            if(sta!=null){
                try {
                    sta.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
}

 

Jsp代碼:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
    function changeImg(obj){
        obj.src="/WEB03/CheckImgServlet?time="+new Date().getTime();
    }

</script>
</head>
<body>
    <div><%=request.getAttribute("loginInfo")==null?"":request.getAttribute("loginInfo") %></div>
    <form action="/WEB03/LoginServlet" method="post">
        驗證碼:<input type="text" name="checkcode">
        <img src="/WEB03/CheckImgServlet" onclick="changeImg(this)">    
        <input type="submit" value="登陸">
    </form>
</body>
</html>

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM