HttpServletResponse和HttpServletRequest
一、HttpServletResponse
HttpServletResponse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。
查看HttpServletResponse的API文档
1、响应行 HTTP/1.1 200 OK
setStatus(int sc) 设置响应状态码
例如:请求重定向,设置状态码值302
2、响应头
***** sendRedirect(String location) 请求重定向
setHeader(String name, String value) 设置响应头信息
//告知浏览器使用什么码表
response.setHeader(“content-type”, “text/html;charset=UTF-8”);
//告知客户端不缓存
response.setHeader(“pragma”, “no-cache”);
response.setHeader(“cache-control”, “no-cache”);
response.setDateHeader(“expires”, 0);
Referesh刷新
3、响应正文(主体)
*** getWrite(); 字符输出流
getOutputStream(); 字节输出流
setCharacterEncoding(String charset) 告知服务器使用什么编码
*****setContentType(String type)
4、response常见应用
向客户端输出中文数据
用OutputStream(字节流)发送数据:
1、response.getOutputStream().write(“中国”.getBytes());//以默认编码发送数据
2、response.getOutputStream().write(“中国”.getBytes(“UTF-8”));//以UTF-8编码发送数据,浏览器(默认用GB2312)会出现乱码
画图描述出现该问题的原因。
解决办法:
2.1通过更改浏览器的编码方式:IE/”查看”/”编码”/”UTF-8”(不可取)
2.2通过设置响应头告知客户端编码方式:response.setHeader(“Content-type”, “text/html;charset=UTF-8”);//告知浏览器数据类型及编码
2.3通过meta标签模拟请求头:out.write("".getBytes());
2.4通过以下方法:response.setContentType(“text/html;charset=UTF-8”);
总结:程序以什么编码输出,就需要告知客户端以什么编码显示。
小细节:输出字符“1”用response.getOutputStream().write(1);出现的问题?
向客户端输出中文数据
用PrintWriter(字符流)发送数据:
示例:response.getWriter().write(“中国” );有没有乱码?
原因:以默认编码发送数据 ISO-8859-1(没有中国二字编码),此时会发生乱码
解决办法:
setCharacterEncoding(“UTF-8”);//更改编码为UTF-8
response.setHead(“Context-type”,”text/html;charset=UTF-8”);//告诉客户端编码方式
注意:不要忘记告诉客户端的编码方式。
由于经常改动编码,response提供了一种更简单的方式
response. setContentType(“text/html;charset=UTF-8”);其作用相当于以上两条代码。
验证码
定义:输出随机图片(CAPTCHA图像):Completely Automated Public Turing Test to Tell Computers and Humans Apart (全自动区分计算机和人类的测试)
相关主要类(JDK 查看API)(手动写)
–BufferedImage:内存图像
–Graphics:画笔
–ImageIO:输出图像
–放在html页面上
使用工具类生成验证码
导入依赖
ValidateCode.jar
•注意:浏览器默认会缓存图片
•控制客户端不要缓存:
•response.addHeader(“Pragma”, “no-cache”);
•response.setHeader(“Cache-Control”, “no-cache”);
•response.setHeader(“Expires”, “0”);
刷新功能
•发送http头,控制浏览器定时刷新网页
•1、输出一个随机数,控制浏览器每2S刷新一次
•2、利用Refresh刷新到其他组件。模拟注册页面,注册处理交由一个Servlet,在Servlet处理完成后,显示注册成功并转向主页。
通过response实现请求重定向。
–定义:请求重定向指,一个web资源收到客户端请求后,通知客户端去访问另外一个web资源,这称之为请求重定向。
–地址栏会变,并发送2次请求,增加服务器负担
–实现方式
–response.sendRedirect()
–实现原理:
–302/307状态码和location头即可实现重定向
response细节
1、getOutputStream和getWriter方法分别用于得到输出二进制数据、输出文本数据的ServletOuputStream、Printwriter对象。
2、getOutputStream和getWriter这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。 会抛异常。
3、Servlet程序向ServletOutputStream或PrintWriter对象中写入的数据将被Servlet引擎从response里面获取,Servlet引擎将这些数据当作响应消息的正文,然后再与响应状态行和各响应头组合后输出到客户端。
4、Serlvet的service方法结束后,Servlet引擎将检查getWriter或getOutputStream方法返回的输出流对象是否已经调用过close方法,如果没有,Servlet引擎将调用close方法关闭该输出流对象。
二、HttpServletRequest
HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息。
查看request的API文档
1、请求行
Get http://localhost:8080/day09/servlet/req1?username=zs http/1.1
getMethod(); 获得请求方式
***getRequestURL();返回客户端发出请求时的完整URL。
***getRequestURI(); 返回请求行中的资源名部分。
*****getContextPath(); 当前应用的虚拟目录 /day09_01_request
getQueryString() ; 返回请求行中的参数部分。
2、请求消息头
- String getHeader(String name) 根据头名称得到头信息值
Enumeration getHeaderNames() 得到所有头信息name
Enumeration getHeaders(String name) 根据头名称得到相同名称头信息值
3、请求正文(重要)
与获取表单数据相关的方法
*** getParameter(name) 根据表单中name属性的名,获取value属性的值方法
*** getParameterValues(String name)专业为复选框取取提供的方法
getParameterNames() 得到表单提交的所有name的方法
*** getParameterMap 到表单提交的所有值的方法 //做框架用,非常实用
getInputStream 以字节流的方式得到所有表单数据
与操作非表单数据相关的方法(request也是一个域对象 Servletcontext)
*** void setAttribute(String name, Object value);
*** Object getAttribute(String name);
Void removeAttribute(String name);
与请求转发相关的方法
//得到请求转发或请求包含的协助对象
RequestDispatcher getRequestDispatcher(String path)
*** forward(ServletRequest request, ServletResponse response) //转发的方法
include(ServletRequest request, ServletResponse response) //请求包含
与请求编码相关的方法:
//解决post方式编码
*****request.setCharacterEncoding(“UTF-8”); //告诉服务器客户端什么编码,只能处理post请求方式
//解决get方式编码
String name = new String(name.getBytes(“iso-8859-1”),”UTF-8”);
(服务器的编码方式:Tomcat设置中)
4、request常用方法
获得客户机信息
getRequestURL方法返回客户端发出请求时的完整URL。
getRequestURI方法返回请求行中的资源名部分。
getQueryString 方法返回请求行中的参数部分。
getRemoteAddr方法返回发出请求的客户机的IP地址
getRemoteHost方法返回发出请求的客户机的完整主机名
getRemotePort方法返回客户机所使用的网络端口号
getLocalAddr方法返回WEB服务器的IP地址。
getLocalName方法返回WEB服务器的主机名
getMethod得到客户机请求方式
获得客户机请求头
–getHead(name)方法
–getHeaders(String name)方法
–getHeaderNames方法
获得客户机请求参数(客户端提交的数据)
–getParameter(name)方法
–getParameterValues(String name)方法
–getParameterNames方法
–getParameterMap方法 //做框架用,非常实用
5、request常见应用
各种表单输入项数据的获取
text、password、radio、checkbox、file、select、textarea、 hidden、image、button给js编程用
请求参数的中文乱码问题
浏览器是什么编码就以什么编码传送数据
解决:request.setCharacterEncoding(“UTF-8”);//POST有效
new String(username.getBytes(“ISO-8859-1”),“UTF-8”);//GET方式
超链接:<a href=“/JavaWeb/RequestDemo2?name=中国”>cn//GET方式
更改Tomcat的配置解决URL编码问题:
请求转发
1、request对象实现请求转发:请求转发指一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理。
2、request对象提供了一个getRequestDispatcher方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward方法可以实现请求转发。
3、request对象同时也是一个域对象,开发人员通过request对象在实现转发时,把数据通过request对象带给其它web资源处理。
setAttribute方法
getAttribute方法
removeAttribute方法
getAttributeNames方法
转发和包含
一个Servlet对象无法获得另一个Servelt对象的引用;如果需要多个Servet组件共同协作(数据传递),只能使用Servelt规范为我们提供的两种方式:
1、请求转发:Servlet(源组件)先对客户请求做一些预处理操作,然后把请求转发给其他web组件(目标组件)来完成包括生成响应结果在内的后续操作。
2、包含:Servelt(源组件)把其他web组件(目标组件)生成的响应结果包含到自身的响应结果中。
3、转发和请求的共同点
源组件和目标组件处理的都是同一个客户请求,源组件和目标组件共享同一个ServeltRequest和ServletResponse对象
目标组件都可以为Servlet、JSP或HTML文档
都依赖 javax.servlet.RequestDispatcher接口
RequestDispather
表示请求分发器,它有两个方法:
1、forward():把请求转发给目标组件
public void forward(ServletRequest request,ServletResponse response)
throws ServletException,java.io.IOException
2、include():包含目标组件的响应结果
public void include(ServletRequest request,ServletResponse response)
throws ServletException,java.io.IOException
得到RequestDispatcher对象
1、ServletContext对象的getRequestDispather(String path1)
path1必须用绝对路径,即以”/”开头,若用相对路径会抛出异常IllegalArgumentException
2、ServletRequest对象的getRequestDispatcher(String path2)
path2可以用绝对路径也可以用相对路径
重定向和内部跳转区别:
1、转发使用的是getRequestDispatcher()方法;重定向使用的是sendRedirect();
2、转发:浏览器URL地址不会发生改变;重定向:浏览器URL的地址栏改变
3、转发是服务器行为,重定向是客户端行为
4、转发是浏览器只做了一次访问,重定向是浏览器至少做了两次访问请求
5、转发2次跳转之间传输的信息不会丢失,重定向2次跳转之间传输的信息会丢失
转发和重定向之间的选择:
1、重定向的速度比转发的速度慢,因为浏览器还得发出一个新请求,如果在使用转发和重定向无所谓的时候,建议使用转发
2、因为转发只能访问当前web的应用程序,所以不同的WEB应用程序之间的访问,特别是要访问到另外一个WEB站点上的资源的情况,这个时候就只能使用重定向了。
forward()和include()的区别
forward():表示在服务器端从一个Servlet中将请求转发到另一个资源(Servlet、Jsp或Html等),本意是让第一个组件对请求做些预处理(或者什么都不做),而让另一组件处理并返回响应。
include():表示在响应中包含另一个资源(Servlet、Jsp或Html等)的响应内容,最终被包含的页面产生的任何响应都将并入原来的response对象,然后一起输出到客户端