D11 Sping Boot 入门 Sping框架--Java Web之书城项目(三)页面动态化
1、页面jsp动态化
Ⅰ、在HTML页面顶行添加page指令。
Ⅱ、把文件后缀名改为.jsp。
2、抽取页面中相同的内容
Ⅰ、head中的css、jQuery、base标签。
Ⅱ、页脚
Ⅲ、各个目录模块
3、登录、注册错误提示及表单回显
LoginServlet.java中
login.jsp中
4、BaseServlet的抽取
Ⅰ、LoginServlet和RegistServlet的合并
Ⅱ、新建UserServlet.java来整合注册和登录功能(配置web.xml)
1 package com.gychen.web; 2 3 import com.gychen.pojo.User; 4 import com.gychen.service.UserService; 5 import com.gychen.service.impl.UserServiceImpl; 6 7 import javax.servlet.ServletException; 8 import javax.servlet.http.HttpServlet; 9 import javax.servlet.http.HttpServletRequest; 10 import javax.servlet.http.HttpServletResponse; 11 import java.io.IOException; 12 13 public class UserServlet extends HttpServlet { 14 15 private UserService userService = new UserServiceImpl(); 16 17 18 /** 19 * 处理登录功能 20 * @param req 21 * @param resp 22 * @throws ServletException 23 * @throws IOException 24 */ 25 protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ 26 27 28 //1、获取请求的参数 29 String username = req.getParameter("username"); 30 String password = req.getParameter("password"); 31 32 // 2、调用XXXService.xxx()处理业务/userService.log()登录 33 //判断用户名是否存在 34 if(userService.existUsername(username)){ 35 // userService.login(new User(null,username,password,null)); 36 User loginUser = userService.login(new User(null,username,password,null)); 37 // 3、根据login()方法返回结果判断登录是否成功 38 if(loginUser != null) { 39 // 40 // Ⅰ、成功 41 System.out.println("login success"); 42 // 43 // 跳到登录成功页面 44 req.getRequestDispatcher("/pages/user/login_success.jsp").forward(req,resp); 45 }else { 46 // 47 // Ⅱ、失败 48 System.out.println("login failed"); 49 //把错误信息和回显信息保存到Resquest域中 50 req.setAttribute("loginError","用户名或密码错误"); 51 req.setAttribute("username",username); 52 // 53 // 跳回登录页面 54 req.getRequestDispatcher("/pages/user/login.jsp").forward(req,resp); 55 } 56 }else{ 57 System.out.println("用户名["+username+"]不存在,请先注册"); 58 req.setAttribute("loginError","用户名不存在"); 59 req.setAttribute("username",username); 60 // 跳回登录页面 61 req.getRequestDispatcher("/pages/user/login.jsp").forward(req,resp); 62 } 63 64 } 65 66 /** 67 * 处理注册功能 68 * @param req 69 * @param resp 70 * @throws ServletException 71 * @throws IOException 72 */ 73 protected void regist(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ 74 75 // 1、获取请求参数 76 String username = req.getParameter("username"); 77 String password = req.getParameter("password"); 78 // String repwd = req.getParameter("repwd"); 79 String email = req.getParameter("email"); 80 String verification_code = req.getParameter("verification_code"); 81 // 2、检查验证码是否正确 82 if("abcde".equalsIgnoreCase(verification_code)){ 83 84 // Ⅰ、正确 85 86 // 3、检查用户名是否可用 87 if(userService.existUsername(username)){ 88 // ①、不可用 89 // 跳回注册页面 90 System.out.println("用户名["+username+"]已存在"); 91 //把错误信息和回显保存到Request域中 92 req.setAttribute("registError","用户名已存在"); 93 req.setAttribute("username",username); 94 req.setAttribute("email",email); 95 req.getRequestDispatcher("/pages/user/regist.jsp").forward(req,resp); 96 }else{ 97 // ②、可用 98 System.out.println("用户名["+username+"]可用"); 99 // 调用Service保存到数据库 100 userService.registUser(new User(null,username,password,email)); 101 // 跳到注册成功页面 102 req.getRequestDispatcher("/pages/user/regist_success.jsp").forward(req,resp); 103 } 104 105 }else { 106 // Ⅱ、错误 107 // 跳回注册页面 108 System.out.println("验证码错误["+verification_code+"]错误"); 109 //把错误信息和回显保存到Request域中 110 req.setAttribute("registError","验证码错误"); 111 req.setAttribute("username",username); 112 req.setAttribute("email",email); 113 req.getRequestDispatcher("/pages/user/regist.jsp").forward(req,resp); 114 } 115 } 116 117 @Override 118 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ 119 120 //判断页面的功能 121 String action = req.getParameter("action"); 122 123 //如果是登录页面,则处理登录业务逻辑 124 if("login".equals(action)){ 125 login(req,resp); 126 } 127 128 //如果是注册页面,则处理注册业务逻辑 129 if("regist".equals(action)){ 130 131 regist(req,resp); 132 } 133 134 } 135 }
Ⅲ、使用反射优化大量的elif语句
情景:有大量的用户功能,比如除了登录、注册的修改密码、绑定手机、绑定邮箱、注销用户等等。
若使用反射(根据参数返回相应方法名),则不需每添加一个功能就写一个if判断语句。开发者只需关注功能模块(即方法)
1 package com.gychen.web; 2 3 import com.gychen.pojo.User; 4 import com.gychen.service.UserService; 5 import com.gychen.service.impl.UserServiceImpl; 6 import com.gychen.test.UserServletTest; 7 8 import javax.servlet.ServletException; 9 import javax.servlet.http.HttpServlet; 10 import javax.servlet.http.HttpServletRequest; 11 import javax.servlet.http.HttpServletResponse; 12 import java.io.IOException; 13 import java.lang.reflect.Method; 14 15 public class UserServlet extends HttpServlet { 16 17 private UserService userService = new UserServiceImpl(); 18 19 20 /** 21 * 处理登录功能 22 * @param req 23 * @param resp 24 * @throws ServletException 25 * @throws IOException 26 */ 27 protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ 28 29 30 //1、获取请求的参数 31 String username = req.getParameter("username"); 32 String password = req.getParameter("password"); 33 34 // 2、调用XXXService.xxx()处理业务/userService.log()登录 35 //判断用户名是否存在 36 if(userService.existUsername(username)){ 37 // userService.login(new User(null,username,password,null)); 38 User loginUser = userService.login(new User(null,username,password,null)); 39 // 3、根据login()方法返回结果判断登录是否成功 40 if(loginUser != null) { 41 // 42 // Ⅰ、成功 43 System.out.println("login success"); 44 // 45 // 跳到登录成功页面 46 req.getRequestDispatcher("/pages/user/login_success.jsp").forward(req,resp); 47 }else { 48 // 49 // Ⅱ、失败 50 System.out.println("login failed"); 51 //把错误信息和回显信息保存到Resquest域中 52 req.setAttribute("loginError","用户名或密码错误"); 53 req.setAttribute("username",username); 54 // 55 // 跳回登录页面 56 req.getRequestDispatcher("/pages/user/login.jsp").forward(req,resp); 57 } 58 }else{ 59 System.out.println("用户名["+username+"]不存在,请先注册"); 60 req.setAttribute("loginError","用户名不存在"); 61 req.setAttribute("username",username); 62 // 跳回登录页面 63 req.getRequestDispatcher("/pages/user/login.jsp").forward(req,resp); 64 } 65 66 } 67 68 /** 69 * 处理注册功能 70 * @param req 71 * @param resp 72 * @throws ServletException 73 * @throws IOException 74 */ 75 protected void regist(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ 76 77 // 1、获取请求参数 78 String username = req.getParameter("username"); 79 String password = req.getParameter("password"); 80 // String repwd = req.getParameter("repwd"); 81 String email = req.getParameter("email"); 82 String verification_code = req.getParameter("verification_code"); 83 // 2、检查验证码是否正确 84 if("abcde".equalsIgnoreCase(verification_code)){ 85 86 // Ⅰ、正确 87 88 // 3、检查用户名是否可用 89 if(userService.existUsername(username)){ 90 // ①、不可用 91 // 跳回注册页面 92 System.out.println("用户名["+username+"]已存在"); 93 //把错误信息和回显保存到Request域中 94 req.setAttribute("registError","用户名已存在"); 95 req.setAttribute("username",username); 96 req.setAttribute("email",email); 97 req.getRequestDispatcher("/pages/user/regist.jsp").forward(req,resp); 98 }else{ 99 // ②、可用 100 System.out.println("用户名["+username+"]可用"); 101 // 调用Service保存到数据库 102 userService.registUser(new User(null,username,password,email)); 103 // 跳到注册成功页面 104 req.getRequestDispatcher("/pages/user/regist_success.jsp").forward(req,resp); 105 } 106 107 }else { 108 // Ⅱ、错误 109 // 跳回注册页面 110 System.out.println("验证码错误["+verification_code+"]错误"); 111 //把错误信息和回显保存到Request域中 112 req.setAttribute("registError","验证码错误"); 113 req.setAttribute("username",username); 114 req.setAttribute("email",email); 115 req.getRequestDispatcher("/pages/user/regist.jsp").forward(req,resp); 116 } 117 } 118 119 @Override 120 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ 121 122 //判断页面的功能 123 String action = req.getParameter("action"); 124 125 // //如果是登录页面,则处理登录业务逻辑 126 // if("login".equals(action)){ 127 // login(req,resp); 128 // } 129 // 130 // //如果是注册页面,则处理注册业务逻辑 131 // else if("regist".equals(action)){ 132 // 133 // regist(req,resp); 134 // } 135 136 //不用添加一个功能就写一个if,反射获取方法名 137 try { 138 //通过action业务鉴别字符串,获取相应的业务 方法反射对象 139 Method method = this.getClass().getDeclaredMethod 140 (action,HttpServletRequest.class,HttpServletResponse.class); 141 // System.out.println(method); 142 //调用目标业务方法 143 method.invoke(this,req,resp); 144 } catch (Exception e) { 145 e.printStackTrace(); 146 } 147 148 } 149 }
UserServlet总结:
①、获取action参数值。
②、通过反射获取action对应的业务方法。
③、通过反射调用业务方法。
Ⅳ、BaseServlet的抽取
新建一个BaseServlet.java类(把doPost抽取到BaseServlet中供所有模块复用继承)
1 package com.gychen.web; 2 3 import javax.servlet.ServletException; 4 import javax.servlet.http.HttpServlet; 5 import javax.servlet.http.HttpServletRequest; 6 import javax.servlet.http.HttpServletResponse; 7 import java.io.IOException; 8 import java.lang.reflect.Method; 9 10 public abstract class BaseServlet extends HttpServlet { 11 12 @Override 13 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 14 15 //判断页面的功能 16 String action = req.getParameter("action"); 17 18 // //如果是登录页面,则处理登录业务逻辑 19 // if("login".equals(action)){ 20 // login(req,resp); 21 // } 22 // 23 // //如果是注册页面,则处理注册业务逻辑 24 // else if("regist".equals(action)){ 25 // 26 // regist(req,resp); 27 // } 28 29 //不用添加一个功能就写一个if,反射获取方法名 30 try { 31 //通过action业务鉴别字符串,获取相应的业务 方法反射对象 32 Method method = this.getClass().getDeclaredMethod 33 (action,HttpServletRequest.class,HttpServletResponse.class); 34 // System.out.println(method); 35 //调用目标业务方法 36 method.invoke(this,req,resp); 37 } catch (Exception e) { 38 e.printStackTrace(); 39 } 40 41 } 42 }
1 package com.gychen.web; 2 3 import com.gychen.pojo.User; 4 import com.gychen.service.UserService; 5 import com.gychen.service.impl.UserServiceImpl; 6 import com.gychen.test.UserServletTest; 7 8 import javax.servlet.ServletException; 9 import javax.servlet.http.HttpServlet; 10 import javax.servlet.http.HttpServletRequest; 11 import javax.servlet.http.HttpServletResponse; 12 import java.io.IOException; 13 import java.lang.reflect.Method; 14 15 public class UserServlet extends BaseServlet { 16 17 private UserService userService = new UserServiceImpl(); 18 19 20 /** 21 * 处理登录功能 22 * @param req 23 * @param resp 24 * @throws ServletException 25 * @throws IOException 26 */ 27 protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ 28 29 30 //1、获取请求的参数 31 String username = req.getParameter("username"); 32 String password = req.getParameter("password"); 33 34 // 2、调用XXXService.xxx()处理业务/userService.log()登录 35 //判断用户名是否存在 36 if(userService.existUsername(username)){ 37 // userService.login(new User(null,username,password,null)); 38 User loginUser = userService.login(new User(null,username,password,null)); 39 // 3、根据login()方法返回结果判断登录是否成功 40 if(loginUser != null) { 41 // 42 // Ⅰ、成功 43 System.out.println("login success"); 44 // 45 // 跳到登录成功页面 46 req.getRequestDispatcher("/pages/user/login_success.jsp").forward(req,resp); 47 }else { 48 // 49 // Ⅱ、失败 50 System.out.println("login failed"); 51 //把错误信息和回显信息保存到Resquest域中 52 req.setAttribute("loginError","用户名或密码错误"); 53 req.setAttribute("username",username); 54 // 55 // 跳回登录页面 56 req.getRequestDispatcher("/pages/user/login.jsp").forward(req,resp); 57 } 58 }else{ 59 System.out.println("用户名["+username+"]不存在,请先注册"); 60 req.setAttribute("loginError","用户名不存在"); 61 req.setAttribute("username",username); 62 // 跳回登录页面 63 req.getRequestDispatcher("/pages/user/login.jsp").forward(req,resp); 64 } 65 66 } 67 68 /** 69 * 处理注册功能 70 * @param req 71 * @param resp 72 * @throws ServletException 73 * @throws IOException 74 */ 75 protected void regist(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ 76 77 // 1、获取请求参数 78 String username = req.getParameter("username"); 79 String password = req.getParameter("password"); 80 // String repwd = req.getParameter("repwd"); 81 String email = req.getParameter("email"); 82 String verification_code = req.getParameter("verification_code"); 83 // 2、检查验证码是否正确 84 if("abcde".equalsIgnoreCase(verification_code)){ 85 86 // Ⅰ、正确 87 88 // 3、检查用户名是否可用 89 if(userService.existUsername(username)){ 90 // ①、不可用 91 // 跳回注册页面 92 System.out.println("用户名["+username+"]已存在"); 93 //把错误信息和回显保存到Request域中 94 req.setAttribute("registError","用户名已存在"); 95 req.setAttribute("username",username); 96 req.setAttribute("email",email); 97 req.getRequestDispatcher("/pages/user/regist.jsp").forward(req,resp); 98 }else{ 99 // ②、可用 100 System.out.println("用户名["+username+"]可用"); 101 // 调用Service保存到数据库 102 userService.registUser(new User(null,username,password,email)); 103 // 跳到注册成功页面 104 req.getRequestDispatcher("/pages/user/regist_success.jsp").forward(req,resp); 105 } 106 107 }else { 108 // Ⅱ、错误 109 // 跳回注册页面 110 System.out.println("验证码错误["+verification_code+"]错误"); 111 //把错误信息和回显保存到Request域中 112 req.setAttribute("registError","验证码错误"); 113 req.setAttribute("username",username); 114 req.setAttribute("email",email); 115 req.getRequestDispatcher("/pages/user/regist.jsp").forward(req,resp); 116 } 117 } 118 }
5、数据的封装和抽取BeanUtils的使用
BeanUtils工具类,它可以一次性的把所有请求的参数注入到JavaBean中。
BeanUtils不是jdk的类,是第三方的类,需要导包。
Ⅰ、BeanUtils导包
1 //使用BeanUtils注入参数 2 try { 3 User user = new User(); 4 System.out.println("参数注入前:"+user); //参数注入前:User{id=null, username='null', password='null', email='null'} 5 /** 6 * 把所有请求的参数都注入到user对象中 7 */ 8 BeanUtils.populate(user,req.getParameterMap()); 9 System.out.println("参数注入之后:"+user); //参数注入之后:User{id=null, username='admin', password='admin', email='admin@qq.com'} 10 } catch (Exception e) { 11 e.printStackTrace(); 12 }
Ⅱ、把此功能封装到com.gychen.utils中供所有模块使用
新建WebUtils.java类
法一:
1 package com.gychen.utils; 2 3 import org.apache.commons.beanutils.BeanUtils; 4 5 import java.util.Map; 6 7 public abstract class WebUtils { 8 9 /** 10 * 把Map中的值注入到对应的JavaBean中 11 * @param map 12 * @param bean 13 */ 14 public static void copyParamToBean(Map map, Object bean){ 15 //使用BeanUtils注入参数,bean是被注入的对象 16 try { 17 18 System.out.println("参数注入前:"+bean); 19 /** 20 * 把所有请求的参数都注入到map中 21 */ 22 BeanUtils.populate(bean,map); 23 System.out.println("参数注入之后:"+bean); 24 } catch (Exception e) { 25 e.printStackTrace(); 26 } 27 } 28 }
法二:
1 package com.gychen.utils; 2 3 import org.apache.commons.beanutils.BeanUtils; 4 5 import java.util.Map; 6 7 public abstract class WebUtils { 8 9 /** 10 * 法二 11 * 把Map中的值注入到对应的JavaBean中 12 * @param map 13 * @param bean 14 * @return 15 */ 16 public static Object copyParamToBean(Map map, Object bean) { 17 //使用BeanUtils注入参数,bean是被注入的对象 18 try { 19 20 System.out.println("参数注入前:" + bean); 21 /** 22 * 把所有请求的参数都注入到map中 23 */ 24 BeanUtils.populate(bean, map); 25 System.out.println("参数注入之后:" + bean); 26 } catch (Exception e) { 27 e.printStackTrace(); 28 } 29 return bean; 30 } 31 }
法三:
1 package com.gychen.utils; 2 3 import org.apache.commons.beanutils.BeanUtils; 4 5 import java.util.Map; 6 7 public abstract class WebUtils { 8 9 // /** 10 // * 法一 11 // * 引用格式为 User user = new User(); 12 // * WebUtils.copyParamToBean(req.getParameterMap(),user); 13 // * 把Map中的值注入到对应的JavaBean中 14 // * @param map 15 // * @param bean 16 // */ 17 // public static void copyParamToBean(Map map, Object bean){ 18 // //使用BeanUtils注入参数,bean是被注入的对象 19 // try { 20 // 21 // System.out.println("参数注入前:"+bean); 22 // /** 23 // * 把所有请求的参数都注入到map中 24 // */ 25 // BeanUtils.populate(bean,map); 26 // System.out.println("参数注入之后:"+bean); 27 // } catch (Exception e) { 28 // e.printStackTrace(); 29 // } 30 // } 31 32 33 // /** 34 // * 法二 35 // * 把Map中的值注入到对应的JavaBean中 36 // * 引用格式为 User user = (User) WebUtils.copyParamToBean(req.getParameterMap(),new User()); 37 // * @param map 38 // * @param bean 39 // * @return 40 // */ 41 // public static Object copyParamToBean(Map map, Object bean) { 42 // //使用BeanUtils注入参数,bean是被注入的对象 43 // try { 44 // 45 // System.out.println("参数注入前:" + bean); 46 // /** 47 // * 把所有请求的参数都注入到map中 48 // */ 49 // BeanUtils.populate(bean, map); 50 // System.out.println("参数注入之后:" + bean); 51 // } catch (Exception e) { 52 // e.printStackTrace(); 53 // } 54 // return bean; 55 // } 56 57 58 59 60 61 62 /** 63 * 法三 泛型 64 * 把Map中的值注入到对应的JavaBean中 65 * 引用格式为 User user = WebUtils.copyParamToBean(req.getParameterMap(),new User()); 66 * @param map 67 * @param bean 68 * @return 69 */ 70 public static <T> T copyParamToBean(Map map, T bean) { 71 //使用BeanUtils注入参数,bean是被注入的对象 72 try { 73 74 System.out.println("参数注入前:" + bean); 75 /** 76 * 把所有请求的参数都注入到map中 77 */ 78 BeanUtils.populate(bean, map); 79 System.out.println("参数注入之后:" + bean); 80 } catch (Exception e) { 81 e.printStackTrace(); 82 } 83 return bean; 84 } 85 }
在UserServlet程序里调用WebUtils
法一(对应以上法一):
//使用封装好的bean工具类来注入参数 User user = new User(); WebUtils.copyParamToBean(req.getParameterMap(),user); // 参数注入之后:User{id=null, username='admin', password='adsss', email='admin@qq.com'}
法二(对应以上法二):
1 //法二 2 User user = (User) WebUtils.copyParamToBean(req.getParameterMap(),new User());
法三(对应以上法三):
1 //法三 2 User user = WebUtils.copyParamToBean(req.getParameterMap(),new User());
6、使用EL表达式实现表单错误和回显
Ⅰ、login.jsp
java脚本表达式: <%=request.getAttribute("loginError")==null?"请输入用户名和密码": request.getAttribute("loginError")%>
EL表达式: ${ empty requestScope.loginError?"请输入用户名和密码":requestScope.loginError }
Java脚本表达式:
1 <input class="itxt" type="text" placeholder="请输入用户名" autocomplete="off" tabindex="1" name="username" 2 value="<%=request.getAttribute("username")==null?"":request.getAttribute("username")%>" />
EL表达式:
1 <input class="itxt" type="text" placeholder="请输入用户名" autocomplete="off" tabindex="1" name="username" 2 value="${ requestScope.username }" />
Ⅱ、regist.jsp
java脚本表达式: <%=request.getAttribute("registError")==null?"" :request.getAttribute("registError")%>
EL表达式: ${ requestScope.registError }