分页
- 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"/>