经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Servlet » 查看文章
Java?Servlet响应httpServletResponse过程详解
来源:jb51  时间:2022/2/28 19:35:49  对本文有异议

一、核心方法

1.setStatus

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

前端代码:

  1. <body>
  2. <h3>设置响应头</h3>
  3. <input type="text" id="status">
  4. <br>
  5. <button onclick="setStatus()">提交</button>
  6. </body>
  7. <script>
  8. function setStatus(){
  9. //js中发送请求:(1)ajax(2)直接修改url
  10. let status = document.querySelector("#status");
  11. //后端会设置文本框输入的值为响应状态码:严格来做需要验证(省略)
  12. window.location.href = "response?status="+status.value;
  13. }
  14. </script>

后端代码:

  1. @WebServlet("/response")
  2. public class ResponseStudyServlet extends HttpServlet {
  3. @Override
  4. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  5. //获取请求发送的queryString数据:status=xxx
  6. String status = req.getParameter("status");
  7. resp.setStatus((Integer.parseInt(status)));
  8. resp.getWriter().write("设置响应状态码成功");
  9. }
  10. }

前端显示:

提交后fiddler抓包:

2.setHeader(String name,String value)

设置响应头

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

前端代码:

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

后端代码:

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

fiddler抓包结果:

3.addHeader(String name,String value)

设置响应头

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

这两个了解即可

4.setContentType(String type)

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

1.响应一个网页

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

可以返回静态和动态网页

两种方式展示:

前端代码:

  1. <body>
  2. <h3>返回响应正文为简单的html</h3>
  3. <a href="html?type=1" rel="external nofollow" >查看</a>
  4.  
  5. <h3>返回响应正文为复杂的html(动态变化的)</h3>
  6. <input type="text" id="username" placeholder="输入姓名">
  7. <br>
  8. <button onclick="toWelcome()">跳转</button>
  9. </body>
  10. <script>
  11. function toWelcome(){
  12. let username = document.querySelector("#username");
  13. window.location.href = "html?type=2&username="+username.value;
  14. }
  15. </script>

后端代码:

  1. @WebServlet("/html")
  2. public class HTMLTypeServlet extends HttpServlet {
  3.  
  4. //html?type=...
  5. @Override
  6. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  7. //响应html:设置响应的Content-Type
  8. resp.setContentType("text/html; charset=utf-8");
  9.  
  10. PrintWriter pw = resp.getWriter();
  11.  
  12. //获取queryString中,type的值
  13. String type = req.getParameter("type");
  14. if("1".equals(type)){//返回简单的html
  15. pw.println("<h3>获取网页成功</h3>");
  16. }else if("2".equals(type)){//返回复杂的动态html
  17. //html?type=2&username=xxx
  18. String username = req.getParameter("username");
  19. pw.println("<p>");
  20. pw.println("欢迎你,"+username);
  21. pw.println("</p>");
  22. }
  23. }
  24. }

简单:

前端显示:

点击“查看”:

动态:

前端显式:

点击“跳转”:

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

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

解决方式:

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

二、响应一个网页

返回已有的一个网页

(1)重定向:

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

原理:

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

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

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

(2)转发:

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

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

前端代码:

  1. <h3>重定向到hello.html</h3>
  2. <a href="goto?type=1" rel="external nofollow" >跳转</a>
  3. <h3>转发到hello.html</h3>
  4. <a href="goto?type=2" rel="external nofollow" >跳转</a>

后端代码:

  1. @WebServlet("/goto")
  2. public class GoToServlet extends HttpServlet {
  3. @Override
  4. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  5. //goto?type=xxx
  6. String type = req.getParameter("type");
  7. if("1".equals(type)){//重定向
  8. // resp.setStatus(301);
  9. // resp.setHeader("Location","hello.html");
  10. //以上代码可以简化为sendRedirect
  11. resp.sendRedirect("hello.html");
  12. }else if("2".equals(type)){//转发
  13. req.getRequestDispatcher("hello.html")
  14. .forward(req,resp);
  15. }
  16. }
  17. }

三、返回一个文件

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

前端代码:

  1. <h3>获取一个图片(渲染展示)</h3>
  2. <img src="file?type=photo&show=1">
  3. <h3>获取一个音乐(渲染展示)</h3>
  4. <audio src="file?type=music&show=1" controls></audio>
  5.  
  6. <h3>获取一个图片(下载)</h3>
  7. <a href="file?type=photo&show=0" rel="external nofollow" >下载</a>
  8. <h3>获取一个音乐(下载)</h3>
  9. <audio src="file?type=music&show=0" controls></audio>

后端代码:

  1. @WebServlet("/file")
  2. public class FileServlet extends HttpServlet {
  3. @Override
  4. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  5. //<img src="file?type=photo&show=1">
  6.  
  7. //获取响应对象的字节输出流
  8. OutputStream os = resp.getOutputStream();
  9. //返回的文件类型:1.图片 2.音乐
  10. String type = req.getParameter("type");
  11. //返回时的操作:1.渲染 2.下载
  12. String show = req.getParameter("show");
  13.  
  14. File file = null;
  15. byte[] data = null;
  16. //<img src="file?type=photo&show=1">
  17. if("photo".equals(type)){//返回图片
  18. if("1".equals(show)){
  19. resp.setContentType("image/jpeg");//jpg格式
  20. }else{
  21. //这样只是没有设置下载的文件名,有兴趣可以自行扩展完成
  22. resp.setContentType("application/octet-stream");
  23. }
  24.  
  25. file =new File("D:\\java\\servlet-study\\src\\main\\resources\\cui.jpg");
  26. //<audio src="file?type=music&show=1" controls></audio>
  27. }else if("music".equals(type)){//返回音乐
  28. if("1".equals(show)){
  29. resp.setContentType("audio/mp3");//mp3格式
  30. }else{
  31. resp.setContentType("application/octet-stream");
  32. }
  33. file = new File("D:\\java\\servlet-study\\src\\main\\resources\\这世界有那么多人.mp3");
  34. }//其他格式可以自行扩展完成
  35. //返回一个文件类型:Content-Length,body
  36. data = Files.readAllBytes(file.toPath());
  37. resp.setContentLength(data.length);//setHeader("Content-Length",xxx)
  38. os.write(data);
  39. }
  40. }

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

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

四、返回json数据

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

前端代码:

  1. <body>
  2. <h3>获取ajax响应数据,动态生成网页内容</h3>
  3. <button onclick="gen()">试试</button>
  4. <div id="content"></div>
  5. </body>
  6. <script>
  7. function gen(){
  8. let content = document.querySelector("#content");
  9. ajax({
  10. url: "ajax-response",
  11. method: "get",
  12. callback: function(status,resp){
  13. console.log(resp);//resp是一个字符串
  14. //转换为json对象
  15. let array = JSON.parse(resp);
  16. for(json of array){//遍历
  17. //每一个json对象,创建一个dom来保存信息
  18. let p = document.createElement("p");
  19. p.innerHTML = json.from+" 对 "+json.to+" 说:"+json.info;
  20. content.appendChild(p);
  21. }
  22. }
  23. });
  24. }
  25. function ajax(args){//var ajax = function(){}
  26. let xhr = new XMLHttpRequest();
  27. //设置回调函数
  28. xhr.onreadystatechange = function(){
  29. //4:客户端接收到响应后回调
  30. if(xhr.readyState == 4){
  31. // 回调函数可能需要使用响应的内容,作为传入参数
  32. args.callback(xhr.status,xhr.responseText);
  33. }
  34. }
  35. xhr.open(args.method,args.url);
  36. // 如果args中,Content-Type属性有内容,就设置Content-Type请求头
  37. if(args.contentType){//js中,除了判断boolean值,还可以判断字符串,对象等,有值就为true
  38. xhr.setRequestHeader("Content-Type",args.contentType);
  39. }
  40. //如果args中,设置了body请求正文,调用send(body)
  41. if(args.body){
  42. xhr.send(args.body);
  43. }else{//如果没有设置,调用send()
  44. xhr.send();
  45. }
  46. }
  47. </script>

后端代码:

  1. @WebServlet("/ajax-response")
  2. public class AjaxJsonServlet extends HttpServlet {
  3. @Override
  4. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  5. List<Message> messages = new ArrayList<>();
  6. Message m1 = new Message("汪汪","喵喵","我喜欢你");
  7. Message m2 = new Message("喵喵","汪汪","我喜欢你");
  8. messages.add(m1);
  9. messages.add(m2);
  10. ObjectMapper mapper = new ObjectMapper();
  11. //把Java对象,转换为一个json字符串,list和数组会转换为[],一个对象{成员变量名:值}
  12. String json = mapper.writeValueAsString(messages);
  13. //[{"from":"汪汪","to":"喵喵","info":"我喜欢你"},{"from":"喵喵","to":"汪汪","info":"我喜欢你"}]
  14. System.out.println("转换的json字符串"+json);
  15.  
  16. //设置json可以不设置Content-Length,tomcat会设置
  17. resp.setContentType("application/json; charset=utf-8");
  18. resp.getWriter().println(json);
  19. }
  20.  
  21. static class Message{
  22. private String from;//谁
  23. private String to;//对谁
  24. private String info;//说了什么
  25.  
  26. public Message(String from, String to, String info) {
  27. this.from = from;
  28. this.to = to;
  29. this.info = info;
  30. }
  31.  
  32. public String getFrom() {
  33. return from;
  34. }
  35.  
  36. public void setFrom(String from) {
  37. this.from = from;
  38. }
  39.  
  40. public String getTo() {
  41. return to;
  42. }
  43.  
  44. public void setTo(String to) {
  45. this.to = to;
  46. }
  47.  
  48. public String getInfo() {
  49. return info;
  50. }
  51.  
  52. public void setInfo(String info) {
  53. this.info = info;
  54. }
  55. }
  56. }

点击“试试”:

具体过程:

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

到此这篇关于Java 后端Servlet响应httpServletResponse详解的文章就介绍到这了,更多相关Servlet 响应httpServletResponse内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号