day10(response、request)

1、response概述

  response是Servlet.service方法的一个参数,类型为javax.servlet.http.HttpServletResponse。在客户端发出每个请求时,服务器都会创建一个response对象,并传入给Servlet.service()方法。response对象是用来对客户端进行响应的,这说明在service()方法中使用response对象可以完成对客户端的响应工作。
response:其类型为HttpServletResponse
ServletResponse-->与协议无关的类型
HttpServletResponse-->与http协议相关的类型

response对象的功能分为以下四种:l   设置响应头信息;l   发送状态码;l  设置响应正文;l  重定向;
1.1 设置响应头信息 Content-Type、Refresh、Location等等。
可以使用response对象的setHeader()方法来设置响应头!使用该方法设置的响应头最终会发送给客户端浏览器!
头就是一个键值对!可能会存在一个头(一个名称,一个值),也可能会存在一个头(一个名称,多个值!)
  > setHeader(String name, String value):适用于单值的响应头,例如:response.setHeader("aaa", "AAA");
  > addHeader(String name, String value):适用于多值的响应头
    response.addHeader("aaa", "A");
    response.addHeader("aaa", "AA");
    response.addHeader("aaa", "AAA");
  > setIntHeader(String name, int value):适用于单值的int类型的响应头
    response.setIntHeader("Content-Length", 888);
  > addIntHeader(String name, int value):适用于多值的int类型的响应头
  > setDateHeader(String name, long value):适用于单值的毫秒类型的响应头(通常给值设置成-1,不让浏览器缓存)
    response.setDateHeader("expires", 1000 * 60 * 60 * 24);
  > addDateHeader(String name, long value):适用于多值的毫秒类型的响应头

1.2 发送状态码

http协议!http协议中响应的内容包含哪些东西呢?
* 状态码:200表示成功、302表示重定向、404表示客户端错(访问的资源不存在)、500表示服务器端错
 > sendError(int sc) --> 发送错误状态码,例如404、500
 > sendError(int sc, String msg) --> 也是发送错误状态码,还可以带一个错误信息!
 > setStatus(int sc) --> 发送成功的状态码,可以用来发送302
案例 发送404 


1.3 设置响应正文

  response是响应对象,向客户端输出响应正文(响应体)可以使用response的响应流,repsonse一共提供了两个响应流对象:

l   PrintWriter out = response.getWriter():获取字符流;

l   ServletOutputStream out = response.getOutputStream():获取字节流;

 如果响应正文内容为字符,那么使用response.getWriter(),如果响应内容是字节,例如下载时,那么可以使用response.getOutputStream()。

注意,在一个请求中,不能同时使用这两个流!也就是说,要么你使用repsonse.getWriter(),要么使用response.getOutputStream(),但不能同时使用这两个流。不然会抛出IllegalStateException异常。

1.4 重定向(重定向是服务器通知浏览器去访问另一个地址,即再发出另一个请求。)

扫描二维码关注公众号,回复: 2414348 查看本文章

  当你访问http://www.sun.com时,你会发现浏览器地址栏中的URL会变成http://www.oracle.com/us/sun/index.htm,这就是重定向了。

重定向[图解]

案例 > 发送302,设置Location响应头,完成重定向!
BServlet.java

CServlet.java

效果图:

案例> 定时刷新(定时重定向):设置Refresh头

案例 禁用浏览器缓存:Cache-Control、pragma、expires

<meta>标签可以代替响应头 = > index.jsp文件里

响应体:通常是html、也可以是图片!
 > response的两个流:
  <> ServletOutputStream,用来向客户端发送字节数据。ServletOutputStream out = resopnse.getOutputStream();
  <> PrintWriter,用来向客户端发送字符数据!需要设置编码。PrintWriter writer = response.getWriter();
  <> 两个流不能同时使用!

案例  使用PrintWriter发送字符数据:response.getWriter().print("hello response");

案例  使用ServletOutputStream发送字节数据(图片)用到工具类:commons-io-1.4.jar

便携重定向:设置302,设置Location!其中变化的只有Location,所以java提供了一个快捷方法,完成重定向!
 > sendRedirect(String location)方法
  如果要重定向的URL是在同一个服务器内,那么可以使用相对路径

重定向小结

a. 重定向是两次请求;

b. 重定向的URL可以是其他应用,不局限于当前应用;

c. 重定向的响应头为302,并且必须要有Location响应头;

d. 重定向就不要再使用response.getWriter()或response.getOutputStream()输出数据,不然可能会出现异常。
2、request概述(封装了客户端所有的请求数据)
 
 request是Servlet.service()方法的一个参数,类型为javax.servlet.http.HttpServletRequest。在客户端发出每个请求时,服务器都会创建一个request对象,并把请求数据封装到request中,然后在调用Servlet.service()方法时传递给service()方法,这说明在service()方法中可以通过request对象来获取请求数据。

请求行
请求头
空行
请求体(GET没体)
请求协议中的数据都可以通过request对象来获取!

2.1 request的功能可以分为以下几种:

a. 封装了请求头数据;

b. 封装了请求正文数据,如果是GET请求,那么就没有正文;

c. request是一个域对象,可以把它当成Map来添加获取数据;

d. request提供了请求转发和请求包含功能。

2.2 request(HTTP)获取请求头数据
>String getHeader(String name),适用于单值头( *****)
> int getIntHeader(String name),适用于单值int类型的请求头
> long getDateHeader(String name),适用于单值毫秒类型的请求头
> Enumeration<String> getHeaders(String name),适用于多值请求头
2.3 request获取请求相关的其它方法

http://localhost:8080/day10_2/AServlet?username=xxx&password=yyy
> String getScheme():返回请求协议,http
> String getServerName():返回主机名,localhost
> String getServerPort():返回服务器端口号,8080
>String getContextPath():返回上下文路径(获取项目名),/day10_2
> String getServletPath():返回Servlet路径,/AServlet
> String getQueryString():返回请求URL中的参数。username=xxx&password=yyy
> String getRequestURI():返回请求URI路径,等于项目名+Servlet路径。/day10_2/AServlet
> String getRequestURL():返回请求URL路径,除了参数以外的路径信息。http://localhost:8080/day10_2/AServlet
e-code

e-image图解部分

2.4 最为常见的客户端传递参数方式有两种

l   浏览器地址栏直接输入:一定是GET请求;

l   超链接:一定是GET请求;

l   表单:可以是GET,也可以是POST,取决与<form>的method属性值;

2.5 GET请求和POST请求的区别:

l   GET请求:

  • 请求参数会在浏览器的地址栏中显示,所以不安全;
  • 请求参数长度限制长度在1K之内;
  • GET请求没有请求体,无法通过request.setCharacterEncoding()来设置参数的编码;

l   POST请求:

  • 请求参数不会显示浏览器的地址栏,相对安全;
  • 请求参数长度没有限制;

2.6 获取常用信息
>获取客户端IP:request.getRemoteAddr()
>请求方式,request.getMethod(),可能是POST也可能是GET
通过User-Agent识别用户浏览器类型
e-code

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

2.7 request获取请求参数
请求参数是由客户端发送给服务器的!有可能是在请求体中(POST),也可能是在URL之后(GET)请求参数:有一个参数一个值的,还有一个参数多个值!

>String getParameter(String name):获取指定名称的请求参数值,适用于单值请求参数
> String[] getParameterValues(String name):获取指定名称的请求参数值,当多个参数名称相同时,可以使用方法来获取
> Enumeration<String> getParameterNames():获取所有请求参数名称
> Map<String,String[]> getParameterMap():获取所有参数封装到Map中,其中key为参数名,value为参数值,因为一个参数名称可能有多个值,所以参数值是String[],而不是String
案例:超链接参 表单数据
e-code

e-image

 e-code&&e-image

  e-code&&e-image

2.8 请求转发和请求包含

  无论是请求转发还是请求包含,都表示由多个Servlet共同来处理一个请求。例如Servlet1来处理请求,然后Servlet1又转发给Servlet2来继续处理这个请求。

  RequestDispatcher rd = request.getRequestDispatcher("/MyServlet"); 使用request获取RequestDispatcher对象,方法的参数是被转发或包含的Servlet的Servlet路径。有时一个请求需要多个Servlet协作才能完成,所以需要在一个Servlet跳到另一个Servlet!
> 一个请求跨多个Servlet,需要使用转发和包含。
> 请求转发:由下一个Servlet完成响应体!当前Servlet可以设置响应头!
> 请求包含:由两个Servlet共同未完成响应体!
> 无论是请求转发还是请求包含,都在一个请求范围内!使用同一个request和response!

请求转发:rd.forward(request,response);
请求包含:rd.include(request,response);

* 请求转发与请求包含比较

l   如果在AServlet中请求转发到BServlet,那么在AServlet中就不允许再输出响应体,即不能再使用response.getWriter()和response.getOutputStream()向客户端输出,这一工作应该由BServlet来完成;如果是使用请求包含,那么没有这个限制;

l   请求转发虽然不能输出响应体,但还是可以设置响应头的,例如:response.setContentType(”text/html;charset=utf-8”);

l   请求包含大多是应用在JSP页面中,完成多页面的合并;

l   请求请求大多是应用在Servlet中,转发目标大多是JSP页面;

* 请求转发和重定向的区别
> 请求转发是一个请求一次响应,而重定向是两次请求两次响应
> 请求转发地址栏不变化,而重定向会显示后一个请求的地址
> 请求转发只能转发到本项目其他Servlet,而重定向不只能重定向到本项目的其他Servlet,还能定向到其他项目
> 请求转发是服务器端行为,只需给出转发的Servlet路径,而重定向需要给出requestURI,即包含项目名!
> 请求转发和重定向效率是转发高!因为是一个请求!
  <> 需要地址栏发生变化,那么必须使用重定向!
  <> 需要在下一个Servlet中获取request域中的数据,必须要使用转发!
>请求转发对AServlet和BServlet的请求方法是相同的,即要么都是GET,要么都是POST,因为请求转发是一个请求;
> 重定向的第二个请求一定是GET;

案例 请求转发(留头不留体)

案例 请求包含(留头即留体)

2.9 request域

  request是域对象!在JavaWeb中一共四个域对象,其中ServletContext就是域对象,它在整个应用中只创建一个ServletContext对象。request其中一个,request可以在一个请求中共享数据。一个请求会创建一个request对象,如果在一个请求中经历了多个Servlet,那么多个Servlet就可以使用request来共享数据。

Servlet中三大域对象:request、session、application,request的域方法:

>void setAttribute(String name, Object value):用来存储一个对象,也可以称之为存储一个域属性,例如:servletContext.setAttribute(“xxx”, “XXX”),在request中保存了一个域属性,域属性名称为xxx,域属性的值为XXX。请注意,如果多次调用该方法,并且使用相同的name,那么会覆盖上一次的值,这一特性与Map相同;

>Object getAttribute(String name):用来获取request中的数据,当前在获取之前需要先去存储才行,例如:String value = (String)request.getAttribute(“xxx”);,获取名为xxx的域属性;

>void removeAttribute(String name):用来移除request中的域属性,如果参数name指定的域属性不存在,那么本方法什么都不做;

>Enumeration getAttributeNames():获取所有域属性的名称;
 同一请求范围内使用request.setAttribute()、request.getAttribute()来传值!前一个Servlet调用setAttribute()保存值,后一个Servlet调用getAttribute()获取值。
3、编码

常见字符编码:iso-8859-1(不支持中文)、gb2312、gbk、gb18030(系统默认编码,中国的国标码)、utf-8(万国码,支持全世界的编码)
3.1 响应编码

3.2 请求编码

3.3 URL编码

猜你喜欢

转载自www.cnblogs.com/cao-yin/p/9364215.html
今日推荐