Day61-Day65 JSP技术整合
1.思维导图
2.代码部分
操作域
- page域
<% //往pageContext域中存储了一个msg变量 pageContext.setAttribute("msg" ,"hello page msg"); %> <% //往pageContext域中存储了一个msg变量 Object msg = pageContext.getAttribute("msg"); System.out.println(msg); %>
- request域
<% //定义变量的意义! 提高复用性! 提高可维护性! //String name : 参数名称 //Object value : 参数值 //int scope : 操作的域 pageContext.setAttribute("msg1","hello page1",PageContext.REQUEST_SCOPE); //请求转发 request.getRequestDispatcher("/demo06.jsp").forward(request,response); %> <% //变量msg1定义到_jspService方法中 Object msg1 = request.getAttribute("msg1"); System.out.println("msg1 : "+msg1); Object msg11 = pageContext.getAttribute("msg1", PageContext.REQUEST_SCOPE); System.out.println(msg11); %>
- session域
<% pageContext.setAttribute("msg2","hello page2",PageContext.SESSION_SCOPE); %>
- application域
<% pageContext.setAttribute("msg3","hello page3",PageContext.APPLICATION_SCOPE); %>
<% pageContext.setAttribute("msg1","hello page1"); %> ${pageScope.msg1}
- 获取request域数据
<% request.setAttribute("msg1","hello page1"); %> ${requestScope.msg1}
- 获取session域数据
<% session.setAttribute("msg1","hello page1"); %> ${sessionScope.msg1}
- 获取application域数据
<% application.setAttribute("msg1","hello page1"); %> ${applicationScope.msg1}
<% //数组静态初始化 String[] msgs = {"获取","复杂","域"}; pageContext.setAttribute("msgs",msgs); %> <%--jsp输出脚本--%> <%= ((String[])pageContext.getAttribute("msgs"))[0] %> ${msgs[1]}
- 获取List集合
<% List<String> msgs1 = new ArrayList<>(); msgs1.add("复杂的"); msgs1.add("域数据"); request.setAttribute("msgs1",msgs1); %> <%= ((List<String>)request.getAttribute("msgs1")).get(0) %> ${msgs1[1]}
- 获取map集合
<% HashMap<String,Object> map = new HashMap<>(); map.put("username","白鸽"); map.put("age",18); session.setAttribute("map",map); %> <%= ((HashMap<String,Object>)session.getAttribute("map")).get("username") %> ${map.age}
- 获取java对象
<% User user = new User(); user.setId(1); user.setUsername("黑鸦"); user.setPassword("123456"); application.setAttribute("user",user); %> <%= ((User)application.getAttribute("user")).getUsername() %> ${user.password}
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <% int num = 1; request.setAttribute("num" , num); %> <c:if test="${num eq 1}"> num等于1 </c:if> <c:if test="${num ne 1}"> num不等于1 </c:if>
- set标签
- 向域对象(page域、request域、session域、application域)中存储数据
<c:set var="msg" scope="request" value="hello jstl"></c:set>
${msg}
- remove标签
- 移除域对象中的数据
<c:remove var="msg" scope="request"></c:remove>
${msg}<br>
- catch标签
- 捕获jsp页面的异常,相当于try...catch,var:声明异常对象名称,比如:var="e" ,变量e就可以接收异常对象
<c:catch var="e"> <% int num = 1 / 0; %> </c:catch> ${e}<br>
- if标签
- 条件判断
<c:set var="num" value="2" scope="request"></c:set> <c:if test="${num == 1}"> num 等于 1 </c:if> <c:if test="${num != 1}"> num 不等于 1 </c:if>
- forEach标签
- 遍历集合或数组 begin:开始、end:结束、step:步数、var:元素名称、items:集合/数组
- varStatus:元素状态对象 first:是否是第一个元素,last:是否是最后一个元素,current:当前元素,index:当前脚标
<!-- 基本使用 --> <c:forEach begin="1" end="10" step="3" var="num"> ${num} </c:forEach> <% List<String> strs = new ArrayList<>(); strs.add("aaa"); strs.add("bbb"); strs.add("ccc"); request.setAttribute("strs",strs); %> <!-- 相当于普通for循环 --> <c:forEach begin="0" end="${strs.size() - 1}" step="1" var="i"> ${strs[i]} </c:forEach> <!-- 相当于增强for循环 --> <c:forEach var="str" items="${strs}" varStatus="status"> ${str}<br> ${status.current} -- ${status.index} -- ${status.first} -- ${status.last}<br> </c:forEach>
- forToken标签
- 分割字符串:items:要分割的字符串,delims:分割的规则,var:分割产生的元素
<% String msg1 = "aaa--bbb--ccc"; request.setAttribute("msg1",msg1); %> <c:forTokens items="${msg1}" delims="--" var="sonMsg"> ${sonMsg} </c:forTokens>
jstl综合案例
- ProductDao
public class ProductDaoImpl implements ProductDao { @Override public List<Product> selectProductList() throws Exception { return new QueryRunner(JDBCUtils.getDataSource()) .query("select * from tb_product", new BeanListHandler<Product>(Product.class)); } }
- ProductServlet
@WebServlet(name = "ProductServlet" ,urlPatterns = "/selectProductList") public class ProductServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ProductDao productDao = new ProductDaoImpl(); try { List<Product> productList = productDao.selectProductList(); System.out.println(productList); } catch (Exception e) { e.printStackTrace(); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }
- productList.jsp
<table border="1px" cellspacing="0px" cellpadding="10px" width="500px" height="200px"> <tr> <td>ID</td> <td>名称</td> <td>单价</td> <td>数量</td> <td>小计</td> </tr> <%--循环之前,总价为0--%> <c:set var="total" value="0" scope="page"></c:set> <c:forEach items="${productList}" var="product"> <%--forEach标签,循环一次就是一个小计!--%> <tr> <td>${product.id}</td> <td>${product.name}</td> <td>${product.price}</td> <td>${product.count}</td> <td>${product.price * product.count}</td> </tr> <c:set var="total" value="${total + product.price * product.count}" scope="page"></c:set> </c:forEach> <%--循环之后,计算出总价--%> <tr> <td colspan="5" align="right"> 总价:${total}元 </td> </tr> </table>
- 注意
页面上的name属性值要和java对象中的属性名一致
自定义BeanUtils框架
- MyBeanUtils
public class MyBeanUtils { /** * 将map集合中的请求参数值封装到对象t中 * @param t * @param map : 键:参数名称;值:一组参数值。 * @param <T> */ public static<T> void populate(T t , Map<String,? extends Object> map ){ Class<?> clazz = t.getClass(); Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { String fieldName = field.getName(); String methodName = "set"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1); System.out.println(methodName); //获取对应的set方法 try { Class<?> type = field.getType(); Method method = clazz.getMethod(methodName, type); if (null != method) { //第二个参数:请求参数的值 //id、username、password、age Object object = map.get(fieldName); if (null != object) { String[] strs = (String[]) object; if (type.getName().equals("java.lang.Integer")) { method.invoke(t,Integer.parseInt(strs[0])); } else { method.invoke(t,strs[0]); } } } } catch (Exception e) { throw new MyNoSuchMethodException("field " + fieldName + " there is no setter method!!!"); } } } }
- MyNoSuchMethodException
public class MyNoSuchMethodException extends RuntimeException{ public MyNoSuchMethodException() { } public MyNoSuchMethodException(String message) { super(message); } public MyNoSuchMethodException(String message, Throwable cause) { super(message, cause); } public MyNoSuchMethodException(Throwable cause) { super(cause); } public MyNoSuchMethodException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } }
- UserDao
@Override public User login(User inputUser) throws Exception { return new QueryRunner(JDBCUtils.getDataSource()) .query("select * from tb_user where username = ? and password = ?", new BeanHandler<User>(User.class), inputUser.getUsername(), inputUser.getPassword()); }
- UserService
@Override public User login(User inputUser) throws Exception { UserDao userDao = new UserDaoImpl(); return userDao.login(inputUser); }
- UserServlet类的login方法
private UserService userService = new UserServiceImpl(); public String login(HttpServletRequest request,HttpServletResponse response){ User inputUser = new User(); //将请求参数封装到inputUser中 try { BeanUtils.populate(inputUser,request.getParameterMap()); User existUser = userService.login(inputUser); //没有异常有返回值 if (null != existUser) { //登录成功 , 修改登录状态,跳转到首页 request.getSession().setAttribute("existUser",existUser); return "redirect:/index.jsp"; } else { //登录失败 ,记录错误信息,跳转到登录页面 request.setAttribute("errorMsg","账户或密码错误"); return "/login.jsp"; } } catch (Exception e) { e.printStackTrace(); } //有异常,应该有返回值 。意味着登录失败,返回登录页面,重新登录 return "/login.jsp"; }
- login.jsp
<body> <font color="red">${errorMsg}</font> <form action="${pageContext.request.contextPath}/user" method="post"> <input type="hidden" name="methodName" value="login"/> 账户:<input type="text" name="username"/><br> 密码:<input type="text" name="password"/><br> <button type="submit">登录</button> </form> </body>
- index.jsp
<body> <%-- 在登录状态 显示用户名 --%> <c:if test="${existUser != null}"> 欢迎回来~~~ ${existUser.username} <a href="${pageContext.request.contextPath}">注销</a> </c:if> <%-- 不在登录状态 提示登录 --%> <c:if test="${existUser == null}"> 您还没有登录,<a href="${pageContext.request.contextPath}/login.jsp">请登录</a> </c:if> </body>
@Override public List<User> selectUserList() throws Exception { return new QueryRunner(JDBCUtils.getDataSource()) .query("select * from tb_user", new BeanListHandler<User>(User.class)); }
- UserServlet类的selectUserList方法
public String selectUserList(HttpServletRequest request,HttpServletResponse response) throws Exception { List<User> userList = userService.selectUserList(); request.getSession().setAttribute("userList",userList); return "/index.jsp"; }
- index.jsp
<body> <%-- 在登录状态 显示用户名 --%> <c:if test="${existUser != null}"> 欢迎回来~~~ ${existUser.username} <a href="${pageContext.request.contextPath}/user?methodName=logout">注销</a> <%--显示用户列表--%> <table border="1px" cellspacing="0px" cellpadding="15px" width="500px" height="200px"> <tr> <td>ID</td> <td>账户</td> <td>密码</td> </tr> <c:forEach items="${userList}" var="user"> <tr> <td>${user.id}</td> <td>${user.username}</td> <td>${user.password}</td> </tr> </c:forEach> </table> </c:if> <%-- 不在登录状态 提示登录 --%> <c:if test="${existUser == null}"> 您还没有登录,<a href="${pageContext.request.contextPath}/login.jsp">请登录</a> </c:if> </body>
@WebFilter(filterName = "LoginFilter" ,urlPatterns = "/*") public class LoginFilter implements Filter { public void destroy() { } public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { System.out.println("LoginFilter doFilter"); HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; //登录校验 String requestURI = request.getRequestURI(); String methodName = request.getParameter("methodName"); if (requestURI.contains("login") || ( methodName != null && methodName.equals("login"))) { //和登录相关的资源,直接放行 chain.doFilter(req, resp); } else { //和登录无关的资源 Object existUser = request.getSession().getAttribute("existUser"); if (null == existUser) { //不在登录状态,跳转到login.jsp response.sendRedirect("/day64/login.jsp"); } else { //在登录状态,直接放行 chain.doFilter(req, resp); } } } public void init(FilterConfig config) throws ServletException { } }
@Override public int deleteUserById(Integer id) throws Exception { return new QueryRunner(JDBCUtils.getDataSource()) .update("delete from tb_user where id = ?", id); }
- UserService
@Override public boolean deleteUserById(Integer id) throws Exception { return userDao.deleteUserById(id) == 1; }
- UserServlet的deleteUserById方法
public String deleteUserById(HttpServletRequest request,HttpServletResponse response){ Integer id = Integer.parseInt(request.getParameter("id")); try { boolean flag = userService.deleteUserById(id); } catch (Exception e) { e.printStackTrace(); } //获取用户列表 return "/user?methodName=selectUserList"; }
- index.jsp
<c:forEach items="${userList}" var="user"> <tr> <td>${user.id}</td> <td>${user.username}</td> <td>${user.password}</td> <td> <a href="${pageContext.request.contextPath}/user?methodName=deleteUserById&id=${user.id}">删除</a> </td> </tr> </c:forEach>
@Override public void updateUserById(User inputUser) throws Exception { new QueryRunner(JDBCUtils.getDataSource()) .update("update tb_user set username = ? , password = ? where id = ?", inputUser.getUsername(), inputUser.getPassword(), inputUser.getId()); }
- UserServlet类toUpdateUserById方法
public String toUpdateUserById(HttpServletRequest request,HttpServletResponse response) { Integer id = Integer.parseInt(request.getParameter("id")); User user = null; try { user = userService.selectUserById(id); } catch (Exception e) { e.printStackTrace(); } request.setAttribute("user",user); return "/updateUser.jsp"; }
- UserServlet类updateUserById方法
public String updateUserById(HttpServletRequest request,HttpServletResponse response){ User inputUser = new User(); try { BeanUtils.populate(inputUser,request.getParameterMap()); userService.updateUserById(inputUser); //修改成功 return "/user?methodName=selectUserList"; } catch (Exception e) { e.printStackTrace(); } request.setAttribute("errorMsg","修改失败"); //修改失败 return "/user?methodName=toUpdateUserById&id="+inputUser.getId(); }
- updateUser.jsp
<body> <font color="red">${errorMsg}</font> <form action="${pageContext.request.contextPath}/user" method="post"> <input type="hidden" name="methodName" value="updateUserById"/> <input type="hidden" name="id" value="${user.id}"> 账户:<input type="text" name="username" value="${user.username}"><br> 密码:<input type="text" name="password" value="${user.password}"><br> <button type="submit">修改</button> </form> </body>
public class UserDaoImpl implements UserDao { @Override public Integer selectTotalSize() throws Exception { return new QueryRunner(JDBCUtils.getDataSource()) .query("select * from tb_user", new BeanListHandler<User>(User.class)) .size(); } @Override public List<User> selectUserListByPage(Integer begin, Integer pageSize) throws Exception { return new QueryRunner(JDBCUtils.getDataSource()) .query("select * from tb_user limit ? , ?" , new BeanListHandler<User>(User.class), begin, pageSize); } }
public String selectUserListByPage(HttpServletRequest request, HttpServletResponse response){ String currentPageStr = request.getParameter("currentPage"); Integer currentPage = getCurrentPage(currentPageStr); //调用UserService,传递currentPage try { PageBean<User> pageBean = userService.selectUserListByPage(currentPage); System.out.println(pageBean); request.setAttribute("pageBean",pageBean); //转发到用户列表页面 return "/userList.jsp"; } catch (Exception e) { e.printStackTrace(); } return "/index.jsp"; }
- UserService
public PageBean<User> selectUserListByPage(Integer currentPage) throws Exception { PageBean<User> pageBean = new PageBean<>(); // currentPage;当前页数 pageBean.setCurrentPage(currentPage); // totalSize;总记录数 UserDao userDao = new UserDaoImpl(); Integer totalSize = userDao.selectTotalSize(); pageBean.setTotalSize(totalSize); // pageSize;每页记录数 Integer pageSize = 3; pageBean.setPageSize(pageSize); // totalPage:总页数 = 总记录数 / 每页记录数 Integer totalPage = ( totalSize % pageSize == 0 ) ? ( totalSize / pageSize ) : (totalSize / pageSize + 1 ) ; pageBean.setTotalPage(totalPage); // list;当前页数据 //select * from tb_user limit ? , ? //第一个? : 开始脚标 = (当前页数 - 1) * 每页记录数 //第二个? : 查询多少个 (每页记录数) pageSize Integer begin = (currentPage - 1) * pageSize; List<User> list = userDao.selectUserListByPage(begin, pageSize); pageBean.setList(list); return pageBean; }
- userList.jsp
<body> <table border="1px" cellspacing="0px" cellpadding="10px" width="600px" height="200px"> <tr> <td>ID</td> <td>账户</td> <td>密码</td> </tr> <c:forEach items="${pageBean.list}" var="user"> <tr> <td>${user.id}</td> <td>${user.username}</td> <td>${user.password}</td> </tr> </c:forEach> <%--分页工具条--%> <tr> <td colspan="3" align="center"> 第${pageBean.currentPage}/${pageBean.totalPage}页 总记录数:${pageBean.totalSize} 每页显示${pageBean.pageSize}条 <c:if test="${pageBean.currentPage != 1}"> <a href="${pageContext.request.contextPath}/user?methodName=selectUserListByPage¤tPage=1"> [首页] </a> <a href="${pageContext.request.contextPath}/user?methodName=selectUserListByPage¤tPage=${pageBean.currentPage-1}"> [上一页] </a> </c:if> <c:if test="${pageBean.currentPage != pageBean.totalPage}"> <a href="${pageContext.request.contextPath}/user?methodName=selectUserListByPage¤tPage=${pageBean.currentPage+1}"> [下一页] </a> <a href="${pageContext.request.contextPath}/user?methodName=selectUserListByPage¤tPage=${pageBean.totalPage}"> [尾页] </a> </c:if> </td> </tr> </table> </body>