JavaWeb学习四(HttpServletResponse和HttpServletRequest)

xiaoxiao2021-02-27  315

一.服务器处理请求流程

1.请求响应流程图

服务器每次收到请求时,都会为这个请求开辟一个新的线程服务器会把客户端的请求数据封装到request对象中 request就是请求数据的载体!(筷子)服务器还会创建response对象,这个对象与客户端连接在一起 它可以用来向客户端发送响应(手机)

二.HttpServletResponse

ServletResponse–> 与协议无关的类型HttpServletResponse –>与Http协议相关的类型

1.状态码

sendError(int sc) –>发送错误状态码,例如404 500sendError(int sc,String msg) –>发送错误状态码,还可以带一个错误信息setStatus(int sc)–> 发送成功的状态码 可以用来发送302 public class CServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.sendError(404,"成都东软校园网无法访问"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }

访问此Servlet效果如下图:

2.响应头

Content-Type Refresh Location等等

头就是一个键值对,可能会存在一个头(一个名称 一个值),也可能会存在一个头(一个名称 多个值)

setHeader(String name,String value):适用于单值的响应头

public class DServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setHeader("aaa","AA"); response.setStatus(200); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }

addHeader(String name,String value):使用于多值的响应头 public class DServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.addHeader("aaa","AAA"); response.addHeader("aaa", "AA"); response.addHeader("aaa", "A"); response.setStatus(200); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }

setIntHeader(String name,int value):适用于单值的int类型的响应头 public class DServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setIntHeader("aaa",1); response.setStatus(200); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }

addIntHeader(String name,int value):适用于多值的int类型的响应头 public class DServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.addIntHeader("aaa",1); response.addIntHeader("aaa",22); response.addIntHeader("aaa",333); response.setStatus(200); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }

setDateHeader(String name,long value):适用于单值的毫秒类型的响应头 public class DServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setDateHeader("expires",60*60*24*1000);//缓存24小时 response.setStatus(200); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }

不过注意一般在开发的时候会这么设置,缓存大多自然不好

response.setDateHeader("expires",-1);//设置过期时间为-1 addDateHeader(String name,long value):适用于多值的毫秒类型的响应头 public class DServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.addDateHeader("expires",60*60*24*1000);//缓存24小时 response.addDateHeader("expires",60*60*24*10000);//缓存240小时 response.setStatus(200); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }

3.案例

(1).发送302,设置Location头,完成重定向
public class DServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("DServlet..."); response.setHeader("Location","/javaweb2/EServlet"); response.setStatus(302); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } } public class EServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("EServlet..."); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }

访问DServlet,控制台打印出

DServlet... EServlet...

大致图解

(2).定时刷新,设置Refresh头,你可以把它理解成,定时的重定向
public class DServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter printWriter=response.getWriter(); printWriter.println("您好,5秒钟将进入重定向"); response.setHeader("Refresh","5;URL=/javaweb2/EServlet"); } } public class EServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); response.getWriter().println("你看到不是乱码!"); } }

(3).禁止浏览器缓存
public class FServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setHeader("Cache-Control","no-cache"); response.setHeader("pragma","no-cache"); response.setDateHeader("expires",-1); response.getWriter().print("hello world"); } }

注意:<meta>标签可以代替响应头

<meta http-equiv="Content-Type" content="text/html"; charset="UTF-8"> <meta http-equiv="Content-Type" content="Cache-Control"; charset="no-cache"> ...

4.响应体

响应体通常是html,也可以是图片 response的两个流

ServletOutputStream 用来向客户端发送字节数据 ServletOutputStream out=response.getOutputStream(); PrintWriter: 用来向客户端发送字符数据 需要设置编码 PrintWriter writer=response.getWriter(); public class GServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String ss="hello world"; byte[] bys=ss.getBytes(); response.getOutputStream().write(bys); String path="‪E:/F/黑黑.jpg"; FileInputStream fis=new FileInputStream(path); byte[] byss=IOUtils.toByteArray(fis);//将图片转换成字节数组 response.getOutputStream().write(byss); } }

注意两个流不能同时使用

5.直接进行重定向

public class DServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("DServlet..."); response.sendRedirect("/javaweb2/EServlet");//直接进行重定向的方法 } } public class EServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("EServlet..."); } }

控制台打印

DServlet... EServlet...

三.HttpServletRequest(封装了客户端所有的请求数据)

1.请求协议

请求行请求头空行请求体(GET提交方式是没有请求体的)

2.常用方法

(1).获取常用信息
A.获取客户端ip
request.getRemoteAddr();
B.获取请求方式
request.getMethod();//可能是POST 也可能是GET
(2).获取HTTP请求头
String getHeader(String name);//适用于单值头 int getIntHeader(Stirng name);//适用于单值int类型的请求头 long getDateHeader(String name);//适用于单值毫秒类型的请求头 Enumeration <String> getHeaders(String name);//适用于多值请求头

举例

public class AServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String addr=request.getRemoteAddr(); String method=request.getMethod(); String userAgent=request.getHeader("user-Agent"); System.out.println("addr:"+addr); System.out.println("请求方式:"+method); System.out.println("user-Agent:"+userAgent); } }

打印

addr:0:0:0:0:0:0:0:1 请求方式:GET user-Agent:Mozilla/5.0 (Windows NT 6.2; Win64; x64; Trident/7.0; rv:11.0) like Gecko

user-Agent包括了很多信息,访问资源浏览器的信息,系统信息等

(3).获取请求URL
String getScheme():获取协议 httpString getServerName():获取服务器名 localhostString getServerPort():获取服务器端口 8080String getContextPath():获取项目名String getServletPath():获取Servlet路径String getQueryString():获取参数部分 即问号后面的部分String getRequestURI():获取请求URIStringBuffer getRequestURL():获取请求URL

举例

public class BServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String http=request.getScheme(); String ServerName=request.getServerName(); int Serverport=request.getServerPort(); String ContextPath=request.getContextPath(); String ServletPath=request.getServletPath(); String QueryString=request.getQueryString(); String uri=request.getRequestURI(); StringBuffer url=request.getRequestURL(); System.out.println("协议名:"+http); System.out.println("服务器名:"+ServerName); System.out.println("服务器端口:"+Serverport); System.out.println("项目名:"+ContextPath); System.out.println("servlet的路径:"+ServletPath); System.out.println("参数:"+QueryString); System.out.println("uri:"+uri); System.out.println("url:"+url.toString()); } }

打印

协议名:http 服务器名:localhost 服务器端口:8080 项目名:/javaweb3 servlet的路径:/BServlet 参数:null //因为你是get请求所以没有参数 uri:/javaweb3/BServlet url:http://localhost:8080/javaweb3/BServlet <%@ 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> <form action="/javaweb3/BServlet" method="get"> <input type="text" name="text"><br/> <input type="submit" value="提交"> </form> </body> </html>

打印

协议名:http 服务器名:localhost 服务器端口:8080 项目名:/javaweb3 servlet的路径:/BServlet 参数:text=1444 uri:/javaweb3/BServlet url:http://localhost:8080/javaweb3/BServlet
(4).防盗链

如果请求不是通过本站的超链接发出的,发送错误状态码404,Referer,这个请求头表示请求的来源!

public class CServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String Referer=request.getHeader("Referer"); System.out.println(Referer); if(Referer==null||Referer.contains("localhost")) {//直接访问Referer值是null response.sendRedirect(request.getContextPath()+"/DServlet"); }else { response.sendError(404, "滚开"); } } }
(5).获取请求参数

请求参数是由客户端发送给服务器的 有可能是在请求体中(POST)

String getParameter(String name):获取指定名称的请求参数值,适用于单值请求参数String [] getParameterValues(String name):获取指定名称的请求参数值,适用于多值请求参数Enumeration<String> getParameterNames():获取所有请求参数名称Map<String,String[]> getParameterMap():获取所有请求参数,其中Key为参数名,value为参数值 <%@ 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> <form action="/javaweb3/EServlet"> 用户名:<input type="text" name="username"><br/> 密码:<input type="password" name="password"><br/> 性别:<input type="radio" name="sex" value="nan"><input type="radio" name="sex" value="nv"><br/> 爱好:<input type="checkbox" name="love" value="ppq">乒乓球 <input type="checkbox" name="love" value="lq">篮球 <input type="checkbox" name="love" value="ymq">羽毛球<br/> <input type="submit" value="提交"> </form> </body> </html> public class EServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username=request.getParameter("username"); String password=request.getParameter("password"); System.out.println("username:"+username); System.out.println("password:"+password); String [] loves=request.getParameterValues("love"); for(String s:loves) { System.out.println("love:"+s); } Enumeration<String> enumeration=request.getParameterNames(); while(enumeration.hasMoreElements()) { System.out.println(enumeration.nextElement()); } Map<String,String[]> map=request.getParameterMap(); for(String name:map.keySet()) { String [] values=map.get(name); System.out.println(name+":"+Arrays.toString(values)); } } }

打印

username:123 password:123 love:ppq love:lq love:ymq username password sex love username:[123] password:[123] sex:[nan] love:[ppq, lq, ymq]
(6).请求转发和请求包含

RequestDispatcher rd=request.getRequestDispatcher("/MyServlet") 使用request获取RequestDispatcher对象,方法的参数是被转发或包含的Servlet路径

A.请求转发
public class OneServlet extends HttpServlet { @Override public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("OneServlet..."); resp.setHeader("aaa","AAA");//设置响应头 resp.getWriter().print("aaaaaaa");//设置响应体 req.getRequestDispatcher("/TwoServlet").forward(req, resp); } } public class TwoServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("TwoServlet..."); response.getWriter().print("bbbbbb");//设置响应体 } }

总结

由下一个Servlet完成响应体,当前Servlet可以设置响应头(留头不留体)

如果把OneServlet改成如下

public class OneServlet extends HttpServlet { @Override public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("OneServlet..."); resp.setHeader("aaa","AAA"); for(int i=0;i<1024*24+1;i++) { resp.getWriter().print("a"); } //相当于调用了TwoServlet的service的方法 req.getRequestDispatcher("/TwoServlet").forward(req, resp); } }

为什么打印出了?不是留头不留体嘛? 看吧!控制台还是报错了的! 总结 在请求转发的时候,最好不要做过多的操作,过多的操作情况下,就好别使用转发

B.请求转发
public class OneServlets extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("OneServlets..."); response.setHeader("aaa","AAA"); response.getWriter().print("OneServlet one!!!"); request.getRequestDispatcher("/TwoServlets").include(request, response); } } public class TwoServlets extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("TwoServlets..."); response.getWriter().print("TwoServlet two!!!"); } }

总结

由两个Servlet共同未完成响应体(都留)

无论是请求转发还是请求包含,都在一个请求范围内,使用同一个request和response!

(7).request域

Servlet中三大域对象: request session application

void setAttribute(String name,Object value)object getAttribute(String name)void removeAttribute(String name)

同一请求范围内使用request.setAttribute(),request.getAttribute()来传值

(8).请求转发和重定向的区别
请求转发是一个请求一次响应,而后者是两次请求两次响应请求转发地址栏不变化,而后者显示后一个请求的地址请求转发只能转发到本项目其他Servlet,而后者不只能重定向到本项目的其他Servlet,还能定向到其他项目请求转发是服务器端行为,只需给出转发的Servlet路径,而后者需要给出requestURI ,即包含项目名请求转发和重定向效率,转发高 ,因为是一个请求需要地址栏发生变化,那么必须重定向需要在下一个Servlet中获取request域中的数据,必须要使用转发

END!!!!!!!!

转载请注明原文地址: https://www.6miu.com/read-3985.html

最新回复(0)