Servlet
HttpServletRequest类
-
HttpServletRequest类有什么用
每次只要有请求进入Tomcat服务器时,Tomcat服务器就会将请求来的HTTP协议信息解析好封装到Request对象中。然后传递到service方法(或者是doGet和doPost方法)中供我们使用。我们可以通过HttpServletRequest对象获取到客户端请求的所有信息。 -
HttpServletRequest类的常用方法
- getRequestURI() :获取请求的资源路径
- getRequestURL() :获取请求的统一资源定位符(绝对路径)
- getRemoteHost() :获取客户端的ip地址
- getHeader() :获取请求头
- getParameter() :获取请求的参数
- getParameterValues() : 获取请求的参数(多个值时使用)
- getMethod() :获取请求的方式GET或者POST
- setAttribute(key,value):设置域数据
- getAttribute(key):获取域数据
API实例代码
public void RequestTestServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("请求的资源路径是:" + request.getRequestURI());
System.out.println("请求的统一资源定位符是:" + request.getRequestURL());
System.out.println("请求的方式是:" + request.getMethod());
System.out.println("客户端的ip地址是:" + request.getRemoteHost());
System.out.println("获取请求头User-Agent:" + request.getHeader("User-Agent"));
System.out.println("设置域数据参数二");
request.setAttribute("参数二" , "canshuer");
System.out.println("获取域数据参数二" + request.getAttribute("参数二"));
}
}
当需要获取请求参数(比如表单项name值)
表单设计
<body>
<form action="http://localhost:8080/07_servlet/parameterServlet" method="get">
用户名:<input type="text" name="username"><br/>
密码:<input type="password" name="password"><br/>
兴趣爱好:
<input type="checkbox" name="hobby" value="cpp">C++
<input type="checkbox" name="hobby" value="java">Java
<input type="checkbox" name="hobby" value="js">JavaScript<br/>
<input type="submit">
</form>
</body>
Java中Servlet程序代码(请求可以为get类型也可以是post类型)
public void ParameterServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest request , HttpServletResponse reponse) throws IOExecption , ServletException{
//获取请求参数
String userName = request.getParameter("username");
String password = request.getParameter("password");
String[] hobbies = request.getParameterValues("hobby");
System.out.println("用户名:" + userName);
System.out.println("密码:" + password);
System.out.println("兴趣爱好:" + Arrays.asList(hobbies));
}
}
使用get方式请求出现中文乱码时,解决方式为:
//获取请求参数
String userName = request.getParameter("username");
//先使用iso8895-1进行编码,再使用utf-8解码即可
userName = new String(userName.getBytes("iso-8895-1"),"UTF-8");
当使用post方式请求结果出现中文乱码时,解决方式如下
@Override
protected void doPost(HttpServletRequest request , HttpServletResponse response) throws IOException , ServletException{
//由于post参数信息放置在post请求体内,因此设置请求体的字符集为utf-8即可解决乱码问题
request.setCharacterEncoding("UTF-8");
//获取请求参数
String userName = request.getParameter("username");
String password = request.getParameter("password");
String[] hobbies = request.getParameterValues("hobby");
System.out.println("用户名:" + userName);
System.out.println("密码:" + password);
System.out.println("兴趣爱好:" + Arrays.asList(hobbies));
}
- 请求的转发
请求转发是指,服务器在收到请求后,从一个资源跳转到另一个资源的操作叫做请求转发。如浏览器发出请求给servlet1程序,servlet1程序完成业务逻辑后将请求发送给servlet2程序进行处理。
Servlet1程序代码
public class Servlet1 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest request , HttpServletResponse response) throws IOException , ServletException{
//1.获取请求参数,即查看该请求是否符合要求
String username = request.getParameter("userName");
System.out.println("在Servlet1程序中查看请求参数" + username);
//2.确认请求参数后,处理业务逻辑随后盖章
request.setAttribute("key1" , "Servlet1");
//3.问路,即给请求指明转发的路径。注意,请求转发需要以斜杠打头,表示地址为http://ip:port/工程路径/,映射到工程下的web目录
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/servlet2");
//4.请求转发向servlet2程序
requestDispatcher.forward(request , response);
}
}
Servlet2程序代码
public class Servlet2 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest request , HttpServletResponse response) throws IOException , ServletException{
//1.查看请求参数,确认请求资格
String username = request.getParameter("username");
System.out.println("servlet2程序确认请求参数" + username);
//2.查看servlet1程序的盖章
Object key1 = request.getAttribute("key1");
System.out.println("查看servlet1程序的盖章" + key1);
//3.处理servlet2的逻辑
System.out.println("Servlet2程序处理逻辑");
}
}
注意:请求转发的一些特点
- 请求转发时,浏览器的地址栏没有变化
- 无论转发多少次,这都是同一次请求
- 他们可以共享Request域中的数据
- 可以转发到WEB-INF目录下(正常情况下,浏览器是不能通过地址栏直接访问到WEB-INF目录下的)
- 请求转发不可以访问工程以外的资源
-
base标签的作用
base标签可以设置页面相对路径工作时参照的地址。由于请求转发时地址栏的地址不变,因此当请求转发到新的页面时,相对路径工作可能会相对于请求转发之前的地址进行,因此会出现查找不到资源的问题。在特定的(有相对页面操作的)页面使用base标签,便可以固定设置页面相对路径工作时参照的地址。
如<base href = "http://localhost:8080/a/b/c.html">
-
Web中的相对路径和绝对路径
在javaWeb中,路径分为绝对路径和相对路径两种- 相对路径是:
. :表示当前目录
…:表示上一级目录
资源名:表示当前目录/资源名 - 绝对路径
http://ip:port/工程路径/资源路径
在实际开发中,路径通常都使用绝对路径,而不是简单地使用相对路径。(绝对路径或者是base+相对路径)
- 相对路径是:
-
web中/斜杠的不同意义
在web中,/斜杠是一种绝对路径
/斜杠 如果被浏览器解析,得到的地址是http://ip:port/,如<a href="/">斜杠<a/>
/斜杠 如果被服务器解析,得到的地址是http://ip:port/工程路径,如<url-patern>/servlet1</url-pattern>
,servletContext.getRealPath("/")
,request.getRequestDispatcher("/")
等
特殊情况:response.sendRedirect("/")
,把斜杠发送给浏览器解析。得到http://ip:port/
HttpServletResponse类
-
HttpServletReponse类的作用
HttpServletResponse类的作用和HttpServletRequest类的作用类似。每当有请求进入服务器,Tomcat就会创建一个Response对象传递给Servlet程序使用。HttpServletRequest类代表请求来的信息,HttpServletResponse来代表所有响应的信息。
如果需要在Servlet程序中设置返回给客户端的信息,都可以通过HttpServletResponse对象来设置 -
两个输出流的说明
HttpServletResponse类响应信息是通过输出流来实现的。- 字节流:getOutputStream(),常用于下载(传递二进制数据)
- 字符流:getWriter(),常用语回传字符串(比较常用)
注意,两个流只能同时使用一个,否则就会报错
-
如何使用服务器向客户端(浏览器)回传数据
public class ResponseTestServlet1 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter writer = response.getWriter();
writer.write("已经收到您的请求");
}
}
- 响应乱码解决
响应时,服务器回传客户端的数据可能会出现乱码,有以下方式解决
// 方式一(不推荐):
//在Servlet程序中设置响应的字符集为UTF-8
response.setCharacterEncoding("UTF-8");
//随后通过响应头,设置浏览器也使用UTF-8字符集
response.setHeader("Content-Type","text/html;charset=UTF-8");
//方式二(推荐)
//使用setContentType方法可以同时设置服务器和客户端的字符集,还可以设置响应头
//并且此方法一定要在获取流对象直线调用才有效(和请求乱码解决方案类似)
response.setContentType("text/html;charset=UTF-8")
- 请求重定向
是指,客户端给服务器发送请求,服务器告知客户端一个新地址去访问,叫做请求重定向(之前的地址可能已经被废弃)——与请求转发类似。
在开发维护的过程中,随着时间和项目的更新,某个Response1接口可能已经被废弃,由新的Response2代替,因此服务器有义务告知客户端(1.状态响应码302——我已搬迁;2.响应头Location——告知新的地址)
//请求重定向的第一种方案
//设置响应状态码,表示重定向(已经搬迁)
response.setStatus(302);
//设置响应头,告知客户端访问新地址
response.setHeader("Location" , "http://localhost:8080/");
//请求重定向的第二种方案,推荐使用
//告知客户端直接解析地址
response.sendRedirect("http://localhost:8080/");
注意:请求重定向的特点
- 浏览器的地址栏会发生变化(请求转发不会)
- 两次请求(请求转发一次)
- 不共享Request域中的数据
- 不能访问WEB-INF下的资源
- 可以访问工程以外的资源