上一篇我们在Servlet的调用过程中讲到服务器在接收到来自浏览器的请求信息后,会调用Servlet的service()方法处理请求,而在调用service()方法之前会创建HttpServletRequest对象(用于封装HTTP请求信息)和HttpServletResponse对象(用于封装服务器的响应信息)
这一篇我们着重介绍HttpServletRequest对象和HttpServletResponse对象的方法以及一些应用
公共接口类HttpServletRequest继承自ServletRequest。客户端浏览器发出的请求被封装成为一个HttpServletRequest对象。对象包含了客户端请求信息包括请求的地址,请求的参数,提交的数据,上传的文件客户端的ip甚至客户端操作系统都包含在其内。
方法 | 说明 |
---|---|
getHeader() | 获取单个请求头域对应的value值 |
getHeaders() | 获取多个同名请求头对应的一组value值,返回的是枚举类型数据 |
getHeaderNames() | 获取所有的请求头域对应的value值 |
测试代码
public class Demo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/**
* 因为浏览器的编码是UTF-8,而Tomcat的编码则是ISO 8859-1
* 浏览器的中文提交给Tomcat后,Tomcat以SO 8859-1去解析,就导致我们拿到的中文数据是乱码,
* 通过我们设置响应头的编码格式后,乱码就解决了
*/
resp.setContentType("text/html;charset=UTF-8");
PrintWriter printWriter = resp.getWriter();
printWriter.write("------单个请求头的值------"+ "
");
String header = req.getHeader("Accept-Encoding");
printWriter.write("Accept-Encoding : "+ header + "
");
printWriter.write("-----多个同名请求头对应的值-------"+ "
");
Enumeration e = req.getHeaders("Accept-Encoding");
//遍历
while (e.hasMoreElements()){
String element = (String) e.nextElement();
printWriter.write(element + "
");
}
printWriter.write("------所有请求头的值------"+ "
");
Enumeration er = req.getHeaderNames();
//遍历
while(er.hasMoreElements()){
String element1 =(String) er.nextElement();
String value = req.getHeader(element1);
printWriter.write(element1 + " = " + value + "
");
}
}
}
方法 | 说明 |
---|---|
getRequestURL() | 返回客户端发送请求时的完整URL |
getRequestURI() | 返回客户端发送请求时的资源 |
getQueryString() | 返回请求行中的参数部分 |
getPathInfo() | 返回请求URL路径中的额外路径信息,额外路径信息是请求URL中的位于Servlet的路径之后和查询参数之前的内容,它以“/”开头。 |
getRemoteAddr() | 返回发出请求的客户机的IP地址 |
getRemoteHost() | 返回发出请求的客户机的完整主机名 |
getRemotePort() | 返回客户机所使用的网络端口号 |
getLocalAddr() | 返回WEB服务器的IP地址 |
getLocalName() | 返回WEB服务器的主机名 |
测试代码
public class Demo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter printWriter = resp.getWriter();
StringBuffer url = req.getRequestURL();
printWriter.write("请求的URL地址:"+ url + "
");
String uri = req.getRequestURI();
printWriter.write("请求的资源:"+ uri + "
");
String queryString = req.getQueryString();
printWriter.write("请求的URL地址中附带的参数:"+queryString + "
");
String pathInfo = req.getPathInfo();
printWriter.write("pathInfo:"+pathInfo + "
");
String remoteAddr = req.getRemoteAddr();
printWriter.write("客户机的IP地址:"+remoteAddr + "
");
String remoteHost = req.getRemoteHost();
printWriter.write("客户机的完整主机名:"+remoteHost + "
");
Integer remotePort= req.getRemotePort();
printWriter.write("客户机使用的网络端口号:"+remotePort + "
");
String localAddr = req.getLocalAddr();
printWriter.write("WEB服务器的IP地址:"+localAddr + "
");
String localName = req.getLocalName();
printWriter.write("WEB服务器的主机名:"+localName + "
");
}
}
输出结果
方法 | 说明 |
---|---|
getParameter() | 获取前台表单单个元素name对应的value值 |
getParameterValues () | 获取前台表单多个标签同名name对应的所有value值 |
getParameterNames() | 获取前台表单所有标签元素name的对应的所有value值 |
编写index.jsp页面,方便我们测试
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<form action="/Demo2" method="post">
<table>
<input type="hidden" name="hidden" value="my name is juzi">
<tr>
<td>用户名</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密码</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td>性别</td>
<td>
<input type="radio" name="gender" value="男">男
<input type="radio" name="gender" value="⼥">⼥
</td>
</tr>
<tr>
<td>爱好</td>
<td>
<input type="checkbox" name="hobbies" value="游泳">游泳
<input type="checkbox" name="hobbies" value="跑步">跑步
<input type="checkbox" name="hobbies" value="健身">健身
</td>
</tr>
<tr>
<td>城市</td>
<td>
<select name="address">
<option value="广州">广州</option>
<option value="深圳">深圳</option>
<option value="北京">北京</option>
</select>
</td>
</tr>
<tr>
<td>说明:</td>
<td>
<textarea cols="30" rows="2" name="textarea"></textarea>
</td>
</tr>
<tr>
<td><input type="submit" value="提交"></td>
<td><input type="reset" value="重置"></td>
</tr>
</table>
</form>
</body>
</html>
配置web.xml文件
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name>Archetype Created Web Applicationdisplay-name>
<servlet>
<servlet-name>Demo2servlet-name>
<servlet-class>com.cn.request.Demo2servlet-class>
servlet>
<servlet-mapping>
<servlet-name>Demo2servlet-name>
<url-pattern>/Demo2url-pattern>
servlet-mapping>
<web-app>
测试代码
public class Demo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置request字符编码的格式
req.setCharacterEncoding("UTF-8");
System.out.println("1.获取前台表单单个元素name对应的value值");
String submitvalue = req.getParameter("username");
System.out.println(submitvalue);
System.out.println("2.获取前台表单多个标签同名name对应的所有value值");
String[] paramvalues = req.getParameterValues("hobbies");
for(String i:paramvalues){
System.out.println(i);
}
System.out.println("3.获取前台表单所有标签元素name的对应的所有value值");
Enumeration paramNames = req.getParameterNames();
while(paramNames.hasMoreElements()){
String paramName = (String)paramNames.nextElement();
String[] paramValue = req.getParameterValues(paramName);
for(String j : paramValue){
System.out.println(j);
}
}
}
}
输出结果
上部分测试代码中,我们加入了这样一行代码
//设置request字符编码的格式
req.setCharacterEncoding("UTF-8");
如果把这行代码去掉,重新测试
我们发现所有提交过来的中文都乱码了,这是为什么呢?
我们知道Tomcat服务器的编码是ISO 8859-1,而浏览器的编码是UTF-8,浏览器的中文数据提交给Tomcat,Tomcat以ISO 8859-1进行编码传给Servlet,这样就导致我们拿到的数据就是乱码,通过我们设置request的编码为UTF-8后,数据就正常了
接下来我们测试get方式提交数据
<form action="/Demo2" method="get">
省略部分代码
测试代码输出结果
中文数据显示正常,没有乱码,那意思就是无论Post请求还是Get请求,只要设置了request的编码后,数据就没有问题
结论似乎下的有点太早,我们看下Tomcat配置的是8以上的版本
我们改成稍低的版本试一下
这什么情况,又乱码了
在Tomcat8中,其对应的官方文档是这样说明的:
翻译如下: 这指定了在解码URL之后内容时所使用的编码。如果没有设置 -Dorg.apache.catalina.STRICT_SERVLET_COMPLIANCE=true,则默认使用UTF-8,否则将使用"iso8859-1"。
但是在Tomcat8之前的版本中官方文档这样说明的:
翻译如下: 这指定了在解码URL之后内容时所使用的编码。如果没有指定,将使用"iso8859-1"。
现在我们可以下结论了,Tomcat8以及之后的版本已经帮我们解决了中文乱码的问题,而Tomcat7以及之前的版本没有帮我们
我们应该怎么做呢?
可以在[tomcat]/conf/server.xml中添加一下配置就可以解决中文乱码
是指定服务器中的某一个资源(Servlet或者jsp)在处理请求的过程中,将请求转发给另一个资源,让其他资源来处理请求
能够在指定的范围内,利用自身的map实现数据共享,这个map我们可以称之为request域
测试代码
省略部分代码
//1.模拟个人信息
String name = "juzi";
String age = "18";
//2.将数据存入到request域中
req.setAttribute("name",name);
req.setAttribute("age",age);
//3.获取到requestDispatcher对象,跳转到index.jsp
RequestDispatcher dispatcher = req.getRequestDispatcher("/index.jsp");
//4.调用requestDispatcher对象的forward()实现转发,传入request和response
dispatcher.forward(req,resp);
编辑index.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
姓名:<%= request.getAttribute("name") %>
年龄:<%= request.getAttribute("age") %>
输出结果
我们发现转发的地址栏是没有发生变化的,也就是说转发相对于浏览器是透明的,请求转发只是一次Http请求,一次转发中request和response都是同一个
这也就验证了我们上面测试的request作为域对象可以进行Servlet之间的通讯
HttpServletResponse继承了ServletResponse接口,并提供了与Http协议有关的方法,这些方法的主要功能是设置HTTP状态码和管理Cookie。
方法 | 说明 |
---|---|
setStatus() | 设置响应的状态码 |
setHeader() | 使用指定名称和值设置响应头的名称和内容 |
setContentType() | 设置响应数据类型 |
getOutputStream() | 返回字节输出流对象 |
getWriter() | 返回字符输出流对象 |
//第一种
resp.getOutputStream().print();
//第二种
resp.getOutputStream().write();
测试代码
public class Demo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//使用resp.getOutputStream()向浏览器输出数据
ServletOutputStream outputStream = resp.getOutputStream();
//.print
outputStream.print("juzi")
}
}
输出结果
如果修改为中文数据
outputStream.print("桔子");
输出结果
报错原因
outputStream是输出二进制数据的,print()方法要把一个字符串改成二进制数据,Tomcat是以ISO 8859-1进行编码,而字符串对ISO 8859-1根本就不支持,所以就出现了异常
测试代码
省略部分代码。。。
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//使用resp.getOutputStream()向浏览器输出数据
ServletOutputStream outputStream = resp.getOutputStream();
//.print
outputStream.write("juzi".getBytes());
}
输出结果
如果修改为中文数据
outputStream.write("桔子".getBytes());
输出结果
原因:
字符串在封装成byte[]数组的时候默认查的是gb2312编码,而字符串又支持gb2312编码,所以数据正常显示了出来
第一种:设置响应数据类型(最方便)
resp.setContentType("text/html;charset=UTF-8");
第二种:设置消息头
resp.setHeader("Content-Type","text/html;charset=UTF-8");
是指用户浏览某个网址时,将其导向到另一个网址的技术,也就是说通知浏览器去跳转
测试代码
public class Demo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
//重定向到index.jsp页面
resp.sendRedirect("/index.jsp");
}
}
输出结果
我们发现转发的地址栏已经发生了变化
重定向是浏览器进行的页面跳转发出了两次Http请求,request对象是无效的,因为是两个不同的request域
这篇文章主要介绍了Servlet的继承类HttpServlet的request,response的常见方法、应用以及解决乱码相关的知识,希望对您有所帮助,别忘了点赞噢。
下一篇我们继续开始学习Servlet的第三部分,Cookie和Session相关的内容,来一起把头发熬秃。。。