Day39
JSP
JSP底层
全称为Java Server Pages,JSP实际上就是一个servelet
JSP:HTML页面+Java代码,本质:servlet。
javapublic class login_jsp{ //JSP的9大内置对象 private JSPWriter out;//当前JSP输出流对象 private HttpServletRequest request;//请求对象 private HttpServletResponse response;//响应对象 private HttpSession session;//会话对象 private ServletContext application//全局域对象--表示整个项目 private ServletConfig config;//当前JSP配置文件对象 private Object page = this;//当前JSP对象 private PageContext pageContext;//当前JSP上下文关系对象:可以获取8大内置对象 //exception /** 9大内置对象中的四大域: 理解:这四大域都可以存储数据,本质是类对象作为容器存储数据、传递数据。 请求域:将数据存储到请求对象中,返回响应后,这个请求对象就会被销毁。 request.setAttribute(key,value); Object obj = request.getAttribute(key); 会话域:将数据存储到会话域对象中,会话超时(默认30分钟)或者单个用户断连时该会话域对象销毁。 session.setAttribute(key,value); object obj = session.getAttribute(key); 全局域:将数据存储到全局中,项目关闭时数据才会销毁。 application.setAttribute(key,value); Object obj = application.getAttribute(key); 页面域:将数据存储到当前页面中,当JSP在当前页面处理完请求并生成响应后,这个对象会被销毁,其他页面无法获取。 page.setAttribute(key,value); Object obj = page.getAttribute(key); 注:一般的servlet只有前面的三大域,jsp有四大域。 */ //jsp文件底层逻辑: public void jsp_service(HttpServletRequest req,HttpServletResponse resp){ //JSP文件中遇到HTML代码,就用输出流传输给客户端 out.writer("<html>\n\r"); out.writer("<head>\n\r"); ... //JSP文件遇到java代码直接执行 } }
注意:1.要导入相应的包。
2.login.jsp在底层实际上是login_jsp.java
JSP语法
JSP模版元素
JSP表达式
JSP脚本片段
JSP注释
JSP指令
JSP标签
JSP内置对象
如何查找JSP页面中的错误:
写一个jsp页面用来展示希望展示的错误信息。然后在web.xml配置文件里进行配置。
如:
xml<!-- 通用错误页面 --> <error-page> <exception-type>java.lang.Throwable</exception-type> <location>/error.jsp</location> </error-page> <!-- 404 错误页面 --> <error-page> <error-code>404</error-code> <location>/error.jsp</location> </error-page> <!-- 500 错误页面 --> <error-page> <error-code>500</error-code> <location>/error.jsp</location> </error-page>
JSP中的page指令:
异常页面:exceptionPage.jsp
EL表达式
功能:取值
要导包
以下是项目中将原来的JSP脚本元素(java代码)转换为EL的具体实现:
注册:
jsp${msg}
登录:
jsp${msg}
详情页面:(EL表达式可以找页面域、请求,会话域,全局域,优先级从高到低)
jsp<h2>欢迎${name}${(role eq "student")?"同学":""}${(role eq "teacher")?"老师":""}进入学生管理系统!</h2> <a href="StuInitModifyServlet?username=${usernmae}">修改信息</a> <a href="TeaInitModifyServlet?username=${usernmae}">修改信息</a>
修改密码:
jsp${msg} <input type="hidden" name="username" value="${username}"/> <input type="hidden" name="role" value="${username}"/> 账号:${username}<br/>
修改信息:(直接获取属性(底层通过反射获取值))
jsp<input type="hidden" name="username" value="${stu.username}"/> 姓名:<input type="text" name="name" value="${stu.name}" /><br /> 年龄:<input type="text" name="age" value="${stu.age}" /><br />
修改老师信息:
jsp<input type="hidden" name="username" value="${tea.username}"/> 姓名:<input type="text" name="name" value="${tea.username}" /><br />
分页:
jsp<a href="QueryAllStuServlet?curPage=${curPage-1}">上一页</a> <a href="QueryAllStuServlet?curPage=${curPage+1}">下一页</a> <a href="QueryAllStuServlet?curPage=${totalPage}">尾页</a>
JSTL-标准标签库
功能:做逻辑
要导包
选择核心库
jsp<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
以下是项目中将原来的JSP脚本元素(java代码)转换为EL和JSTL语句的具体实现:
详情页面:
jsp<c:if test="${role eq 'student'}"> <a href="StuInitModifyServlet?username=${username}">修改信息</a> </c:if> <c:if test="${role eq 'teacher'}"> <a href="TeaInitModifyServlet?username=${username}">修改信息</a> <a href="QueryAllStuServlet?curPage=1">查询学生</a> </c:if>
修改信息:(核心库+函数库,函数库中有包含的方法)
jsp<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%> 性别: <input type="radio" name="sex" value="man" <c:if test="${stu.sex eq 'man'}">checked="checked"</c:if>/>男 <input type="radio" name="sex" value="woman"<c:if test="${stu.sex eq 'woman'}">checked="checked"</c:if>/>女 爱好: <input type="checkbox" name="hobbies" value="football" <c:if test="${fn:contains(stu.hobbies,'football')}">checked="checked"</c:if>/>足球 <input type="checkbox" name="hobbies" value="basketball"<c:if test="${fn:contains(stu.hobbies,'basketball' )}">checked="checked"</c:if>/>篮球 <input type="checkbox" name="hobbies" value="shop" <c:if test="${fn:contains(stu.hobbies,'shop')}">checked="checked"</c:if>/>购物
修改老师信息:
jsp<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <input type="hidden" name="username" value="${tea.username}"/> <br/> 姓名:<input type="text" name="name" value="${tea.username}" /><br /> 课程:<select name="courseId"> <c:forEach items="${courseList}" var="course"> <option value="${course.id}"<c:if test="${tea.CourseId==course.id}">selected</c:if>>${course.name}</option> </c:forEach> </select>
分页:
jsp<c:forEach items="${stuList}" var="stuDto"> <tr> <td>${stuDto.stu.username}</td> <td>${stuDto.stu.name}</td> <td>${stuDto.sex}</td> <td>${stuDto.stu.age}</td> <td>${stuDto.hobbies}</td> <td> <a href="#">修改</a> <a href="#">删除</a> </td> </tr> </c:forEach> <a href="QueryAllStuServlet?curPage=1">首页</a> <c:if test="${curPage>1}"> <a href="QueryAllStuServlet?curPage=${curPage-1}">上一页</a> </c:if> <c:if test="${curPage<totalPage}"> <a href="QueryAllStuServlet?curPage=${curPage+1}">下一页</a> </c:if> <a href="QueryAllStuServlet?curPage=${totalPage}">尾页</a>
写一个rememberMe.jsp
jsp<%@ page import="java.net.URLDecoder" %><%-- Created by IntelliJ IDEA. User: Gu Date: 2024-06-15 Time: 14:54 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <% Cookie[] cookies = request.getCookies(); if(cookies!=null){ int count=0; for(Cookie cookie:cookies){ String key = cookie.getName(); String value = URLDecoder.decode(cookie.getValue(),"UTF-8"); if(key.equals("username")){ session.setAttribute("username",value); count++; } if(key.equals("name")){ session.setAttribute("name",value); count++; } if(key.equals("role")){ session.setAttribute("role",value); count++; } } if(count==3){ response.sendRedirect("index.jsp"); } } %> </body> </html>
把login.jsp中的java代码放进来,在login.jsp前面用include导入java代码。
jsp<!-- 物理包含:直接将rememberMe.jsp的代码添加到当前jsp中 --> <%@include file="rememberMe.jsp" %>
编译时没有rememberMe.jsp,此时是物理包含,直接将rememberMe.jsp的代码放到了login.jsp文件中。
WEB学生管理系统-优化分页查询
封装分页查询
在pojo文件夹中创建一个Page类,存储url、当前页、总页数、数据源等,创建有参构造方法,getset方法,toString方法等。
javapackage com.qf.pojo; import java.util.List; public class Page<T> { private String url; private int curPage; private int totalPage; private List<T> list; public Page(String url, int curPage, int totalPage, List<T> list) { this.url = url; this.curPage = curPage; this.totalPage = totalPage; this.list = list; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public int getCurPage() { return curPage; } public void setCurPage(int curPage) { this.curPage = curPage; } public int getTotalPage() { return totalPage; } public void setTotalPage(int totalPage) { this.totalPage = totalPage; } public List<T> getList() { return list; } public void setList(List<T> list) { this.list = list; } @Override public String toString() { return "Page{" + "url='" + url + '\'' + ", curPage=" + curPage + ", totalPage=" + totalPage + ", list=" + list + '}'; } }
然后在分页查询的Servlet(QueryAllStuServlet)中把数据封装到Page对象中。
javapackage com.qf.servlet; import com.qf.dto.StudentDto; import com.qf.pojo.Page; import com.qf.pojo.Student; import com.qf.utils.DBUtil; import com.qf.utils.DtoUtil; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.sql.SQLException; import java.util.List; @WebServlet("/QueryAllStuServlet") public class QueryAllStuServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); String url = "QueryAllStuServlet?curPage="; int curPage = Integer.parseInt(request.getParameter("curPage")); int count = 15;//每一页的数据条数 int offset = (curPage-1)*count;//计算偏移量 int allCount = DBUtil.getAllCount("select count(username) from student");//总条数 int totalPage;//总页数 if(allCount%count == 0){ totalPage = allCount/count; }else{ totalPage = allCount/count + 1; } try { String sql = "select * from student limit ?,?"; List<Student> stuList = DBUtil.commonQueryList(Student.class,sql,offset,count); List<StudentDto> stuDtoList = DtoUtil.studentListHandler(stuList); //将数据封装到对象中 Page<StudentDto> page = new Page<>(url,curPage,totalPage,stuDtoList); //将数据传回前端 request.setAttribute("page",page); request.getRequestDispatcher("stuList.jsp").forward(request,response); } catch (SQLException | InstantiationException | IllegalAccessException e) { throw new RuntimeException(e); } } } // 假数据 // public static void main(String[] args) { // for(int i=0;i<100;i++){ // String sql = "insert into student values (?,?,?,?,?,?)"; // try { // DBUtil.commonInsert(sql,"jiashuju"+i,"123123","假数据"+i,"man",18,"football"); // } catch (SQLException e) { // throw new RuntimeException(e); // } // } // }
创建一个新的jsp用于写首页、上下页、尾页等。
jsp<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <a href="${page.url}${page.curPage}">首页</a> <c:if test="${page.curPage>1}"> <a href="${page.url}${page.curPage-1}">上一页</a> </c:if> <c:if test="${page.curPage<page.totalPage}"> <a href="${page.url}${page.curPage+1}">下一页</a> </c:if> <a href="${page.url}${page.totalPage}">尾页</a>
此时用逻辑包含放到查询的jsp(stuList.jsp)中:
jsp<!-- 逻辑包含:当前jsp引用了page.jsp文件,底层是两个单独的jsp文件 --> <jsp:include page="page.jsp"/>
注:逻辑包含编译有jsp.java和jsp.class文件,相当于当前jsp引用了page.jsp文件,底层是两个单独的jsp文件。