在Servlet表单处理的练习中,我们实现了用户登录功能。用户通过服务器验证以后,Servlet会渲染一段HTML内容返回给浏览器,提示已经登录成功。但这样做存在一些问题:
上述问题对于任意表单提交都是存在的,包括文章创建表单。
上一节中表单提交的用户体验非常不友好,为了解决这个问题,一种叫做Post/Redirect/GET的模式被提出并广泛应用在Web程序开发中。和传统的表单提交方法不同,这种模式在POST请求完成后,会重定向(HTTP状态码302)到另外一个页面。这样相当于浏览器重新加载了一个页面(使用GET请求),此时用户无论如何刷新浏览器,都是刷新当前GET请求对应的页面而不再是重复提交一次表单。下面是一个用户提交订单到服务器的过程描述:
这样的表单提交处理方法,相当于接连触发了两个HTTP请求:
页面重定向相当于返回HTTP状态码302以及一个重定向地址到浏览器,在Servlet中可以使用HttpServletResponse.sendRedirect()
方法来完成。例如在登录成功后,可以跳转到博客列表页面:
@WebServlet("/login")
public class UserLoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if (登陆成功) {
// 登陆成功重定向到博客列表页面
response.sendRedirect(request.getContextPath() + "/blogs");
} else {
// 登陆失败重新回到登陆页面
request.setAttribute("message", "登陆失败原因");
RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/jsp/login.jsp");
dispatcher.forward(request, response);
}
}
}
提示
注意这里的重定向地址需要包含本身的Context Path,在生产环境中一般是/
,在我们这个练习中是/blog
,为了代码具有更好的可移植性,可以使用HttpServletRequest.getContextPath()
方法:
和登录表单一样,创建文章表单提交成功后,直接跳转到该文章详细页面,这样用户自然而然的知道文章已经创建成功.
在通常情况下,表单通过POST方法提交数据后,我们推荐使用POST/Redirect/GET模式(HTTP状态码302)进行重定向来实现更友好的用户体验。
你现在应该对使用MVC模式非常熟悉,接下来我们需要用MVC模式来重写重写login.html
。
你可能已经发现上一节的代码中存在这一行:
因此,我们把login.html
重名为login.jsp
并放入到/WEB-INF/jsp
目录下。如何显示登陆页面呢?我们需要在UserLoginServlet
中增加doGet()
方法:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/jsp/login.jsp");
dispatcher.forward(request, response);
}
这样,访问登陆页面的URL就从/blog/login.html
变为/blog/login
了。
当然,这样做最大的好处在于,登陆页面也是一个动态页面了,这样会方便我们添加动态信息。比如在上一节中,登陆失败的原因可能是:
我们可以请求的实际信息,使用request.setAttribute("message", "登陆失败原因");
来给用户显示登陆失败原因,这样会更加友好。相应地,你只需要在login.jsp
页面中添加处理登陆失败信息的Servlet代码片段即可。
相应地,create.html
和register.html
都可以做类似的处理。
登录发表评论 登录 注册
第10课的用例,创建博客成功,没有通过,哪位可以看一下呢