1、Jar 包
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<!--统一版本属性管理-->
<lombok.version>1.18.12</lombok.version>
<junit.version>4.11</junit.version>
<mysql.version>5.1.47</mysql.version>
<fastjson.version>1.2.62</fastjson.version>
</properties>
<dependencies>
<!-- servlet begin -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- servlet end -->
<!-- lombok begin -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<!-- lombok end -->
<!-- junit begin -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- junit end -->
<!-- mysql-connector-java begin -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- mysql-connector-java end -->
<!-- fastjson begin 做数据转JSON格式 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- fastjson begin -->
<!-- 邮件发送需要的jar包 -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId>
<version>1.6.7</version>
</dependency>
<!-- 邮件发送需要的jar包end -->
<!-- https://mvnrepository.com/artifact/commons-lang/commons-lang -->
<!-- apache的commons-long 使用StringUtils.isEmpty()做非空校验 -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<!-- apache的commons-long end>
</dependencies>
jdbc.properties
driverClass=com.mysql.jdbc.Driver
jdbcUrl=jdbc:mysql://localhost:3306/kh96_smbms?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2b8
user=root
password=root
2、登录 登出
2.1 系统常量
系统常量要习惯放在常量类中,方便以后的代码扩展和维护;
public class CommConstant {
//系统默认当前页码 为1
public static final Integer DEFAULT_INT_PAGE_NO = 1;
//系统默认 每页容量为 5
public static final Integer DEFAULT_INT_PAGE_SIZE = 5;
//系统默认提示信息
public static final String SYS_TIP_MESSAGE = "message";
//系统默认登录session信息 :id
public static final String SYS_USER_SESSION_ID = "userId";
public static final String SYS_USER_SESSION_USER_CODE = "userCode";
public static final String SYS_USER_SESSION_USER_PWD = "userPwd";
}
2.2 登录表单
<form class="loginForm" action="${pageContext.request.contextPath }/userServlet?method=login" name="actionForm" id="actionForm" method="post" >
<div class="info">${error }</div>
<div class="inputbox">
<label for="user">用户名:</label>
<input type="text" class="input-text" id="userCode" name="userCode" placeholder="请输入用户名" required/>
</div>
<div class="inputbox">
<label for="mima">密码:</label>
<input type="password" id="userPassword" name="userPassword" placeholder="请输入密码"/>
</div>
<div class="subBtn">
<input type="submit" value="登录"/>
<input type="reset" value="重置"/>
<input type="button" id="codeLogin" value="邮箱登录"/>
</div>
</form>
2.3 登录方式
2.3.1 一般登录
- 获取用户名和密码,跳转到登录请求,查询用户是否存在;
- 存在将登录用户对象存放到sesssion域中(方便展示用户信息),跳转到用户展示页面;
- 不存在转发到登录页面(携带错误提示信息回来);
2.3.2 邮箱登录
- 输入用户名是判断用户是否开启邮箱登录(邮箱字段是否有值)
- 开启就可以使用邮箱登录按钮,不开启就不能使用
- 点击邮箱登录后,后台异步发送验证码,并跳转到邮件登录页面
授权码获取-> qq邮箱获取授权码
2.3.2.1 判断用户是否开启邮箱验证登录
开启,邮件登录按钮可以使用;
没有开启,邮件登录不可以使用;
是否开启邮箱验证登录javascript
//对验证码登录的处理
//一开始的验证码登录按钮不能使用,只有用户邮箱存在才可以使用
//这里有个问题,用户编码不唯一(用编码查询用户邮箱),最好使用唯一的字段进行登录,查邮箱的时候才好查找
//校验用户邮箱是否存在
//一开始 不可以使用邮箱登录,用户名正确才可以
$("#codeLogin").attr("disabled","true");
$("#codeLogin").css("background-color","#aaa");
$("#userCode").blur(function () {
$.getJSON("userServlet?method=checkUserCodeExist",{"userCode":$("#userCode").val()} ,function(data){
//判断添加返回结果
//alert(data);
if(data == true){
//alert("用户邮箱存在");
$("#codeLogin").attr("disabled",false);
$("#codeLogin").css("background-color","#54a4d7"); //蓝色
}else{
//alert("用户没有开启邮箱登录!!!");
$("#codeLogin").attr("disabled",true);
$("#codeLogin").css("background-color","#aaa"); //灰色
}
});
});
是否开启邮箱验证servlet
//根据用户编码查看用户邮箱是否存在
public void checkUserCodeExist(HttpServletRequest req, HttpServletResponse resp) throws Exception {
System.out.println("=============根据用户编码查看用户邮箱是否存在=====================");
//获取用户编码
String userCode = req.getParameter("userCode");
//调用业务层查看用户邮箱是否存在
User emailLoginUser = userService.getUserByUserCode(userCode);
if(emailLoginUser != null && emailLoginUser.getUserEmail() != null){
//如果用户存在,且有邮箱
System.out.println(userCode+"用户邮箱为===》userEmail="+emailLoginUser.getUserEmail());
//将用户存入session域中,当邮箱登录成功之后,用emailLoginUser 替换 loginUser
req.getSession().setAttribute("emailLoginUser",emailLoginUser);
resp.getWriter().print(true);
}else{
System.out.println(userCode+"用户没有开启邮箱登录!!!");
resp.getWriter().print(false);
}
}
2.3.2.1 异步请求发送验证码
异步请求发送验证码javascript
//发送验证码 跳转到验证码登录页面
$("#codeLogin").click(function () {
$.getJSON("userServlet?method=sendEmail",null ,function(data){
//判断添加返回结果
//alert(data)
if(data == true){
alert("请注意接收验证码!!!");
location.href = "emailLogin.jsp";
}else{
alert("验证码发送失败!!!");
}
});
});
异步发送验证码servlet
//发送验证码
public void sendEmail(HttpServletRequest req, HttpServletResponse resp) throws Exception {
System.out.println("=============发送验证码=====================");
//获取 session中的 emailLoginUser
User emailLoginUser = (User)req.getSession().getAttribute("emailLoginUser");
//发送验证码
//随机生成6位 验证码
String emailCode = "143233";
System.out.println("验证码==》"+emailCode);
//发送
//new SendEmilCode().sendCode(emailLoginUser.getUserEmail(),emailCode);
//多线程 异步发送
new Sendmail(emailLoginUser.getUserEmail(),emailCode).start();
//并将验证码存到session中,方便验证
req.getSession().setAttribute("emailCode",emailCode);
resp.getWriter().print(true);
}
发送验证码工具类
public class Sendmail extends Thread {
//发邮件的人
private String from = "发件人邮箱";
//邮箱的用户名
private String username = "邮箱的用户名";
//邮箱的密码
private String password = "邮箱授权码";
//发送邮件的服务器地址
private String host = "smtp.qq.com";
//收邮件的人
private String loginUserEmail;
//发送打验证码
private String sendEmailCode;
public Sendmail(String loginUserEmail,String sendEmailCode){
this.loginUserEmail = loginUserEmail;
this.sendEmailCode = sendEmailCode;
}
//重写run方法的实现,在run方法中发送邮件给指定的用户
@Override
public void run() {
try{
Properties prop = new Properties();
prop.setProperty("mail.host", host);
prop.setProperty("mail.transport.protocol", "smtp");
prop.setProperty("mail.smtp.auth", "true");
// 关于QQ邮箱,还要设置SSL加密,加上以下代码即可
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
prop.put("mail.smtp.ssl.enable", "true");
prop.put("mail.smtp.ssl.socketFactory", sf);
//1、创建定义整个应用程序所需的环境信息的 Session 对象
Session session = Session.getDefaultInstance(prop, new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
//发件人邮件用户名、授权码
return new PasswordAuthentication("[email protected]","gvxxjbnfmouoeacd");
}
});
//开启Session的debug模式,这样就可以查看到程序发送Email的运行状态
session.setDebug(true);
//2、通过session得到transport对象
Transport ts = session.getTransport();
//3、使用邮箱的用户名和授权码连上邮件服务器
ts.connect(host, username, password);
//4、创建邮件
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from)); //发件人
message.setRecipient(Message.RecipientType.TO, new InternetAddress(loginUserEmail)); //收件人
message.setSubject("《超市订单管理系统》登录验证码"); //邮件的标题
String info = "<h1 style='color: pink'>尊敬的用户您的动态登录验证码为:"+sendEmailCode+",请不要将验证码转发给他人!!!</h1>";
message.setContent(info, "text/html;charset=UTF-8");
message.saveChanges();
//发送邮件
ts.sendMessage(message, message.getAllRecipients());
ts.close();
}catch (Exception e) {
throw new RuntimeException(e);
}
}
}
2.3.3 判断验证码是否正确
判断验证码javascript
//验证验证码是否正确
$("#emailLogin").click(function () {
$.getJSON("userServlet?method=emailLogin",{"checkCode":$("#checkCode").val()} ,function(data){
//判断添加返回结果
//alert(data);
if(data == true){
alert("登录成功");
location.href = "${pageContext.request.contextPath}/jsp/frame.jsp";
}else{
alert("验证码错误!!!");
}
});
return false;
});
判断验证码servlet
//判断用户验证码是否正确
public void emailLogin(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("=============判断用户验证码是否正确 emailLogin =====================");
//获取用户 输入的验证码
String checkCode = req.getParameter("checkCode");
//获取session中 发送给用户的验证码
String emailCode = (String) req.getSession().getAttribute("emailCode");
//判断验证码是否正确
//获取 session中的 emailLoginUser
User emailLoginUser = (User)req.getSession().getAttribute("emailLoginUser");
if(checkCode.equals(emailCode)){
//登录成功
//用 emailLoginUser 替换session 中的 loginUser
req.getSession().setAttribute("loginUser",emailLoginUser);
System.out.println(emailLoginUser.getUserCode()+"用户邮箱验证登录成功!!!");
resp.getWriter().print(true);
}else {
System.out.println(emailLoginUser.getUserCode()+"用户邮箱验证登录失败!!!");
resp.getWriter().print(false);
}
}
2.4 登出
- 跳转到用户退出请求
- 移除session中的用户对象
- 重定向到用户登录页面
<a href="${pageContext.request.contextPath }/userServlet?method=userLogOut">退出</a>
3、分页条件查询
条件分页查询的重点在于,要拿到查询条件和分页条件;
为了方便获取参数,和在分页跳转的时候,方便 多页面 使用一个公用的跳转部分;
将分页参数隐藏在form表单中,提交表单的时候将分页参数一起提交;
3.1 html
userlist.jsp
<%@include file="/jsp/common/head.jsp"%>
<div class="right">
<div class="location">
<strong>你现在所在的位置是:</strong>
<span>用户管理页面</span>
</div>
<div class="search">
<form id="searchForm" method="post" action="${pageContext.request.contextPath }/userServlet?method=userList">
<span>用户名:</span>
<input name="queryName" class="input-text" type="text" id="queryName" value="${(pageSupport.callBackInfo)[0]}">
<span>用户角色:</span>
<select name="queryUserRole">
<option value="0" <c:if test="${(pageSupport.callBackInfo)[1] == 0 }" > selected </c:if>>--请选择--</option>
<c:forEach items="${roleList}" var="role">
<option value="${role.id}" <c:if test="${(pageSupport.callBackInfo)[1] == role.id }" > selected </c:if>>--${role.roleName}--</option>
</c:forEach>
</select>
<!-- 当前页面参数 和 页面容量-->
<input type="hidden" name="pageNo" id="pageNo" value="${pageSupport.currPageNo == null ? 1 : pageSupport.currPageNo}"/>
<input type="hidden" name="pageSize" id="pageSize" value="${pageSupport.pageSize == null ? 5 : pageSupport.pageSize}"/>
<!-- 当前排序字段 和 排序方式-->
<input type="hidden" name="orderBy" id="orderBy" value="${pageSupport.orderBy == null ? 'id' : pageSupport.orderBy}"/>
<input type="hidden" name="ascOrDesc" id="ascOrDesc" value="${pageSupport.ascOrDesc == null ? 'asc' : pageSupport.ascOrDesc}"/>
<input value="查 询" type="submit" id="searchbutton">
<a href="${pageContext.request.contextPath}/jsp/useradd.jsp" >添加用户</a>
</form>
</div>
<!--用户-->
<table class="providerTable" cellpadding="0" cellspacing="0">
<tr class="firstTr">
<th width="10%">用户编码</th>
<th width="20%">用户名称</th>
<th width="10%">性别</th>
<th width="10%">年龄</th>
<th width="10%">电话</th>
<th width="10%">用户角色</th>
<th width="30%">操作</th>
</tr>
<c:forEach items="${pageSupport.data}" var="user">
<tr>
<td>
<span>${user.userCode}</span>
</td>
<td>
<span>${user.userName}</span>
</td>
<td>
<span>${user.gender == 1 ? "女" : "男"}</span>
</td>
<td>
<span>${user.birthday}</span>
</td>
<td>
<span>${user.phone}</span>
</td>
<td>
<!-- 遍历用户角色列表 -->
<c:forEach items="${roleList}" var ="role" varStatus="status">
<!-- 根据用户的userRole 与 角色的 id 匹配对应的 角色 -->
<c:if test="${ role.id eq user.userRole}" var="flag">
<span>${role.roleName}</span>
</c:if>
</c:forEach>
</td>
<td>
<span><a class="viewUser" href="${pageContext.request.contextPath }/userServlet?method=userInfo&id=${user.id}" ><img src="${pageContext.request.contextPath }/images/read.png" alt="查看" title="查看"/></a></span>
<span><a class="modifyUser" href="${pageContext.request.contextPath }/userServlet?method=toUserMod&id=${user.id}"><img src="${pageContext.request.contextPath }/images/xiugai.png" alt="修改" title="修改"/></a></span>
<span><a class="deleteUser" href="${pageContext.request.contextPath }/userServlet?method=userDel&id=${user.id}" onClick="return confirm('是否确认删除${user.userName}用户')" ><img src="${pageContext.request.contextPath }/images/schu.png" alt="删除" title="删除"/></a></span>
</td>
</tr>
</c:forEach>
</table>
<input type="hidden" id="totalPageCount" value="1"/>
<c:import url="rollpage.jsp">
<c:param name="totalCount" value="1"/>
<c:param name="currentPageNo" value="1"/>
<c:param name="totalPageCount" value="1"/>
</c:import>
</div>
</section>
<%@include file="/jsp/common/foot.jsp" %>
3.2 pageSupport
主要有三类数据:
1、分页参数
2、回显参数 (条件查询的条件)
3、条件分页查询的数据
public class PageSupport<T> {
//当前页,显示页码
private int currPageNo = 1;
//页面容量
private int pageSize = 5;
//总条数(带条件查询的总条数)
private int totalCount;
//总页数(根据总条数和页面容量)
private int totalPage;
//分页条件查询的数据
private T data;
//回显 查询数据
private List<String> callBackInfo;
//排序字段
private String orderBy = "id";
//升序 还是 降序
private String ascOrDesc = "asc";
//设置总条数的时候 计算总页数
public void setTotalCount(int totalCount) {
//当存在总条数,确定总页数
this.totalCount = totalCount;
//计算总页数
this.totalPage = this.totalCount % this.pageSize == 0 ?
this.totalCount / this.pageSize :
this.totalCount / this.pageSize + 1;
}
public int getCurrPageNo() {
return currPageNo;
}
public void setCurrPageNo(int currPageNo) {
//页码特殊处理
if(currPageNo < 1 || this.totalCount == 0 ){
currPageNo = 1;
}else if(currPageNo > this.totalPage){
currPageNo = this.getTotalPage();
}
this.currPageNo = currPageNo;
}
.......
}
3.3 userList 方法
分页 条件查询用户列表
- 获取 条件查询参数
- 获取 分页参数pageNo,pageSize
- 获取 排序参数
- 条件查询 总条数
- 创建 分页对象(指定data的类型,一般 List
) - 设置 pageSize (必须先放pageSize)
- 设置 totalCount (再放totalCount),pageSupport计算总页数
- 创建 回显数据集合,放入需要回显的数据
- 查询分页条件查询的 数据集合List
- 将数据集合放入pageSupport的data中
- 将pageSupport放入request中,方便转发后 遍历数据,和 回显数据
- 查询角色列表(展示 用户信息 的时候 和 条件查询的 时候需要使用)
- 将角色列表集合放入session域中 (这一类需要经常使用的参数,可以放到session中,不过修改后要重置)
- 转发 到用户展示页面 userlist.jsp
// 分页 条件查询用户列表
public void userList(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("=============条件 分页 查询用户列表=====================");
//获取 条件查询 参数
String queryName = req.getParameter("queryName");
String queryUserRole = req.getParameter("queryUserRole") == null ? "0" : req.getParameter("queryUserRole");
//获取 分页 参数
//获取显示的当前页码
Integer pageNo = Integer.parseInt( req.getParameter("pageNo") == null ? "1" : req.getParameter("pageNo") );
Integer pageSize = Integer.parseInt( req.getParameter("pageSize") == null ? "5" : req.getParameter("pageSize") );
//排序条件
String orderBy = req.getParameter("orderBy") == null ? "id" : req.getParameter("orderBy");
String ascOrDesc = req.getParameter("ascOrDesc") == null ? "asc" : req.getParameter("ascOrDesc");
//根据条件查询获取用户 总数
int totalCount = userService.getUserListTotalByQueryNameAndQueryUserRole(queryName,Integer.parseInt(queryUserRole));
//创建分页对象
PageSupport<List<User>> pageSupport = new PageSupport<List<User>>();
//先放pageSize
pageSupport.setPageSize(pageSize);
//再放totalCount
pageSupport.setTotalCount(totalCount);
//创建回显数据
List callBackInfo = new ArrayList();
//pageSupport 中放入回显数据
//查询条件
callBackInfo.add(queryName);
callBackInfo.add(queryUserRole);
pageSupport.setCallBackInfo(callBackInfo);
//当前页码
pageSupport.setCurrPageNo(pageNo);
//页面容量
pageSupport.setPageSize(pageSize);
//排序条件
pageSupport.setOrderBy(orderBy);
//排序 方式 asc desc
pageSupport.setAscOrDesc(ascOrDesc);
//查询所有的用户详情列表
List<User> userList = userService.getUserListByQueryNameAndQueryUserRole(queryName,Integer.parseInt(queryUserRole),pageSupport);
System.out.println("=============条件 分页 查询用户列表 参数=============");
System.out.println("查询参数==》queryName = " + queryName);
System.out.println("查询参数==》queryUserRole = " + queryUserRole);
System.out.println("排序参数==》orderBy = " + orderBy);
System.out.println("排序参数==》ascOrDesc = " + ascOrDesc);
System.out.println("分页参数==》pageNo = " + pageNo);
System.out.println("分页参数==》pageSize = " + pageSize);
System.out.println(JSON.toJSONStringWithDateFormat(userList,"yyyy-MM-dd"));
//req.setAttribute("userList",userList);
//将数据放入分页对象中
pageSupport.setData(userList);
//将分页对象放进request域中
req.setAttribute("pageSupport",pageSupport);
//查询所有的 用户角色
List<Role> roleList = roleService.findRoleList();
System.out.println("=============查询所有的用户角色===============");
System.out.println(JSON.toJSONStringWithDateFormat(roleList,"yyyy-MM-dd"));
//将roleList 放进session域中,方便其他的地方直接调用,不用再次查询
req.getSession().setAttribute("roleList",roleList);
//内部转发到用户列表页面
req.getRequestDispatcher( "/jsp/userlist.jsp").forward(req,resp);
//req.getContextPath()+"/jsp/userlist.jsp" 带项目名的时候不能这样会 拼接两次 项目名
//req.getRequestDispatcher( req.getContextPath()+"/jsp/userlist.jsp").forward(req,resp);
}
3.4 Dao层实现方法
3.4.1 selectUserListTotalByQueryNameAndQueryUserRole
条件查询用户列表 总数
//条件查询用户列表 总数
@Override
public int selectUserListTotalByQueryNameAndQueryUserRole(String queryName, Integer QueryUserRole) {
int total = 0;
//SQl
String executeSql = "select count(1) as 'total' \n"
+ "from smbms_user where 1=1 ";
//params
List<Object> params = new ArrayList<Object>();
//拼接参数 和 sql
if(null != queryName && !"".equals(queryName)){
executeSql += " and userName like concat('%',?,'%') ";
params.add(queryName);
}
if(null != QueryUserRole && 0 != QueryUserRole){
executeSql += " and userRole = ? ";
params.add(QueryUserRole);
}
try {
//执行
executeSelect(executeSql, params.toArray());
//处理数据
while (rs.next()) {
total = rs.getInt("total");
}
}catch(Exception e){
e.printStackTrace();
}finally {
releaseResource(conn,pstmt,rs);
}
return total;
}
3.4.2 SelectUserListByQueryNameAndQueryUserRole
条件 分页 查询用户列表
1、定义返回的参数
2、定义sql
3、动态拼接查询条件
3、动态拼接查询参数(List
标签:15,String,req,用户,查询,Javaweb09,跳转,增删,分页 From: https://www.cnblogs.com/xiaoqigui/p/16594687.html