百木园-与人分享,
就是让自己快乐。

Javaweb09-请求跳转项目 分页条件查询 + 增删改 + 邮件登录

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 一般登录

  1. 获取用户名和密码,跳转到登录请求,查询用户是否存在;
  2. 存在将登录用户对象存放到sesssion域中(方便展示用户信息),跳转到用户展示页面
  3. 不存在转发到登录页面(携带错误提示信息回来);

2.3.2 邮箱登录

  1. 输入用户名判断用户是否开启邮箱登录(邮箱字段是否有值)
  2. 开启就可以使用邮箱登录按钮,不开启就不能使用
  3. 点击邮箱登录后,后台异步发送验证码,并跳转到邮件登录页面

授权码获取-> 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(\"2663092414@qq.com\",\"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 登出

  1. 跳转到用户退出请求
  2. 移除session中用户对象
  3. 重定向用户登录页面
<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 方法

分页 条件查询用户列表

  1. 获取 条件查询参数
  2. 获取 分页参数pageNopageSize
  3. 获取 排序参数
  4. 条件查询 总条数
  5. 创建 分页对象(指定data的类型,一般 List)
  6. 设置 pageSize (必须先放pageSize)
  7. 设置 totalCount (再放totalCount),pageSupport计算总页数
  8. 创建 回显数据集合,放入需要回显的数据
  9. 查询分页条件查询的 数据集合List
  10. 将数据集合放入pageSupport的data中
  11. pageSupport放入request中,方便转发后 遍历数据,和 回显数据
  12. 查询角色列表(展示 用户信息 的时候 和 条件查询的 时候需要使用)
  13. 角色列表集合放入session域中 (这一类需要经常使用的参数,可以放到session中,不过修改后要重置)
  14. 转发 到用户展示页面 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、动态拼接查询参数(ListparamList)

4、动态拼接分页条件

5、动态拼接分页参数(ListparamList)

6、执行sql

7、处理数据

其中 timestampdiff(year,birthday, now()) 计算年龄的函数,最后说明;

//条件  分页 查询用户列表
@Override
public List<User> SelectUserListByQueryNameAndQueryUserRole(String queryName, Integer QueryUserRole, PageSupport pageSupport) {

    List<User> userList = new ArrayList<User>();

    //SQl
    String executeSql = \"select id,userCode,userName,userPassword,gender,birthday,timestampdiff(year,birthday, now()) as userAge ,phone,address,userRole,createdBy,creationDate,modifyBy,modifyDate\\n\"
        + \"from smbms_user where 1=1 \";


    //params
    List<Object> paramList = new ArrayList<Object>();

    //拼接参数 和 sql
    if(null != queryName  && !\"\".equals(queryName)){
        executeSql += \" and userName  like concat(\'%\',?,\'%\') \";
        paramList.add(queryName);
    }

    if(null != QueryUserRole  &&  0 != QueryUserRole){
        executeSql += \" and userRole = ? \";
        paramList.add(QueryUserRole);
    }

    //增加分页SQL语句
    executeSql += \" order by \"+pageSupport.getOrderBy()+ \" \" +pageSupport.getAscOrDesc()+\" limit ?,?\";
    paramList.add((pageSupport.getCurrPageNo() - 1) * pageSupport.getPageSize());
    paramList.add(pageSupport.getPageSize());

    try {
        //执行
        executeSelect(executeSql, paramList.toArray());

        //处理数据
        while (rs.next()) {
            User user = new User();
            user.setId(rs.getInt(\"id\"));
            user.setUserCode(rs.getString(\"userCode\"));
            user.setUserName(rs.getString(\"userName\"));
            user.setUserPassword(rs.getString(\"userPassword\"));
            user.setGender(rs.getInt(\"gender\"));
            user.setBirthday(rs.getDate(\"birthday\"));
            user.setUserAge(rs.getInt(\"userAge\"));
            user.setPhone(rs.getString(\"phone\"));
            user.setAddress(rs.getString(\"address\"));
            user.setUserRole(rs.getInt(\"userRole\"));
            user.setCreatedBy(rs.getInt(\"createdBy\"));
            user.setCreationDate(rs.getDate(\"creationDate\"));
            user.setModifyBy(rs.getInt(\"modifyBy\"));
            user.setModifyDate(rs.getDate(\"modifyDate\"));

            userList.add(user);
        }
    }catch(Exception e){
        e.printStackTrace();
    }finally {
        releaseResource(conn,pstmt,rs);
    }

    return userList;
}

角色列表查询省略;

不过如果角色列表有更改需要重置session域中的角色列表集合数据

3.5 分页跳转

  1. 点击分页跳转按钮,或者 切换分页条件排序条件
  2. 将切换以后的分页参数,放到 表单的隐藏input中
  3. $(\"#searchForm\").submit(); 提交表单即可;(每个页面的表单各自提交,分页部分Javascript就可以复用)

3.5.1 分页html

<div class=\"page-bar\">
    <ul class=\"page-num-ul clearfix\">
        <li>共&nbsp;${pageSupport.totalCount}&nbsp;条记录
            &nbsp;<span id=\"currPageNo\">${pageSupport.currPageNo}</span>&nbsp;
            /
            &nbsp;<span id=\"totalPage\">${pageSupport.totalPage}</span>&nbsp;页</li>&nbsp;&nbsp;
        <a href=\"javaScript:void(0);\" >首页</a>
        <a href=\"javaScript:void(0);\" >上一页</a>
        <a href=\"javaScript:void(0);\" >下一页</a>
        <a href=\"javaScript:void(0);\" >最后一页</a>
        &nbsp;&nbsp;	每页<select name=\"currentPageSize\" id=\"currentPageSize\">
        <option value=\"3\" <c:if test=\"${pageSupport.pageSize == 3 }\" > selected </c:if>>3</option>
    <option value=\"5\" <c:if test=\"${pageSupport.pageSize == 5 }\" > selected </c:if>>5</option>
<option value=\"10\" <c:if test=\"${pageSupport.pageSize == 10 }\" > selected </c:if>>10</option>
</select>条
根据<select name=\"currentOrderBy\" id=\"currentOrderBy\">
    <option value=\"id\" <c:if test=\"${pageSupport.orderBy == \'id\' }\" > selected </c:if>> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;id </option>
<option value=\"creationDate\" <c:if test=\"${pageSupport.orderBy == \'creationDate\' }\" > selected </c:if>>创建时间</option>
</select>
<select name=\"currentAscOrDesc\" id=\"currentAscOrDesc\">
    <option value=\"asc\" <c:if test=\"${pageSupport.ascOrDesc == \'asc\' }\" > selected </c:if>>升序</option>
<option value=\"desc\" <c:if test=\"${pageSupport.ascOrDesc == \'desc\' }\" > selected </c:if>>降序</option>
</select>查询
</ul>
<span class=\"page-go-form\"><label>跳转至</label>
    <input type=\"text\" name=\"inputPage\" id=\"inputPage\" class=\"page-key\" />页
    <button type=\"button\" class=\"page-btn\" >GO</button>
</span>
</div> 

3.5.2 页面跳转处理

首页,上一页,下一页,尾页,及上一页和下一页隐藏

//分页跳转
//首页
$(\".page-num-ul  a:eq(0)\").click(function(){
    //获取id为pageNo的input标签,并给value属性赋值
    // $(\"#pageNo\").val(1);
    //获取表单,并给表单name为pageNo的input标签赋值
    document.forms[0].pageNo.value = 1;
    $(\"#searchForm\").submit();
});

// 上一页
$(\".page-num-ul  a:eq(1)\").click(function(){
    // $(\"#pageNo\").val(parseInt($(\"#currPageNo\").text()) - 1);
    document.forms[0].pageNo.value = parseInt($(\"#currPageNo\").text()) - 1;
    $(\"#searchForm\").submit();
});


// 下一页
$(\".page-num-ul  a:eq(2)\").click(function(){
    // $(\"#pageNo\").val(parseInt($(\"#currPageNo\").text()) + 1);
    document.forms[0].pageNo.value = parseInt($(\"#currPageNo\").text()) + 1;
    $(\"#searchForm\").submit();
});

// 尾页
$(\".page-num-ul  a:eq(3)\").click(function(){
    // $(\"#pageNo\").val(parseInt($(\"#totalPage\").text()));
    document.forms[0].pageNo.value = parseInt($(\"#totalPage\").text());
    $(\"#searchForm\").submit();
});

//上一页,下一页隐藏处理
//上一页
if($(\"#currPageNo\").text() == \"1\"){
    //alert($(\"#currPageNo\").text());
    $(\".page-num-ul  a:eq(1)\").hide();
}else {
    $(\".page-num-ul  a:eq(2)\").show();
}

//下一页
if($(\"#currPageNo\").text() == $(\"#totalPage\").text()){
    //alert($(\"#currPageNo\").text());
    $(\".page-num-ul  a:eq(2)\").hide();
    						//.css(\"display\",\"none\");
}else {
    //alert($(\"#currPageNo\").text());
    $(\".page-num-ul  a:eq(2)\").show();
    						//.css(\"display\",\"inline\");
}

//跳到指定页数
$(\".page-btn\").click(function () {
    var $inputPage = $(\"#inputPage\");
    if($inputPage.val() < 0  || $inputPage.val() > parseInt($(\"#totalPage\").text())){
        alert(\"请输入正确的页数!!!\");
    }else{
        //修改表单中的当前页
        // $(\"#pageNo\").val($inputPage.val());
        document.forms[0].pageNo.value = $inputPage.val();
        $(\"#searchForm\").submit();
    }
});

3.5.3 修改分页条件,或排序条件

select的$(\"#selected\").change(function(){});

切换select选项触发change事件

修改每页页面大小

//修改每页页面大小 重新查询
$(\"#currentPageSize\").change(function(){
    //获取修改后的 currentPageSize
    var currentPageSize = $(this).children(\'option:selected\').val();
    //alert(currentPageSize);
    //修改提交表单的pageSize
    // $(\"#pageSize\").val(currentPageSize);
    document.forms[0].pageSize.value = currentPageSize;
    //修改页面大小后,再主动查询一次动漫数据
    //将当前页数,重置为1
    // $(\"#pageNo\").val(1);
    document.forms[0].pageNo = 1;
    $(\"#searchForm\").submit();
});

修改查询条件

//修改查询条件
$(\"#currentOrderBy\").change(function(){
    //获取修改后的 currentOrderBy
    var currentOrderBy = $(this).children(\'option:selected\').val();
    //修改提交表单的orderBy
    // $(\"#orderBy\").val(currentOrderBy);
    document.forms[0].orderBy.value =  currentOrderBy;
    //修改页面大小后,再主动查询一次动漫数据
    //将当前页数,重置为1
    // $(\"#pageNo\").val(1);
    document.forms[0].pageNo.value = 1;
    $(\"#searchForm\").submit();
});

修改升序或降序

//升序或降序
$(\"#currentAscOrDesc\").change(function(){
    //获取修改后的 currentAscOrDesc
    var currentAscOrDesc = $(this).children(\'option:selected\').val();
    //修改提交表单的orderBy
    // $(\"#ascOrDesc\").val(currentAscOrDesc);
    document.forms[0].ascOrDesc.value = currentAscOrDesc;
    //修改页面大小后,再主动查询一次动漫数据
    //将当前页数,重置为1
    // $(\"#pageNo\").val(1);
    document.forms[0].pageNo.value = 1;
    $(\"#searchForm\").submit();
});

4、查看详情

  1. 携带用户id跳转到用户详情请求
  2. 根据用户id查询到用户信息
  3. 存放在request域中
  4. 转发到用户详情页面
  5. EL表达式取出用户数据

查看详情a标签

<a class=\"viewUser\"   href=\"${pageContext.request.contextPath }/userServlet?method=userInfo&id=${user.id}\" > 查看用户详情

5、修改用户

  1. 携带用户id用户修改请求
  2. 根据id查询出用户信息
  3. 存放到request域中
  4. 转发到用户修改页面
  5. EL表达式取出用户数据(注意隐藏用户id)

用户修改a标签

<a class=\"modifyUser\" href=\"${pageContext.request.contextPath }/userServlet?method=toUserMod&id=${user.id}\">修改用户
  1. 修改完数据,表单提交到用户修改请求
  2. 用户信息修改成功后跳转到用户条件分页查询请求,重新查询数据

用户修改页面的form表单请求

 <form id=\"userForm\" name=\"userForm\" method=\"post\" action=\"${pageContext.request.contextPath}/userServlet?method=userMod\">

6、删除用户

  1. 携带用户id用户删除请求
  2. 删除成功后,跳转到用户条件分页查询请求,重新查询数据
<a class=\"deleteUser\" href=\"${pageContext.request.contextPath }/userServlet?method=userDel&id=${user.id}\"  onClick=\"return confirm(\'是否确认删除${user.userName}用户\')\" >

7、增加用户

  1. 跳转到用户添加页面
  2. 填写用户信息
  3. 表单提交到用户添加请求
  4. 添加完用户后,跳转到用户条件分页查询请求,重新查询数据

添加用户a标签

 <a href=\"${pageContext.request.contextPath}/jsp/useradd.jsp\" >添加用户</a>

用户添加页面的用户添加请求表单

 <form id=\"userForm\" name=\"userForm\" method=\"post\" action=\"${pageContext.request.contextPath }/userServlet?method=userAdd\">

8、修改用户密码

  1. 校验两次用户输入的新密码是否一样
  2. 判断用户的旧密码是否正确(用户密码要从数据库中查询)
  3. 根据登录的id修改用户密码
  4. 修改成功,移除session中的登录用户对象
  5. 重定向到跳转到用户登录页面

9、注意点

9.1 tomcat项目启动不起来

注意看路径映射是否有问题;(有没有少写 \"/\")

9.2 css获取到,但是渲染有问题

报错信息:Resource interpreted as Stylesheet but transferred with MIME type text/html

字符编码拦截器单独对css文件的解析类型进行处理

 @Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    //设置post请求字符集  encoding为设置映射路径时,设置的初始化字符编码
    servletRequest.setCharacterEncoding(encoding);

    HttpServletRequest request = (HttpServletRequest) servletRequest;

    //静态资源放行
    //获取资源名
    String url=request.getRequestURI();
    //如果资源名包含css样式表、js样式表就特殊处理然后放行
    if(url.contains(\".css\")) {
        servletResponse.setContentType(\"text/css; charset=UTF-8\");
        servletResponse.setCharacterEncoding(this.encoding);
        System.out.println(\"css放行\");
        //放行请求
        filterChain.doFilter(servletRequest,servletResponse);
    }else {
        //设置响应字符集
        servletResponse.setContentType(\"text/html; charset=UTF-8\");
        servletResponse.setCharacterEncoding(this.encoding);

        //放行请求
        filterChain.doFilter(servletRequest,servletResponse);
    }

}

9.3 自动导包问题

有时候自动导包导致不是自己想要的包直接用全类名即可

主要会再使用@WebServlet 和 @WebFilter 注解后会出现这个问题

javax.servlet.http.HttpServlet

@WebServlet(name = \"userServlet\",urlPatterns = \"/userServlet\")
public class UserServlet extends javax.servlet.http.HttpServlet{......}

javax.servlet.Filter

@WebFilter(filterName = \"characterEncodingFilter\",urlPatterns = \"/*\",initParams = {
        @WebInitParam(name = \"encoding\",value = \"utf-8\")
})
//
public class CharacterEncodingFilter implements javax.servlet.Filter {......}

9.4 form表单提交 拼接路径问题

form表单的action拼接路径,注意再get提交方式不能拼接参数,在post提交方式可以

form表单提交方式 action是否可以拼接参数
get 不可以(实在要使用get就在input中隐藏,这样get和post都可以)
post 可以

get提交

get提交由于不能拼接参数,所以将method参数隐藏在表单中;

action=\"${pageContext.request.contextPath }/billServlet\"

<form id=\"searchForm\" method=\"get\" action=\"${pageContext.request.contextPath }/billServlet\">
  <input name=\"method\" type=\"hidden\" value=\"billList\">
   ......
</form>

post提交

post提交可以直接拼接参数,也可以将method参数隐藏在表单中;

action=\"${pageContext.request.contextPath }/billServlet?method=billList\"

<form id=\"searchForm\" method=\"post\" action=\"${pageContext.request.contextPath }/billServlet?method=billList\">
   ......
</form>

9.5转发和重定向到底要不要 + req.getContextPath()

9.5.1 req.getContextPath()

首先要知道 req.getContextPath() 获取到的是什么内容?

如果发布的项目路径为:/kh96_smbms

System.out.println(\" req.getContextPath()==》\"+req.getContextPath());
// req.getContextPath()==》 /kh96_smbms         注意它前面有 /,这个是重点

如果发布的项目名为:/

System.out.println(\" req.getContextPath()==》\"+req.getContextPath());
// req.getContextPath()==》         什么都没有,包括我们之前写发布名时的 / 也没有

知道 req.getContextPath() 获取的是什么我们就 恍然大悟了;

9.5.2 再看转发和重定向的路径区别

转发和重定向的路径区别

  • 重定向路径中如果有 \"/\",只会获取到 站点,然后拼接上我们写的路径;
  • 转发路径中如果有 \"/\",会先获取到 站点 + 项目名,再拼接上我们写的路径;

所以重定向:(前提自己写的路径前有 /)

  • 如果有项目名,我们一定要 加上 req.getContextPath(),获取到项目名,再拼接跳转的路径;

  • 如果没有项目名,我们加上或不加上,都可以

转发:(前提自己写的路径前有 /)

  • 如果有项目名,我们不能 加上 req.getContextPath(),如果加上会多拼接上一个项目名,而找不到路径;
  • 如果没有项目名,我们加上或不加上,都可以

总结:(前提自己写的路径前有 /)

  • 没有项目名,加不加 req.getContextPath() 都可以,不过建议加上
  • 有项目名:
    • 重定向一定要加req.getContextPath() ;
    • 转发一定不能加req.getContextPath() ;

10、sql的时间差函数

参考博客

用来计算时间的差距,年龄,距上一次登录多少天等等;

10.1 datediff()函数

只比较日期

DATEDIFF() 函数返回两个日期之间的天数。
date1 和 date2 参数是合法的日期或日期/时间表达式。 只有值的日期部分参与计算。

测试一下MySQL:

 SELECT DATEDIFF(\'2018-05-09 08:00:00\',\'2018-05-09\') AS DiffDate;
 //结果 0 ; 表示 2018-05-09 与 2018-05-09之间没有日期差。这里是不比较时分秒的。下面验证带上时分秒有没有差别。
 SELECT DATEDIFF(\'2018-05-09 00:00:00\',\'2018-05-09 23:59:59\') AS DiffDate;
 //结果 0 ;
 SELECT DATEDIFF(\'2018-05-08 23:59:59\',\'2018-05-09 00:00:00\') AS DiffDate;
 //结果 -1;
 SELECT DATEDIFF(\'2018-05-09 00:00:00\',\'2018-05-08 23:59:59\') AS DiffDate;
//结果 1;

10.2timestampdiff()

可以计算,年,月,日的差距;

select timestampdiff(YEAR,\"2018-01-01 15:15:16\",\"2019-08-23 15:15:16\") as timestamodiff;
//结果1。相差一年。
select timestampdiff(YEAR,\"2019-08-22 15:15:19\",\"2018-12-23 15:15:16\") as timestamodiff;
//结果 -1,也是相差一年。
select timestampdiff(YEAR,\"2019-08-22 15:15:19\",\"2018-08-22 15:15:16\") as timestamodiff; 
//结果0,相差不到一年

select timestampdiff(MONTH,\"2018-08-22 15:15:16\",\"2018-07-23 15:15:16\") as timestamodiff;
// 结果 0 相差不到一个月
select timestampdiff(MONTH,\"2018-08-22 15:15:16\",\"2018-07-01 15:15:16\") as timestamodiff;
// 结果 -1 相差一个月
select timestampdiff(MONTH,\"2018-08-22 15:15:19\",\"2018-09-23 15:15:16\") as timestamodiff; 
// 结果 1 想差一个月

select timestampdiff(DAY,\"2018-08-22 15:15:16\",\"2018-08-23 15:15:16\") as timestamodiff;
// 结果 1 想差一天
select timestampdiff(DAY,\"2018-08-22 15:15:19\",\"2018-08-23 15:15:16\") as timestamodiff;
// 结果 0 想差不到一天
select timestampdiff(DAY,\"2018-08-23 15:15:19\",\"2018-08-22 15:15:16\") as timestamodiff;
// 结果 -1 想差一天


来源:https://www.cnblogs.com/xiaoqigui/p/16594687.html
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » Javaweb09-请求跳转项目 分页条件查询 + 增删改 + 邮件登录

相关推荐

  • 暂无文章