Java Servlet响应httpServletResponse过程详解

2023-01-21 0 3,449

目录

一、核心方法

1.setStatus

设置响应状态码 如果没有调用这个方法,默认返回200状态码(前提:正常执行,没有异常) 如果出现异常,返回500

前端代码:

<body>
    <h3>设置响应头</h3>
    <input type=\"text\" id=\"status\">
    <br>
    <button onclick=\"setStatus()\">提交</button>
</body>
<script>
    function setStatus(){
        //js中发送请求:(1)ajax(2)直接修改url
        let status = document.querySelector(\"#status\");
        //后端会设置文本框输入的值为响应状态码:严格来做需要验证(省略)
        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 {
        //获取请求发送的queryString数据:status=xxx
        String status = req.getParameter(\"status\");
        resp.setStatus((Integer.parseInt(status)));
        resp.getWriter().write(\"设置响应状态码成功\");
    }
}

前端显示:

Java Servlet响应httpServletResponse过程详解

提交后fiddler抓包:

Java Servlet响应httpServletResponse过程详解

2.setHeader(String name,String value)

设置响应头

响应头name键已有,会覆盖原有的键值对

前端代码:

<h3>设置响应头</h3>
<a href=\"response\" rel=\"external nofollow\" >设置</a>

后端代码:

//设置响应头的键值对,键可以是标准的http响应头的键,也可以是自定义的
//响应状态码是301,302,307,响应头有Location字段,才是重定向
resp.setHeader(\"Location\",\"http://www.baidu.com\");
resp.setHeader(\"username\",\"张三\");

fiddler抓包结果:

Java Servlet响应httpServletResponse过程详解

3.addHeader(String name,String value)

设置响应头

响应头name键已有,不会影响,添加一个新的

这两个了解即可

4.setContentType(String type)

设置响应头Content-Type的值,等同于setHeader(“Content-Type”,String type) 因为Content-Type是标识body的数据格式,所以还需要设置body的内容

1.响应一个网页

//响应html:设置响应的Content-Type
resp.setContentType(\"text/html; charset=utf-8\");

可以返回静态和动态网页

两种方式展示:

前端代码:

<body>
    <h3>返回响应正文为简单的html</h3>
    <a href=\"html?type=1\" rel=\"external nofollow\" >查看</a>

    <h3>返回响应正文为复杂的html(动态变化的)</h3>
    <input type=\"text\" id=\"username\" placeholder=\"输入姓名\">
    <br>
    <button onclick=\"toWelcome()\">跳转</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>获取网页成功</h3>\");
        }else if(\"2\".equals(type)){//返回复杂的动态html
            //html?type=2&username=xxx
            String username = req.getParameter(\"username\");
            pw.println(\"<p>\");
            pw.println(\"欢迎你,\"+username);
            pw.println(\"</p>\");
        }
    }
}

简单:

前端显示:

Java Servlet响应httpServletResponse过程详解

点击“查看”:

Java Servlet响应httpServletResponse过程详解

动态:

前端显式:

Java Servlet响应httpServletResponse过程详解

点击“跳转”:

Java Servlet响应httpServletResponse过程详解

关于动态网页:在Java的代码中,写很多html的代码

耦合性太强(两个完全不同的编程语言,放在一起来开发)、维护性、扩展性很差

解决方式:

  • 模板技术
  • 这种方式还存在一些问题,进一步发展就有了ajax技术的产生

二、响应一个网页

返回已有的一个网页

(1)重定向:

特点:url地址栏会变,发起两次请求

原理:

第一次返回301/302/307响应状态码,及响应头Location:网页的地址

第二次:浏览器自动的跳转到Location设置的地址

还是比较常用的:比如登录成功(其实也可以在js代码中跳转)后,跳转到某个首页

(2)转发:

特点:url地址栏不变,只有一次请求

原理:当次请求Servlet时,由Servlet获取到转发路径的html,把这个路径的内容设置到响应正文

前端代码:

<h3>重定向到hello.html</h3>
<a href=\"goto?type=1\" rel=\"external nofollow\" >跳转</a>
<h3>转发到hello.html</h3>
<a href=\"goto?type=2\" rel=\"external nofollow\" >跳转</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)){//转发
            req.getRequestDispatcher(\"hello.html\")
                    .forward(req,resp);
        }
    }
}

三、返回一个文件

设置一下Content-Type,然后把文件的二进制数据放在响应正文就可以

前端代码:

<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\">

        //获取响应对象的字节输出流
        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);
    }
}

问题:图片、音乐、视频是静态文件,直接放在web应用webapp下,就可以直接访问,那还需要Servlet来返回么?是否多此一举?

如果文件总的大小非常大,放在web应用的webapp下就不合适了:打包就比较费劲,使用Servlet去读取本地其他地方的文件,来返回,就比较适合

四、返回json数据

常用于ajax请求,返回一些数据,用于动态的填充网页

前端代码:

<body>
    <h3>获取ajax响应数据,动态生成网页内容</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是一个字符串
                //转换为json对象
                let array = JSON.parse(resp);
                for(json of array){//遍历
                    //每一个json对象,创建一个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();
        //设置回调函数
        xhr.onreadystatechange = function(){
            //4:客户端接收到响应后回调
            if(xhr.readyState == 4){
                // 回调函数可能需要使用响应的内容,作为传入参数
                args.callback(xhr.status,xhr.responseText);
            }
        }
        xhr.open(args.method,args.url);
        // 如果args中,Content-Type属性有内容,就设置Content-Type请求头
        if(args.contentType){//js中,除了判断boolean值,还可以判断字符串,对象等,有值就为true
            xhr.setRequestHeader(\"Content-Type\",args.contentType);
        }
        //如果args中,设置了body请求正文,调用send(body)
        if(args.body){
            xhr.send(args.body);
        }else{//如果没有设置,调用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对象,转换为一个json字符串,list和数组会转换为[],一个对象{成员变量名:值}
        String json = mapper.writeValueAsString(messages);
        //[{\"from\":\"汪汪\",\"to\":\"喵喵\",\"info\":\"我喜欢你\"},{\"from\":\"喵喵\",\"to\":\"汪汪\",\"info\":\"我喜欢你\"}]
        System.out.println(\"转换的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;
        }
    }
}

点击“试试”:

Java Servlet响应httpServletResponse过程详解

Java Servlet响应httpServletResponse过程详解

具体过程:

Java Servlet响应httpServletResponse过程详解

对应可以使用的数据格式:

Java Servlet响应httpServletResponse过程详解

:本文采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可, 转载请附上原文出处链接。
1、本站提供的源码不保证资源的完整性以及安全性,不附带任何技术服务!
2、本站提供的模板、软件工具等其他资源,均不包含技术服务,请大家谅解!
3、本站提供的资源仅供下载者参考学习,请勿用于任何商业用途,请24小时内删除!
4、如需商用,请购买正版,由于未及时购买正版发生的侵权行为,与本站无关。
5、本站部分资源存放于百度网盘或其他网盘中,请提前注册好百度网盘账号,下载安装百度网盘客户端或其他网盘客户端进行下载;
6、本站部分资源文件是经压缩后的,请下载后安装解压软件,推荐使用WinRAR和7-Zip解压软件。
7、如果本站提供的资源侵犯到了您的权益,请邮件联系: 442469558@qq.com 进行处理!

猪小侠源码-最新源码下载平台 Java教程 Java Servlet响应httpServletResponse过程详解 http://www.20zxx.cn/463333/xuexijiaocheng/javajc.html

猪小侠源码,优质资源分享网

常见问题
  • 本站所有资源版权均属于原作者所有,均只能用于参考学习,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担
查看详情
  • 最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,建议提前注册好百度网盘账号,使用百度网盘客户端下载
查看详情

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务