这篇来讨论下JSP的最佳实践,也就是JSP中应该写什么代码,不应该写什么代码。JSP本质是Servlet,那么我们就要考虑什么时候用Servlet什么时候使用jsp。有些代码确实在servlet中实现,也可以在jsp文件中实现,本篇就是来了解下JSP最佳实践。
1.全部代码写成jsp,模拟用户登录成功。
三个jsp页面,分别是登录框和处理判断登录是否成功页面和登录成功,欢迎用户页面。
这么由于没有servlet类,就不用配置web.xml文件,三个文件代码如下
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>登录</title> </head> <body> <form action="/JSP01/doLogin.jsp" method="post"> 用户名:<input type="text" name="userName" /><br/> 密码:<input type="password" name="pwd" /><br/> <input type="submit" value="登录" /><br/> </form> </body> </html> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>验证登录</title> </head> <body> <% //获取表单数据 String userName = request.getParameter("userName"); String pwd = request.getParameter("pwd"); //处理业务逻辑,这里不走mysql DB,模拟一下 if("Anthony".equals(userName) && "123".equals(pwd)){ //跳转到 登录成功,欢迎你页面 request.getRequestDispatcher("/loginSuccess.jsp").forward(request, response); }else { //重定向到登录页面 response.sendRedirect("/JSP01/login.jsp"); } //分发转向 %> </body> </html><%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>登录成功</title> </head> <body> 欢迎你:<% String userName = request.getParameter("userName"); out.print(userName); %> </body> </html>
运行来测试下
这样看起来好像没啥问题对吧,但是我们明明是想要让用户看到的是loginSuccess.jsp,然后显示欢迎用户,这个第二张图显示是doLogin.jsp, 对用户来说,判断用户登录,这个页面应该隐藏,不应该让用户看到,当然用户也不关心和他无关的页面。
2.和用户UI无关代码写到servlet中去
这样我们这里把doLogin中代码提取到一个Servlet类中,其他文件代码。
package com.anthony.login; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class DoLoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取表单数据 String userName = req.getParameter("userName"); String pwd = req.getParameter("pwd"); //处理业务逻辑,这里不走mysql DB,模拟一下 if("Anthony".equals(userName) && "123".equals(pwd)){ //转发到 登录成功,欢迎你页面 req.getRequestDispatcher("/loginSuccess.jsp").forward(req, resp); }else { //重定向到登录页面 resp.sendRedirect("/JSP01/login.jsp"); } //分发转向 } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }在login.jsp中表单中action需要改成这个doLoginServlet的访问url
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>登录</title> </head> <body> <form action="/JSP01/doLoginServlet" method="post"> 用户名:<input type="text" name="userName" /><br/> 密码:<input type="password" name="pwd" /><br/> <input type="submit" value="登录" /><br/> </form> </body> </html>重新部署到tomcat,然后访问,没啥问题。
3.转发和重定向不同,引起拿不到用户名称
这里把doLoginServlet.java中登录成功,把转发改成重定向试试,看看用户名还能不能拿到。
package com.anthony.login; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class DoLoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取表单数据 String userName = req.getParameter("userName"); String pwd = req.getParameter("pwd"); //处理业务逻辑,这里不走mysql DB,模拟一下 if("Anthony".equals(userName) && "123".equals(pwd)){ //转发到 登录成功,欢迎你页面 //req.getRequestDispatcher("/loginSuccess.jsp").forward(req, resp); resp.sendRedirect(req.getContextPath() + "/loginSuccess.jsp"); }else { //重定向到登录页面 resp.sendRedirect(req.getContextPath() + "/login.jsp"); } //分发转向 } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }登录成功转发改成重定向之后,name的值就拿不到了
4.还是转发,新增一个页面也需要欢迎用户,还是拿不到用户名
这里我们还是改回到转发方法,上面我们知道转发,在登录成功页面,肯定能拿到用户名信息。那么如果跳转一个主页,也需要拿到用户名信息,转发还好使吗。
package com.anthony.login; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class DoLoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取表单数据 String userName = req.getParameter("userName"); String pwd = req.getParameter("pwd"); //处理业务逻辑,这里不走mysql DB,模拟一下 if("Anthony".equals(userName) && "123".equals(pwd)){ //转发到 登录成功,欢迎你页面 req.getRequestDispatcher("/loginSuccess.jsp").forward(req, resp); //resp.sendRedirect(req.getContextPath() + "/loginSuccess.jsp"); }else { //重定向到登录页面 resp.sendRedirect(req.getContextPath() + "/login.jsp"); } //分发转向 } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } } <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <h1>欢迎来到首页</h1> 欢迎你:<% String userName = request.getParameter("userName"); out.print(userName); %> </body> </html>测试这个修改
点击这个link
这里来想一下什么拿不到,我们点击跳转主页,这个动作就是触发了一个新的请求,我们知道请求是一个域对象,不同请求对象中,是不能共享数据,那么我们学习过session,下面就用session来解决这个问题。
package com.anthony.login; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class DoLoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取表单数据 String userName = req.getParameter("userName"); String pwd = req.getParameter("pwd"); //处理业务逻辑,这里不走mysql DB,模拟一下 if("Anthony".equals(userName) && "123".equals(pwd)){ //转发到 登录成功,欢迎你页面 //转发之前,用户名写入session属性 req.getSession().setAttribute("userName", userName); req.getRequestDispatcher("/loginSuccess.jsp").forward(req, resp); //resp.sendRedirect(req.getContextPath() + "/loginSuccess.jsp"); }else { //重定向到登录页面 resp.sendRedirect(req.getContextPath() + "/login.jsp"); } //分发转向 } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } } <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <h1>欢迎来到首页</h1> 欢迎你:<% String userName = (String)session.getAttribute("userName"); out.print(userName); %> </body> </html>得到效果是这样
5.JSP最佳实践总结
Servlet:控制器,重点编写Java代码逻辑(获取表单数据,处理业务逻辑,分发转向) JSP:代码显示模板,重点在于显示数据。