Servlet交互
在serlvet中,需要调用另外一个资源来对浏览器的请求进行响应,两种方式实现:
调用HttpServletResponse.sendRedirect 方法实现 重定向
调用RequestDispatcher.forward 方法来实现请求分派 (转发)
1.reponse.sendRedirect("目标URL")
原理:
Servlet执行重定向的时候向客户端返回302 ,把“目标URL”作为请求头Location的值发送给客户端
客户端浏览器接收到302,会自动发送location请求头指向新的地址
web容器针对这个请求作出响应
特征:
两次请求和响应
最终请求地址会显示在地址栏中
第一次请求中的数据会在以后的请求中丢失
2.RequestDispatcher.forward(request,response)
原理:
Servlet执行请求分派,在容器内部 调用其他的servle程序,同时通过forward方法将请求和响应传递给被调用Servlet。
客户端浏览器接收到200 ,获取容器的响应
特征:
一次请求和响应
请求地址不会发生变化
响应是从其他servlet中响应的
具体如图:
两者之间的区别:
1.重定向由客户端来完成工作,请求分派服务器端来完成任务
2.重定向会丢失请求对象中的数据,分派不会
注意:
重定向和请求分派中的新路径如果以 / 开头 意义不同
重定向中, / 代表服务器根路径
http://localhost:8080
请求分派中, / 代表Web应用根路径
http://localhost:8080/WebContextRoot
- 那么重定向的路径加上“/”怎样才能和不加“/”所表示的路径一样呢?
response.sendRedirect("info.do");
//等价于
response.sendRedirect("http://localhost"+request.getContextPath()+"/info.do");
代码
重定向:
提交界面
<!--find.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>serevlet重定向</h1><hr/>
<form action="find.do" method="post">
搜索:<input type="text" name="find" />
<input type="submit" value="提交"/>
</form>
</body>
</html>
发起重定向代码:
public class FindServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String info = request.getParameter("find");
System.out.println("第一个servlet中的信息:"+info);
response.sendRedirect("info.do");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
重定向页面:
public class InfoServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String info = request.getParameter("find");
System.out.println("第二个servlet中的信息:"+info);
response.setContentType("text/html;charset=utf-8");
response.getWriter().println("第二个servlet中的信息:"+info);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
结果如图:
在这里数据丢失的原因:
因为重定向是通过目标路径来请求的,也就是我们所说的 “get”方式,而“get”方式是没有消息体的,因此重定向之后数据会丢失。
如何能让数据能够不丢失呢?
分析:“get”方式的请求数据的提交是以键值对的形式跟在URL后面的 其格式为:
http://localhost:8080/XXX/XXX/index.html?key1=value1&key2=value2......
那么我们就可以,通过对发起重定向的servlet进行如下修改:
//原来的代码
response.sendRedirect("info.do");
//修改改后
response.sendRedirect("info.do?find="+info);
请求分派:
其他代码和上面相同,发起重定向的代码改为请求分派的代码,带码如下:
public class FindServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String info = request.getParameter("find");
System.out.println("第一个servlet中的信息:"+info);
// response.sendRedirect("info.do?find="+info);
request.getRequestDispatcher("info.do").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
结果如下:
以上就是Servlet交互【重定向 与 请求分派】详解