欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java?Servlet響應httpServletResponse過程詳解

 更新時間:2022年02月28日 17:26:30   作者:dhdhdhdhg  
HttpServletResponse是處理http響應的對象,調(diào)用該對象的方法,設置到對象屬性的內(nèi)容,tomcat最終會組織為http響應報文

一、核心方法

1.setStatus

設置響應狀態(tài)碼 如果沒有調(diào)用這個方法,默認返回200狀態(tài)碼(前提:正常執(zhí)行,沒有異常) 如果出現(xiàn)異常,返回500

前端代碼:

<body>
    <h3>設置響應頭</h3>
    <input type="text" id="status">
    <br>
    <button onclick="setStatus()">提交</button>
</body>
<script>
    function setStatus(){
        //js中發(fā)送請求:(1)ajax(2)直接修改url
        let status = document.querySelector("#status");
        //后端會設置文本框輸入的值為響應狀態(tài)碼:嚴格來做需要驗證(省略)
        window.location.href = "response?status="+status.value;
    }
</script>

后端代碼:

@WebServlet("/response")
public class ResponseStudyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //獲取請求發(fā)送的queryString數(shù)據(jù):status=xxx
        String status = req.getParameter("status");
        resp.setStatus((Integer.parseInt(status)));
        resp.getWriter().write("設置響應狀態(tài)碼成功");
    }
}

前端顯示:

提交后fiddler抓包:

2.setHeader(String name,String value)

設置響應頭

響應頭name鍵已有,會覆蓋原有的鍵值對

前端代碼:

<h3>設置響應頭</h3>
<a href="response" rel="external nofollow" >設置</a>

后端代碼:

//設置響應頭的鍵值對,鍵可以是標準的http響應頭的鍵,也可以是自定義的
//響應狀態(tài)碼是301,302,307,響應頭有Location字段,才是重定向
resp.setHeader("Location","http://www.baidu.com");
resp.setHeader("username","張三");

fiddler抓包結(jié)果:

3.addHeader(String name,String value)

設置響應頭

響應頭name鍵已有,不會影響,添加一個新的

這兩個了解即可

4.setContentType(String type)

設置響應頭Content-Type的值,等同于setHeader(“Content-Type”,String type) 因為Content-Type是標識body的數(shù)據(jù)格式,所以還需要設置body的內(nèi)容

1.響應一個網(wǎng)頁

//響應html:設置響應的Content-Type
resp.setContentType("text/html; charset=utf-8");

可以返回靜態(tài)和動態(tài)網(wǎng)頁

兩種方式展示:

前端代碼:

<body>
    <h3>返回響應正文為簡單的html</h3>
    <a href="html?type=1" rel="external nofollow" >查看</a>

    <h3>返回響應正文為復雜的html(動態(tài)變化的)</h3>
    <input type="text" id="username" placeholder="輸入姓名">
    <br>
    <button onclick="toWelcome()">跳轉(zhuǎn)</button>
</body>
<script>
    function toWelcome(){
        let username = document.querySelector("#username");
        window.location.href = "html?type=2&username="+username.value;
    }
</script>

后端代碼:

@WebServlet("/html")
public class HTMLTypeServlet extends HttpServlet {

    //html?type=...
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //響應html:設置響應的Content-Type
        resp.setContentType("text/html; charset=utf-8");

        PrintWriter pw = resp.getWriter();

        //獲取queryString中,type的值
        String type = req.getParameter("type");
        if("1".equals(type)){//返回簡單的html
            pw.println("<h3>獲取網(wǎng)頁成功</h3>");
        }else if("2".equals(type)){//返回復雜的動態(tài)html
            //html?type=2&username=xxx
            String username = req.getParameter("username");
            pw.println("<p>");
            pw.println("歡迎你,"+username);
            pw.println("</p>");
        }
    }
}

簡單:

前端顯示:

點擊“查看”:

動態(tài):

前端顯式:

點擊“跳轉(zhuǎn)”:

關(guān)于動態(tài)網(wǎng)頁:在Java的代碼中,寫很多html的代碼

耦合性太強(兩個完全不同的編程語言,放在一起來開發(fā))、維護性、擴展性很差

解決方式:

  • 模板技術(shù)
  • 這種方式還存在一些問題,進一步發(fā)展就有了ajax技術(shù)的產(chǎn)生

二、響應一個網(wǎng)頁

返回已有的一個網(wǎng)頁

(1)重定向:

特點:url地址欄會變,發(fā)起兩次請求

原理:

第一次返回301/302/307響應狀態(tài)碼,及響應頭Location:網(wǎng)頁的地址

第二次:瀏覽器自動的跳轉(zhuǎn)到Location設置的地址

還是比較常用的:比如登錄成功(其實也可以在js代碼中跳轉(zhuǎn))后,跳轉(zhuǎn)到某個首頁

(2)轉(zhuǎn)發(fā):

特點:url地址欄不變,只有一次請求

原理:當次請求Servlet時,由Servlet獲取到轉(zhuǎn)發(fā)路徑的html,把這個路徑的內(nèi)容設置到響應正文

前端代碼:

<h3>重定向到hello.html</h3>
<a href="goto?type=1" rel="external nofollow" >跳轉(zhuǎn)</a>
<h3>轉(zhuǎn)發(fā)到hello.html</h3>
<a href="goto?type=2" rel="external nofollow" >跳轉(zhuǎn)</a>

后端代碼:

@WebServlet("/goto")
public class GoToServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //goto?type=xxx
        String type = req.getParameter("type");
        if("1".equals(type)){//重定向
//            resp.setStatus(301);
//            resp.setHeader("Location","hello.html");
            //以上代碼可以簡化為sendRedirect
            resp.sendRedirect("hello.html");
        }else if("2".equals(type)){//轉(zhuǎn)發(fā)
            req.getRequestDispatcher("hello.html")
                    .forward(req,resp);
        }
    }
}

三、返回一個文件

設置一下Content-Type,然后把文件的二進制數(shù)據(jù)放在響應正文就可以

前端代碼:

<h3>獲取一個圖片(渲染展示)</h3>
<img src="file?type=photo&show=1">
<h3>獲取一個音樂(渲染展示)</h3>
<audio src="file?type=music&show=1" controls></audio>

<h3>獲取一個圖片(下載)</h3>
<a href="file?type=photo&show=0" rel="external nofollow" >下載</a>
<h3>獲取一個音樂(下載)</h3>
<audio src="file?type=music&show=0" controls></audio>

后端代碼:

@WebServlet("/file")
public class FileServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //<img src="file?type=photo&show=1">

        //獲取響應對象的字節(jié)輸出流
        OutputStream os = resp.getOutputStream();
        //返回的文件類型:1.圖片 2.音樂
        String type = req.getParameter("type");
        //返回時的操作:1.渲染 2.下載
        String show = req.getParameter("show");

        File file = null;
        byte[] data = null;
        //<img src="file?type=photo&show=1">
        if("photo".equals(type)){//返回圖片
            if("1".equals(show)){
                resp.setContentType("image/jpeg");//jpg格式
            }else{
                //這樣只是沒有設置下載的文件名,有興趣可以自行擴展完成
                resp.setContentType("application/octet-stream");
            }

            file =new File("D:\\java\\servlet-study\\src\\main\\resources\\cui.jpg");
            //<audio src="file?type=music&show=1" controls></audio>
        }else if("music".equals(type)){//返回音樂
            if("1".equals(show)){
                resp.setContentType("audio/mp3");//mp3格式
            }else{
                resp.setContentType("application/octet-stream");
            }
            file = new File("D:\\java\\servlet-study\\src\\main\\resources\\這世界有那么多人.mp3");
        }//其他格式可以自行擴展完成
        //返回一個文件類型:Content-Length,body
        data = Files.readAllBytes(file.toPath());
        resp.setContentLength(data.length);//setHeader("Content-Length",xxx)
        os.write(data);
    }
}

問題:圖片、音樂、視頻是靜態(tài)文件,直接放在web應用webapp下,就可以直接訪問,那還需要Servlet來返回么?是否多此一舉?

如果文件總的大小非常大,放在web應用的webapp下就不合適了:打包就比較費勁,使用Servlet去讀取本地其他地方的文件,來返回,就比較適合

四、返回json數(shù)據(jù)

常用于ajax請求,返回一些數(shù)據(jù),用于動態(tài)的填充網(wǎng)頁

前端代碼:

<body>
    <h3>獲取ajax響應數(shù)據(jù),動態(tài)生成網(wǎng)頁內(nèi)容</h3>
    <button onclick="gen()">試試</button>
    <div id="content"></div>
</body>
<script>
    function gen(){
        let content = document.querySelector("#content");
        ajax({
            url: "ajax-response",
            method: "get",
            callback: function(status,resp){
                console.log(resp);//resp是一個字符串
                //轉(zhuǎn)換為json對象
                let array = JSON.parse(resp);
                for(json of array){//遍歷
                    //每一個json對象,創(chuàng)建一個dom來保存信息
                    let p = document.createElement("p");
                    p.innerHTML = json.from+" 對 "+json.to+" 說:"+json.info;
                    content.appendChild(p);
                }
            }
        });
    }
    function ajax(args){//var ajax = function(){}
        let xhr = new XMLHttpRequest();
        //設置回調(diào)函數(shù)
        xhr.onreadystatechange = function(){
            //4:客戶端接收到響應后回調(diào)
            if(xhr.readyState == 4){
                // 回調(diào)函數(shù)可能需要使用響應的內(nèi)容,作為傳入?yún)?shù)
                args.callback(xhr.status,xhr.responseText);
            }
        }
        xhr.open(args.method,args.url);
        // 如果args中,Content-Type屬性有內(nèi)容,就設置Content-Type請求頭
        if(args.contentType){//js中,除了判斷boolean值,還可以判斷字符串,對象等,有值就為true
            xhr.setRequestHeader("Content-Type",args.contentType);
        }
        //如果args中,設置了body請求正文,調(diào)用send(body)
        if(args.body){
            xhr.send(args.body);
        }else{//如果沒有設置,調(diào)用send()
            xhr.send();
        }
    }
</script>

后端代碼:

@WebServlet("/ajax-response")
public class AjaxJsonServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        List<Message> messages = new ArrayList<>();
        Message m1 = new Message("汪汪","喵喵","我喜歡你");
        Message m2 = new Message("喵喵","汪汪","我喜歡你");
        messages.add(m1);
        messages.add(m2);
        ObjectMapper mapper = new ObjectMapper();
        //把Java對象,轉(zhuǎn)換為一個json字符串,list和數(shù)組會轉(zhuǎn)換為[],一個對象{成員變量名:值}
        String json = mapper.writeValueAsString(messages);
        //[{"from":"汪汪","to":"喵喵","info":"我喜歡你"},{"from":"喵喵","to":"汪汪","info":"我喜歡你"}]
        System.out.println("轉(zhuǎn)換的json字符串"+json);

        //設置json可以不設置Content-Length,tomcat會設置
        resp.setContentType("application/json; charset=utf-8");
        resp.getWriter().println(json);
    }

    static class Message{
        private String from;//誰
        private String to;//對誰
        private String info;//說了什么

        public Message(String from, String to, String info) {
            this.from = from;
            this.to = to;
            this.info = info;
        }

        public String getFrom() {
            return from;
        }

        public void setFrom(String from) {
            this.from = from;
        }

        public String getTo() {
            return to;
        }

        public void setTo(String to) {
            this.to = to;
        }

        public String getInfo() {
            return info;
        }

        public void setInfo(String info) {
            this.info = info;
        }
    }
}

點擊“試試”:

具體過程:

對應可以使用的數(shù)據(jù)格式:

到此這篇關(guān)于Java 后端Servlet響應httpServletResponse詳解的文章就介紹到這了,更多相關(guān)Servlet 響應httpServletResponse內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論