分页
- MySQL 使用:
limit 起始条数,显示多少条
- Oracle使用:
SELECT * FROM( SELECT e.*,ROWNUM rn FROM emp e WHERE ROWNUM <=20 )WHERE rn>10; -- 第10条开始,取10条
- 分页的对象封装
public class Page<T> { private List<T> datas = new ArrayList<T>();// 数据 private int size;// 显示条数:10 private int dataCount;// 总120条 private int pre;// 上一页 private int now;// 第3页: private int count;// 共5页/尾页 private int next;// 下一页 private int start;// 显示页码开始 private int end;// 显示页码结束 private String url;// 路径 // 共130条/第3页/共5页 // 第一页 上一页 [1][2]3[4][5] 下一页 尾页 /** * @param size */ public Page(int size, int dataCount, int nowPage) { // 根据数据总条数来计算总页数:count/size如果除不尽则加1 this.size = size; this.dataCount = dataCount; if (this.dataCount % this.size == 0) { this.count = this.dataCount / this.size; } else { this.count = (this.dataCount / this.size) + 1; } if (nowPage <= 0) { this.now = 1; this.pre = 1; this.next = this.now + 1; } else if (nowPage >= this.count) { this.now = this.count; this.pre = this.now - 1; this.next = this.count; } else { this.now = nowPage; this.pre = 1; this.next = this.now + 1; } // 显示页码计算 this.start = this.now - 5; this.end = this.now + 5; if (this.start <= 0) { this.start = 1; } if (this.end > this.count) { this.end = this.count; } } public List<T> getDatas() { return datas; } public void setDatas(List<T> datas) { this.datas = datas; } public int getDataCount() { return dataCount; } public int getSize() { return size; } public int getPre() { return pre; } public int getNow() { return now; } public int getCount() { return count; } public int getNext() { return next; } public int getStart() { return start; } public int getEnd() { return end; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } }
异常处理
在web.xml
<error-page> <error-code>404</error-code> <location>/fileNotfound.jsp</location> </error-page> <error-page> <error-code>405</error-code> <location>/methodNotfound.jsp</location> </error-page> <error-page> <error-code>500</error-code> <location>/exception.jsp</location> </error-page> <error-page> <exception-type>javax.servlet.ServletException</exception-type> <location>/error-xml.jsp</location> </error-page> <!-- 所有异常使用,不推荐这么用 --> <error-page> <exception-type>java.lang.Throwable</exception-type> <location>/throwable-error.jsp</location> </error-page>
路径
相对路径:../(上一级目录下)./(当前目录下)
绝对路径:/项目名/(web项目从项目名开始,windows系统从盘符开始,linux系统从根目录开始)
链接、form表单、重定向使用绝对路径
转发不用写项目名称,默认在项目路径下
Cookie的应用
- 服务器判断是否是同一个用户:
客户端第一次访问服务器时,服务器创建一个session,并将session 的id添加到响应头的Cookie集合中,服务器向客户端响应数据时将Cookie一起带到客户端,此时一般客户端保留这个Cookie信息,当客户端再次访问服务器时,这时将Cookie信息一起带到服务器,服务器取出Cookie中的session的id,查找服务器中有没有这个session,如果有这个session说明就是同一个客户。
- 添加Cookie:
String gender = URLEncoder.encode("男", "utf-8"); Cookie cookie1 = new Cookie("username", "lishi"); Cookie cookie2 = new Cookie("password", "li123"); Cookie cookie3 = new Cookie("gender", gender); resp.addCookie(cookie1); resp.addCookie(cookie2); resp.addCookie(cookie3);
- 获取Cookie:
Cookie[] cookies = req.getCookies(); for (Cookie cookie : cookies) { String name = cookie.getName(); String value = URLDecoder.decode(cookie.getValue(), "utf-8"); resp.getWriter().println("<h3>"+name + "=" + value+"</h3>"); }
- Cookie生命周期设定
Cookie cookie1 = new Cookie("username", "lishi"); cookie1.setMaxAge(120);//单位秒,即2分钟就消失 Cookie cookie2 = new Cookie("password", "li123"); cookie2.setMaxAge(0);//只响应到客户端,到了客户端就消失 Cookie cookie3 = new Cookie("gender", gender); cookie3.setMaxAge(-1);//浏览器结束时消失
- 浏览器发送Cookie路径限定
Cookie默认路径是同一个文件下默认发送Cookie
设置Cookie发送路径 cookie.setPath(request.getContextPath());
- Cookie的限制
Cookie可以被用户禁用
Cookie保存到游览器端不安全,对于敏感数据需要加密后再使用Cookie来保存
Cookie保存只能少量数据,4kb左右
Cookie的个数有限制
Cookie只能保存字符串
中文译码解码
- 译码: String gender = URLEncoder.encode("男", "utf-8");
- 解码: String value = URLDecoder.decode(cookie.getValue(), "utf-8");
拷贝项目修改访问路径
点击Eclipse的Window>show view>Navigator,点击打开需要修改访问路径的项目>将settings点开>点开org.eclipse.wst.common.component文件,修改
<?xml version="1.0" encoding="UTF-8"?> <project-modules id="moduleCoreId" project-version="1.5.0"> <!-- 修改deploy-name属性 --> <wb-module deploy-name="day01-26"> <wb-resource deploy-path="/" source-path="/WebContent" tag="defaultRootSource" /> <wb-resource deploy-path="/WEB-INF/classes" source-path="/src" /> <property name="context-root" value="deploy-name属性值" /> <property name="java-output-path" value="/deploy-name属性值/build/classes" /> </wb-module> </project-modules>
保存,访问项目时使用deploy-name属性值作为项目名来访问
session
session存放在服务器,用于存放用户从浏览器访问服务器的一次会话信息
session用于登录:
if ("login".equals(oper)) { // 登录 String username = (String) req.getParameter("username"); String password = (String) req.getParameter("password"); String vcode = (String) req.getParameter("vcode"); if (username != null && username.equals("111") && password != null && password.equals("123")) { System.out.println("密码正确!"); // 密码正确 if (vcode == null || !vcode.equalsIgnoreCase((String) req.getSession().getAttribute("code"))) { // 验证码不对 System.out.println("验证码不对!"); req.setAttribute("msg", "验证码输入有误!"); req.getRequestDispatcher("login.jsp").forward(req, resp); } else { System.out.println("验证码正确!"); req.getSession().setAttribute("loginUser", "loginUser"); // session.setMaxInactiveInterval(20);//设置不活跃间隔,单位秒 req.getRequestDispatcher("list.do").forward(req, resp); // resp.sendRedirect("pageList.do");// 去员工列表 } } else { req.setAttribute("msg", "用户名或者密码输入错误!"); req.getRequestDispatcher("login.jsp").forward(req, resp); } } else if ("logout".equals(oper)) { // 退出登录 req.getSession().invalidate(); resp.sendRedirect("login.jsp"); }
验证码
public class ValidateCode extends HttpServlet { /** * */ private static final long serialVersionUID = 1L; public void service(HttpServletRequest request, HttpServletResponse response) throws IOException { // 创建空白图片 BufferedImage image = new BufferedImage(100, 30, BufferedImage.TYPE_INT_RGB); // 获取图片画笔 Graphics g = image.getGraphics(); Random r = new Random(); // 设置画笔颜色 g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255))); // 绘制矩形的背景 g.fillRect(0, 0, 100, 30); // 调用自定义的方法,获取长度为5的字母数字组合的字符串 String number = getNumber(5); // 插入session HttpSession session = request.getSession(); session.setAttribute("code", number); g.setColor(new Color(0, 0, 0)); g.setFont(new Font(null, Font.BOLD, 24)); // 设置颜色字体后,绘制字符串 g.drawString(number, 5, 25); // 绘制8条干扰线 for (int i = 0; i < 8; i++) { g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255))); g.drawLine(r.nextInt(100), r.nextInt(30), r.nextInt(100), r.nextInt(30)); } response.setContentType("image/jpeg"); // 写入响应头中 OutputStream ops = response.getOutputStream(); ImageIO.write(image, "jpeg", ops); ops.close(); } private String getNumber(int size) { String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; String number = ""; Random r = new Random(); for (int i = 0; i < size; i++) { number += str.charAt(r.nextInt(str.length())); } return number; } }
过滤器
可插入的web组件,编写一个过滤器需要实现Filter接口,多个Filter根据映射信息的先后顺序执行
过滤器优点:实现代码“可插拔性”,既增加或减少某个功能模块,不会影响程序的正常运行,
监听器
- 生命周期事件
httpRequestListener
HttpSessionListener
HttpServletContextListener
- 绑定数据相关事件
EL表达式
依次查找pagecontext、request、session、application
运算:empty判断是否为空
用户名:${name} 用户名:${requestScope.user.name} <!-- EL表达式常用的逻辑运算符 &&或者and 且 ||或者or 或 !或者not 非 ==或者eq 等于 !=或者ne 不等于 <或者lt 小于 >或者gt 大于 <=或者le 小于等于 >=或者ge 大于等于 --> <!-- param使用于request.getParameter(arg0) --> 用户名:${param.name} 爱好:${paramValues.interest[0]} 爱好:${paramValues.interest[1]}
JSTL表达式
<!-- if --> <c:if test="${user.score.score>=60}" var="s" scope="request">及格</c:if> <c:if test="${!s}">不及格</c:if> <br /> <!-- 集合遍历count从1开始,index中0开始 --> <c:forEach items="${emps}" var="emp" varStatus="s"> s.count:${s.count} s.index:${s.index} 员工姓名:${emp.uname} 员工职位:${emp.job}<br/> </c:forEach> <!-- if else --> <c:choose> <c:when test="${user.score.score>=60}">及格</c:when> <c:otherwise>不及格</c:otherwise> </c:choose>
web项目引用WEB-INF下面的图片例子
jsp页面在 WebRoot\WEB-INF\jsp\foreground\login\newlogin.jsp 在此页面引用 WebRoot\WEB-INF\images\common\下面的图片文件 例子: <img src="${pageContext.request.contextPath}/images/common/mask.png"/> 即: <img src="http://192.168.2.106:8180/NEcrd/images/common/mask.png"/>