本次项目主要有以下几个重点导入项目、优化servlet、前后台勾连等。

如图片所示,这是一个常见的网站首页,包括登录、注册、查看相关信息的功能。
但要怎么实现呢?
除了准备好相应的图片文字信息,我们要怎么做才能让它拥有以上功能并展示在页面上呢?
抱着这样的疑惑,我们慢慢来一探究竟吧?
后端:

还有要提前建立存放图片和文字资源的数据库。

这里我使用的是Navicat软件。

这是一款可视化建库软件,使用起来非常方便。
前端及资源文件:

看到pom.xml文件了吗?这表示 我是从maven导入的半成品项目,接下来我们来了解一下如何使用maven导入项目。
maven:Maven是一个跨平台的项目管理工具,是Apache组织中的一个颇为成功的开源项目。Maven主要服务基于java的项目构建,项目信息管理和依赖管理。
作用:
1.Maven可以创建项目。
2.Maven可以引入依赖的jar包。
在Maven中有一个核心的概念--仓库,分为本地仓库和远程仓库。远程仓库又分为中央仓库,私服和其他仓库。
首先是确保自己下载了maven的资源文件,并且IDE安装并启动了maven插件:
打开设置:


以上准备操作没有问题就会在右侧导航栏出现以下内容:

点击maven,出现以下内容:

点击“+”号,导入项目。

选择pom.xml文件,点击OK完成项目导入,初始化微微等待一会即可。
以下是pom.xml文件的内容,我们可以看到里面包含了诸多插件的信息,这是依赖管理:对jar包统一管理的过程
- "1.0" encoding="UTF-8"?>
-
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0modelVersion>
-
- <groupId>cn.itcastgroupId>
- <artifactId>travelartifactId>
- <version>1.0-SNAPSHOTversion>
- <packaging>warpackaging>
- <dependencies>
- <dependency>
- <groupId>junitgroupId>
- <artifactId>junitartifactId>
- <version>3.8.1version>
- <scope>testscope>
- dependency>
-
- <dependency>
- <groupId>javax.servletgroupId>
- <artifactId>javax.servlet-apiartifactId>
- <version>3.1.0version>
- <scope>providedscope>
- dependency>
-
-
-
- <dependency>
- <groupId>mysqlgroupId>
- <artifactId>mysql-connector-javaartifactId>
- <version>5.1.26version>
- <scope>compilescope>
- dependency>
-
- <dependency>
- <groupId>com.alibabagroupId>
- <artifactId>druidartifactId>
- <version>1.0.9version>
- dependency>
-
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-coreartifactId>
- <version>4.1.2.RELEASEversion>
- <scope>compilescope>
- dependency>
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-jdbcartifactId>
- <version>4.1.2.RELEASEversion>
- <scope>compilescope>
- dependency>
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-txartifactId>
- <version>4.1.2.RELEASEversion>
- <scope>compilescope>
- dependency>
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-beansartifactId>
- <version>4.1.2.RELEASEversion>
- <scope>compilescope>
- dependency>
- <dependency>
- <groupId>commons-logginggroupId>
- <artifactId>commons-loggingartifactId>
- <version>1.1.1version>
- <scope>compilescope>
- dependency>
-
- <dependency>
- <groupId>commons-beanutilsgroupId>
- <artifactId>commons-beanutilsartifactId>
- <version>1.9.2version>
- <scope>compilescope>
- dependency>
-
- <dependency>
- <groupId>com.fasterxml.jackson.coregroupId>
- <artifactId>jackson-databindartifactId>
- <version>2.3.3version>
- dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.coregroupId>
- <artifactId>jackson-coreartifactId>
- <version>2.3.3version>
- dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.coregroupId>
- <artifactId>jackson-annotationsartifactId>
- <version>2.3.3version>
- dependency>
-
-
-
- <dependency>
- <groupId>javax.mailgroupId>
- <artifactId>javax.mail-apiartifactId>
- <version>1.5.6version>
- dependency>
- <dependency>
- <groupId>com.sun.mailgroupId>
- <artifactId>javax.mailartifactId>
- <version>1.5.3version>
- dependency>
-
- <dependency>
- <groupId>redis.clientsgroupId>
- <artifactId>jedisartifactId>
- <version>2.7.0version>
- dependency>
-
- dependencies>
-
-
- <build>
-
- <plugins>
-
- <plugin>
- <groupId>org.apache.maven.pluginsgroupId>
- <artifactId>maven-compiler-pluginartifactId>
- <configuration>
- <source>1.8source>
- <target>1.8target>
- <encoding>utf-8encoding>
- configuration>
- plugin>
-
- <plugin>
- <groupId>org.apache.tomcat.mavengroupId>
-
- <artifactId>tomcat7-maven-pluginartifactId>
- <version>2.1version>
- <configuration>
-
- <port>80port>
-
- <path>/path>
- configuration>
- plugin>
-
- plugins>
- build>
- project>
项目导入成功之后我们便要启动项目:
方式一:

启动Tomcat7:run;的命令
方式二:配置maven快捷启动


启动项目之后来分析一下每一层我们要做的事情:
现在我们手里已经有了一个前端页面后端实体类已经写好的网页,接下来要让它具备登录注册的功能。
页面效果:

前台代码设计:
- html>
- <html lang="en">
- <head>
- <meta charset="utf-8">
- <title>注册title>
- <link rel="stylesheet" type="text/css" href="css/common.css">
- <link rel="stylesheet" href="css/register.css">
-
- <script src="js/jquery-3.3.1.js">script>
-
- <script>
- /*
- 表单校验:
- 1.用户名:单词字符,长度8到20位
- 2.密码:单词字符,长度8到20位
- 3.email:邮件格式
- 4.姓名:非空
- 5.手机号:手机号格式
- 6.出生日期:非空
- 7.验证码:非空
- */
-
- //校验用户名
- //单词字符,长度4到20位
- function checkUsername() {
- //1.获取用户名值
- var username = $("#username").val();
- //2.定义正则
- var reg_username = /^\w{4,20}$/;
-
- //3.判断,给出提示信息
- var flag = reg_username.test(username);
- if(flag){
- //用户名合法
- $("#username").css("border","");
- }else{
- //用户名非法,加一个红色边框
- $("#username").css("border","1px solid red");
- }
-
- return flag;
- }
-
- //校验密码
- function checkPassword() {
- //1.获取密码值
- var password = $("#password").val();
- //2.定义正则
- var reg_password = /^\w{6,20}$/;
-
- //3.判断,给出提示信息
- var flag = reg_password.test(password);
- if(flag){
- //密码合法
- $("#password").css("border","");
- }else{
- //密码非法,加一个红色边框
- $("#password").css("border","1px solid red");
- }
-
- return flag;
- }
-
- //校验邮箱
- function checkEmail(){
- //1.获取邮箱
- var email = $("#email").val();
- //2.定义正则 itcast@163.com
- var reg_email = /^\w+@\w+\.\w+$/;
-
- //3.判断
- var flag = reg_email.test(email);
- if(flag){
- $("#email").css("border","");
- }else{
- $("#email").css("border","1px solid red");
- }
-
- return flag;
- }
- //校验姓名
- //非空单词字符,长度1到10位
- function checkName() {
- //1.获取姓名
- var name = $("#name").val();
- //2.定义姓名正则
- var reg_name = /^\w{1,10}$/;
-
- //3.判断,给出提示信息
- var flag = reg_name.test(name);
- if (name!=null){
- if(flag){
- //姓名合法
- $("#name").css("border","");
- }
-
- }else{
- //姓名非法,加一个红色边框
- $("#name").css("border","1px solid red");
- }
-
- return flag;
- }
- //校验手机号
- //非空单词字符,长度11位
- function checkPhoneNumber() {
- //1.获取用号码
- var number = $("#number").val();
- //2.定义11位手机号码正则
- var reg_number = /^[1][3,4,5,7,8][0-9]{9}$/;
-
- //3.判断,给出提示信息
- var flag = reg_number.test(number);
-
- if(flag){
- //号码合法
- $("#number").css("border","");
-
-
- }else{
- //号码非法,加一个红色边框
- $("#number").css("border","1px solid red");
- }
-
- return flag;
- }
- //校验生日
- function checkBirthday() {
- //1.获取生日
- var birthday = $("#birthday").val();
- //2.定义日期正则
- var reg_birthday =/^((?:19[2-9]\d{1})|(?:20(?:(?:0[0-9])|(?:1[0-8]))))\-((?:0?[1-9])|(?:1[0-2]))\-((?:0?[1-9])|(?:[1-2][0-9])|30|31)$/;
-
- //3.判断,给出提示信息
- var flag = reg_birthday.test(birthday);
-
- if(flag){
- //生日合法
- $("#birthday").css("border","");
-
-
- }else{
- //生日非法,加一个红色边框
- $("#birthday").css("border","1px solid red");
- }
-
- return flag;
- }
- //校验4位验证码authCode
- function checkAuthCode() {
- //1.获取密码值
- var authCode = $("#authCode").val();
- //2.定义正则
- var reg_authCode = /^\w{4}$/;
-
- //3.判断,给出提示信息
- var flag = reg_authCode.test(authCode);
- if(flag){
- //密码合法
- $("#authCode").css("border","");
- }else{
- //密码非法,加一个红色边框
- $("#authCode").css("border","1px solid red");
- }
-
- return flag;
- }
-
-
- $(function () {
- //当表单提交时,调用所有的校验方法
- $("#registerForm").submit(function(){
- //1.发送数据到服务器
- if(checkUsername() && checkPassword() && checkEmail()){
- //校验通过,发送ajax请求,提交表单的数据 username=zhangsan&password=123
-
- $.post("user/regist",$(this).serialize(),function(data){
- //处理服务器响应的数据 data {flag:true,errorMsg:"注册失败"}
-
- if(data.flag){
- //注册成功,跳转成功页面
- location.href="register_ok.html";
- }else{
- //注册失败,给errorMsg添加提示信息
- $("#errorMsg").html(data.errorMsg);
-
- }
- });
-
- }
- //2.不让页面跳转
- return false;
- //如果这个方法没有返回值,或者返回为true,则表单提交,如果返回为false,则表单不提交
- });
-
- //当某一个组件失去焦点是,调用对应的校验方法
- $("#username").blur(checkUsername);
- $("#password").blur(checkPassword);
- $("#email").blur(checkEmail);
- $("#name").blur(checkName);
- $("#number").blur(checkPhoneNumber);
- $("#birthday").blur(checkBirthday);
- $("#authCode").blur(changeCheckCode);
-
-
- });
-
-
- script>
-
-
- head>
- <body>
-
- <div id="header">div>
-
- <div class="rg_layout">
- <div class="rg_form clearfix">
- <div class="rg_form_left">
- <p>新用户注册p>
- <p>USER REGISTERp>
- div>
- <div class="rg_form_center">
- <div id="errorMsg" style="color:red;text-align: center">div>
-
- <form id="registerForm" action="user">
-
- <input type="hidden" name="action" value="register">
- <table style="margin-top: 25px;">
- <tr>
- <td class="td_left">
- <label for="username">用户名label>
- td>
- <td class="td_right">
- <input type="text" id="username" name="username" placeholder="请输入4-20位账号">
- td>
- tr>
- <tr>
- <td class="td_left">
- <label for="password">密码label>
- td>
- <td class="td_right">
- <input type="text" id="password" name="password" placeholder="请输入6-10位密码">
- td>
- tr>
- <tr>
- <td class="td_left">
- <label for="email">Emaillabel>
- td>
- <td class="td_right">
- <input type="text" id="email" name="email" placeholder="请输入Email">
- td>
- tr>
- <tr>
- <td class="td_left">
- <label for="name">姓名label>
- td>
- <td class="td_right">
- <input type="text" id="name" name="name" placeholder="请输入真实姓名">
- td>
- tr>
- <tr>
- <td class="td_left">
- <label for="telephone">手机号label>
- td>
- <td class="td_right">
- <input type="text" id="telephone" name="telephone" placeholder="请输入您的11位手机号">
- td>
- tr>
- <tr>
- <td class="td_left">
- <label for="sex">性别label>
- td>
- <td class="td_right gender">
- <input type="radio" id="sex" name="sex" value="男" checked> 男
- <input type="radio" name="sex" value="女"> 女
- td>
- tr>
- <tr>
- <td class="td_left">
- <label for="birthday">出生日期label>
- td>
- <td class="td_right">
- <input type="date" id="birthday" name="birthday" placeholder="年/月/日">
- td>
- tr>
- <tr>
- <td class="td_left">
- <label for="check">验证码label>
- td>
- <td class="td_right check">
- <input type="text" id="check" name="check" class="check">
- <img src="checkCode" height="32px" alt="" onclick="changeCheckCode(this)">
- <script type="text/javascript">
- //图片点击事件
- function changeCheckCode(img) {
- img.src="checkCode?"+new Date().getTime();
- }
- script>
- td>
- tr>
- <tr>
- <td class="td_left">
- td>
- <td class="td_right check">
- <input type="submit" class="submit" value="注册">
- <span id="msg" style="color: red;">span>
- td>
- tr>
- table>
- form>
- div>
- <div class="rg_form_right">
- <p>
- 已有账号?
- <a href="#">立即登录a>
- p>
- div>
- div>
- div>
-
- <div id="footer">div>
-
- <script type="text/javascript" src="js/include.js">script>
-
- body>
- html>

- package cn.itcast.travel.web.servlet;
-
- import cn.itcast.travel.domain.ResultInfo;
- import cn.itcast.travel.domain.User;
- import cn.itcast.travel.service.UserService;
- import cn.itcast.travel.service.impl.UserServiceImpl;
- import cn.itcast.travel.service.impl.routeServiceImpl;
- import cn.itcast.travel.service.routeService;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import org.apache.commons.beanutils.BeanUtils;
-
- 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 javax.servlet.http.HttpSession;
- import java.io.IOException;
- import java.lang.reflect.InvocationTargetException;
- import java.util.Map;
-
- @WebServlet("/registUserServlet")
- public class RegistUserServlet extends HttpServlet {
-
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-
-
- //验证校验
- String check = request.getParameter("check");
- //从sesion中获取验证码
- HttpSession session = request.getSession();
- String checkcode_server = (String) session.getAttribute("CHECKCODE_SERVER");
- session.removeAttribute("CHECKCODE_SERVER");//为了保证验证码只能使用一次
- //比较
- if(checkcode_server == null || !checkcode_server.equalsIgnoreCase(check)){
- //验证码错误
- ResultInfo info = new ResultInfo();
- //注册失败
- info.setFlag(false);
- info.setErrorMsg("验证码错误");
- //将info对象序列化为json
- ObjectMapper mapper = new ObjectMapper();
- String json = mapper.writeValueAsString(info);
- response.setContentType("application/json;charset=utf-8");
- response.getWriter().write(json);
- return;
- }
-
- //1.获取数据
- Map
map = request.getParameterMap(); -
- //2.封装对象
- User user = new User();
- try {
- BeanUtils.populate(user,map);
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- }
- System.out.println(user);
-
- //3.调用service完成注册
- UserService service = new UserServiceImpl();
- boolean flag = service.regist(user);
- ResultInfo info = new ResultInfo();
- //4.响应结果
- if(flag){
- //注册成功
- info.setFlag(true);
- }else{
- //注册失败
- info.setFlag(false);
- info.setErrorMsg("注册失败!");
- }
-
- //将info对象序列化为json
- ObjectMapper mapper = new ObjectMapper();
- String json = mapper.writeValueAsString(info);
-
- //将json数据写回客户端
- //设置content-type
- response.setContentType("application/json;charset=utf-8");
- response.getWriter().write(json);
-
-
- }
-
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- this.doPost(request, response);
- }
- }
有了请求信息,我们现在要做的就是做可注册用户的校验和存入注册信息到数据库。

- public class UserServiceImpl implements UserService {
-
- private UserDao userDao = new UserDaoImpl();
- /**
- * 注册用户
- * @param user
- * @return
- */
- @Override
- public boolean regist(User user) {
- //1.根据用户名查询用户对象
- User u = userDao.findByUsername(user.getUsername());
- //判断u是否为null
- if(u != null){
- //用户名存在,注册失败
- return false;
- }
- //2.保存用户信息
- userDao.save(user);
- return true;
- }
userDao:

- public class UserDaoImpl implements UserDao {
-
- private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
-
- @Override
- public User findByUsername(String username) {
- User user = null;
- try {
- //1.定义sql
- String sql = "select * from tab_user where username = ?";
- //2.执行sql
- user = template.queryForObject(sql, new BeanPropertyRowMapper
(User.class), username); - } catch (Exception e) {
-
- }
-
- return user;
- }
-
- @Override
- public void save(User user) {
- //1.定义sql
- String sql = "insert into tab_user(username,password,name,birthday,sex,telephone,email,status,code) values(?,?,?,?,?,?,?,?,?)";
- //2.执行sql
-
- template.update(sql,user.getUsername(),
- user.getPassword(),
- user.getName(),
- user.getBirthday(),
- user.getSex(),
- user.getTelephone(),
- user.getEmail(),
- user.getStatus(),
- user.getCode()
- );
- }
- }
完成这个功能之后我们需要激活账户。
现在常用的方法是通过邮件验证激活。
具体操作如下:

MailUtils:
- package cn.itcast.travel.util;
-
- import javax.mail.*;
- import javax.mail.internet.InternetAddress;
- import javax.mail.internet.MimeMessage;
- import java.util.Properties;
-
- /**
- * 发邮件工具类
- */
- public final class MailUtils {
- private static final String USER = "********@qq.com"; // 发件人称号,同邮箱地址
- private static final String PASSWORD = "**********"; // 如果是qq邮箱可填写户端授权码,或者登录密码
-
- /**
- *
- * @param to 收件人邮箱
- * @param text 邮件正文
- * @param title 标题
- */
- /* 发送验证信息的邮件 */
- public static boolean sendMail(String to, String text, String title){
- try {
- final Properties props = new Properties();
- props.put("mail.smtp.auth", "true");
- props.put("mail.smtp.host", "smtp.qq.com");
-
- // 发件人的账号
- props.put("mail.user", USER);
- //发件人的密码
- props.put("mail.password", PASSWORD);
-
- // 构建授权信息,用于进行SMTP进行身份验证
- Authenticator authenticator = new Authenticator() {
- @Override
- protected PasswordAuthentication getPasswordAuthentication() {
- // 用户名、密码
- String userName = props.getProperty("mail.user");
- String password = props.getProperty("mail.password");
- return new PasswordAuthentication(userName, password);
- }
- };
- // 使用环境属性和授权信息,创建邮件会话
- Session mailSession = Session.getInstance(props, authenticator);
- // 创建邮件消息
- MimeMessage message = new MimeMessage(mailSession);
- // 设置发件人
- String username = props.getProperty("mail.user");
- InternetAddress form = new InternetAddress(username);
- message.setFrom(form);
-
- // 设置收件人
- InternetAddress toAddress = new InternetAddress(to);
- message.setRecipient(Message.RecipientType.TO, toAddress);
-
- // 设置邮件标题
- message.setSubject(title);
-
- // 设置邮件的内容体
- message.setContent(text, "text/html;charset=UTF-8");
- // 发送邮件
- Transport.send(message);
- return true;
- }catch (Exception e){
- e.printStackTrace();
- }
- return false;
- }
-
- public static void main(String[] args) { // 做测试用
- MailUtils.sendMail("2621247177@qq.com","你好,这是一封测试邮件,无需回复。","测试邮件");
- System.out.println("发送成功");
- }
-
-
-
- }

修改保存Dao代码,加上存储status和code 的代码逻辑:

激活代码实现:
ActiveUserServlet:
- package cn.itcast.travel.web.servlet;
-
- import cn.itcast.travel.service.UserService;
- import cn.itcast.travel.service.impl.UserServiceImpl;
-
- 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;
-
- @WebServlet("/activeUserServlet")
- public class ActiveUserServlet extends HttpServlet {
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- //1.获取激活码
- String code = request.getParameter("code");
- if(code != null){
- //2.调用service完成激活
- UserService service = new UserServiceImpl();
- boolean flag = service.active(code);
-
- //3.判断标记
- String msg = null;
- if(flag){
- //激活成功
- msg = "激活成功,请登录";
- }else{
- //激活失败
- msg = "激活失败,请联系管理员!";
- }
- response.setContentType("text/html;charset=utf-8");
- response.getWriter().write(msg);
- }
-
- }
-
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- this.doPost(request, response);
- }
- }

- /**
- * 激活用户
- * @param code
- * @return
- */
- @Override
- public boolean active(String code) {
- //1.根据激活码查询用户对象
- User user = userDao.findByCode(code);
- if(user != null){
- //2.调用dao的修改激活状态的方法
- userDao.updateStatus(user);
- return true;
- }else{
- return false;
- }
-
-
-
- }
userDao:之后会有相同的流程,为了便捷,接口部分将省略不写,对三层架构有了解的小伙伴应该对这个流程轻车熟路了。

userDaoImpl:
- /**
- * 根据激活码查询用户对象
- * @param code
- * @return
- */
- @Override
- public User findByCode(String code) {
- User user = null;
- try {
- String sql = "select * from tab_user where code = ?";
-
- user = template.queryForObject(sql,new BeanPropertyRowMapper
(User.class),code); - } catch (DataAccessException e) {
- e.printStackTrace();
- }
-
- return user;
- }
-
- /**
- * 修改指定用户激活状态
- * @param user
- */
- @Override
- public void updateStatus(User user) {
- String sql = " update tab_user set status = 'Y' where uid=?";
- template.update(sql,user.getUid());
- }
登录功能的实现:
前台代码:
login.html

-
- "utf-8">
- "X-UA-Compatible" content="IE=edge">
- "viewport" content="width=device-width, initial-scale=1">
-
黑马旅游网-登录 - "stylesheet" type="text/css" href="css/common.css">
- "stylesheet" type="text/css" href="css/login.css">
-
-
-
-
-
-
-
-
- $(function () {
- //1.给登录按钮绑定单击事件
- $("#btn_sub").click(function () {
- //2.发送ajax请求,提交表单数据
- $.post("user/login",$("#loginForm").serialize(),function (data) {
- //data : {flag:false,errorMsg:''}
- if(data.flag){
- //登录成功
- location.href="index.html";
- }else{
- //登录失败
- $("#errorMsg").html(data.errorMsg);
- }
- });
- });
- });
- //3.处理响应结果
-
-
-
-
-
-
-
-
-

- 欢迎登录黑马旅游账户
-
-
-
-
-
-
-
-
-
-
-
-

-
- //图片点击事件
- function changeCheckCode(img) {
- img.src="checkCode?"+new Date().getTime();
- }
-
-
-
-
-
-
- 自动登录
-
-
-
- 没有账户?立即注册
-
-
-
-
-
-
-
-
-
-
-
-
后台代码:
LoginServlet
//1.获取用户名和密码数据
Map map = request.getParameterMap();
//2.封装User对象
User user = new User();
try {
BeanUtils.populate(user,map);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
//3.调用Service查询
UserService service = new UserServiceImpl();
User u = service.login(user);
ResultInfo info = new ResultInfo();
//4.判断用户对象是否为null
if(u == null){
//用户名密码或错误
info.setFlag(false);
info.setErrorMsg("用户名密码或错误");
}
//5.判断用户是否激活
if(u != null && !"Y".equals(u.getStatus())){
//用户尚未激活
info.setFlag(false);
info.setErrorMsg("您尚未激活,请激活");
}
//6.判断登录成功
if(u != null && "Y".equals(u.getStatus())){
//登录成功
info.setFlag(true);
}
//响应数据
ObjectMapper mapper = new ObjectMapper();
response.setContentType("application/json;charset=utf-8");
mapper.writeValue(response.getOutputStream(),info);
UserService
public User login(User user) {
return userDao.findByUsernameAndPassword(user.getUsername(),user.getPassword());
}
UserDao
public User findByUsernameAndPassword(String username, String password) {
User user = null;
try {
//1.定义sql
String sql = "select * from tab_user where username = ? and password = ?";
//2.执行sql
user = template.queryForObject(sql, new BeanPropertyRowMapper(User. class), username,password);
} catch (Exception e) {
}
return user;
}
细节优化提示交给小伙伴自己完成。
减少Servlet的数量,现在是一个功能一个Servlet,将其优化为一个模块一个Servlet,相当于在数据库中一张表对应一个Servlet,在Servlet中提供不同的方法,完成用户的请求。

通过继承实现:
BaseServlet编写:
- //9.2 BaseServlet编写:
-
- public class BaseServlet extends HttpServlet {
-
-
- @Override
- protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- //System.out.println("baseServlet的service方法被执行了...");
-
- //完成方法分发
- //1.获取请求路径
- String uri = req.getRequestURI(); // /travel/user/add
- System.out.println("请求uri:"+uri);// /travel/user/add
- //2.获取方法名称
- String methodName = uri.substring(uri.lastIndexOf('/') + 1);
- System.out.println("方法名称:"+methodName);
- //3.获取方法对象Method
- //谁调用我?我代表谁
- System.out.println(this);//UserServlet的对象cn.itcast.travel.web.servlet.UserServlet@4903d97e
- try {
- //获取方法
- Method method = this.getClass().getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
- //4.执行方法
- //暴力反射
- //method.setAccessible(true);
- method.invoke(this,req,resp);
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- }
-
-
- }
- }
-
将之前的Servlet实现的功能,抽取到UserServlet中的不同方法中实现,并且将UserService创建抽取到成员变量位置
-
- @WebServlet("/user/*") // /user/add /user/find
- public class UserServlet extends BaseServlet {
-
- //声明UserService业务对象
- private UserService service = new UserServiceImpl();
-
- /**
- * 注册功能
- * @param request
- * @param response
- * @throws ServletException
- * @throws IOException
- */
- public void regist(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-
- //验证校验
- String check = request.getParameter("check");
- //从sesion中获取验证码
- HttpSession session = request.getSession();
- String checkcode_server = (String) session.getAttribute("CHECKCODE_SERVER");
- session.removeAttribute("CHECKCODE_SERVER");//为了保证验证码只能使用一次
- //比较
- if(checkcode_server == null || !checkcode_server.equalsIgnoreCase(check)){
- //验证码错误
- ResultInfo info = new ResultInfo();
- //注册失败
- info.setFlag(false);
- info.setErrorMsg("验证码错误");
- //将info对象序列化为json
- ObjectMapper mapper = new ObjectMapper();
- String json = mapper.writeValueAsString(info);
- response.setContentType("application/json;charset=utf-8");
- response.getWriter().write(json);
- return;
- }
-
- //1.获取数据
- Map
map = request.getParameterMap(); -
- //2.封装对象
- User user = new User();
- try {
- BeanUtils.populate(user,map);
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- }
-
- //3.调用service完成注册
- //UserService service = new UserServiceImpl();
- boolean flag = service.regist(user);
- ResultInfo info = new ResultInfo();
- //4.响应结果
- if(flag){
- //注册成功
- info.setFlag(true);
- }else{
- //注册失败
- info.setFlag(false);
- info.setErrorMsg("注册失败!");
- }
-
- //将info对象序列化为json
- ObjectMapper mapper = new ObjectMapper();
- String json = mapper.writeValueAsString(info);
-
- //将json数据写回客户端
- //设置content-type
- response.setContentType("application/json;charset=utf-8");
- response.getWriter().write(json);
-
- }
-
- /**
- * 登录功能
- * @param request
- * @param response
- * @throws ServletException
- * @throws IOException
- */
- public void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- //1.获取用户名和密码数据
- Map
map = request.getParameterMap(); - //2.封装User对象
- User user = new User();
- try {
- BeanUtils.populate(user,map);
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- }
-
- //3.调用Service查询
- // UserService service = new UserServiceImpl();
- User u = service.login(user);
-
- ResultInfo info = new ResultInfo();
-
- //4.判断用户对象是否为null
- if(u == null){
- //用户名密码或错误
- info.setFlag(false);
- info.setErrorMsg("用户名密码或错误");
- }
- //5.判断用户是否激活
- if(u != null && !"Y".equals(u.getStatus())){
- //用户尚未激活
- info.setFlag(false);
- info.setErrorMsg("您尚未激活,请激活");
- }
- //6.判断登录成功
- if(u != null && "Y".equals(u.getStatus())){
- request.getSession().setAttribute("user",u);//登录成功标记
-
- //登录成功
- info.setFlag(true);
- }
-
- //响应数据
- ObjectMapper mapper = new ObjectMapper();
-
- response.setContentType("application/json;charset=utf-8");
- mapper.writeValue(response.getOutputStream(),info);
- }
-
- /**
- * 查询单个对象
- * @param request
- * @param response
- * @throws ServletException
- * @throws IOException
- */
- public void findOne(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- //从session中获取登录用户
- Object user = request.getSession().getAttribute("user");
- //将user写回客户端
-
- ObjectMapper mapper = new ObjectMapper();
- response.setContentType("application/json;charset=utf-8");
- mapper.writeValue(response.getOutputStream(),user);
- }
-
- /**
- * 退出功能
- * @param request
- * @param response
- * @throws ServletException
- * @throws IOException
- */
- public void exit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- //1.销毁session
- request.getSession().invalidate();
-
- //2.跳转登录页面
- response.sendRedirect(request.getContextPath()+"/login.html");
- }
-
- /**
- * 激活功能
- * @param request
- * @param response
- * @throws ServletException
- * @throws IOException
- */
- public void active(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- //1.获取激活码
- String code = request.getParameter("code");
- if(code != null){
- //2.调用service完成激活
- //UserService service = new UserServiceImpl();
- boolean flag = service.active(code);
-
- //3.判断标记
- String msg = null;
- if(flag){
- //激活成功
- msg = "激活成功,请登录";
- }else{
- //激活失败
- msg = "激活失败,请联系管理员!";
- }
- response.setContentType("text/html;charset=utf-8");
- response.getWriter().write(msg);
- }
- }
- }
后端代码完成这个功能十分简单,麻烦的是前端代码的分页显示设置。
以下代码是优化缓存之后的版本,启动redis服务,第一次从数据库中获取数据,并保存在缓存中,之后每次访问都从缓存中查询,提高效率节约资源。
- public class CategoryServiceImpl implements CategoryService {
- private categoryDao categoryDao=new categoryDaoImpl();
- @Override
- public List
findAll() { - //1.从redis中查询
- Jedis jedis = JedisUtil.getJedis();
- //1.1使查询的结果有顺序使用sortedset
- List
cs=null; - // Set
categorys = jedis.zrange("category", 0, -1); - Set
categorys = jedis.zrangeWithScores("category", 0, -1); - //2.获取jedis客户端
- //3.如果为空从数据库查询,不为空在redis中查询
- if (categorys==null||categorys.size()==0){
- System.out.println("从数据库中查询。。。");
- cs=categoryDao.findAll();
- //将集合数据存储到redis;
- for (int i = 0; i
- jedis.zadd("category",cs.get(i).getCid(),cs.get(i).getCname());
-
- }
-
- }else {
- System.out.println("从缓存中查询。。。");
- //如果不为空,将set集合数据存入list
- cs=new ArrayList
(); - for (Tuple tuple : categorys) {
- Category category=new Category();
- category.setCname(tuple.getElement());
- category.setCid((int)tuple.getScore());
- cs.add(category);
-
- }
- }
-
-
- return cs;
- }
- }
CategoryServlet:
- package cn.itcast.travel.web.servlet;
-
- import cn.itcast.travel.domain.Category;
- import cn.itcast.travel.service.CategoryService;
- import cn.itcast.travel.service.impl.CategoryServiceImpl;
- import com.fasterxml.jackson.databind.ObjectMapper;
-
- 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.util.List;
-
- @WebServlet("/category/*")
- public class CategoryServlet extends BaseServlet {
- private CategoryService service=new CategoryServiceImpl();
- /**
- * 查询所有
- * @param request
- * @param response
- * @throws ServletException
- * @throws IOException
- */
- public void findAll(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- //1.查询所有
- List
cs=service.findAll(); - // //2.序列化返回
- // ObjectMapper mapper=new ObjectMapper();
- // response.setContentType("application/json;charset=utf-8");
- // mapper.writeValue(response.getOutputStream(),cs);
- writeValue(cs,response);
-
-
-
- }
-
- public void find(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-
- }
- }
CategoryDao:
-
- public class CategoryDaoImpl implements CategoryDao {
-
- private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
-
- @Override
- public List
findAll() { - String sql = "select * from tab_category ";
- return template.query(sql,new BeanPropertyRowMapper
(Category.class)); - }
- }
在BaseServlet中封装了序列化json的方法
/**
* 直接将传入的对象序列化为json,并且写回客户端
* @param obj
*/
public void writeValue(Object obj,HttpServletResponse response) throws IOException {
ObjectMapper mapper = new ObjectMapper();
response.setContentType("application/json;charset=utf-8");
mapper.writeValue(response.getOutputStream(),obj);
}
/**
* 将传入的对象序列化为json,返回
* @param obj
* @return
*/
public String writeValueAsString(Object obj) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(obj);
}
之后根据需要调用即可。
之后是最麻烦的前台代码:麻烦的点在于分页处理,需要设置分页信息展示:
后端别忘记了创建分页展示使用到的实体类:

pageBean内容:
- package cn.itcast.travel.domain;
-
- import java.util.List;
-
- public class PageBean
{ - private int totalCount;//总记录数
- private int totalPage;//总页数
- private int currentPage;//当前页码
- private int pageSize;//每页显示的条数
- private List
list;//每页显示的数据集合 -
- public int getTotalCount() {
- return totalCount;
- }
-
- public void setTotalCount(int totalCount) {
- this.totalCount = totalCount;
- }
-
- public int getTotalPage() {
- return totalPage;
- }
-
- public void setTotalPage(int totalPage) {
- this.totalPage = totalPage;
- }
-
- public int getCurrentPage() {
- return currentPage;
- }
-
- public void setCurrentPage(int currentPage) {
- this.currentPage = currentPage;
- }
-
- public int getPageSize() {
- return pageSize;
- }
-
- public void setPageSize(int pageSize) {
- this.pageSize = pageSize;
- }
-
- public List
getList() { - return list;
- }
-
- public void setList(List
list) { - this.list = list;
- }
- }
- html>
- <html lang="en">
-
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>黑马旅游-搜索title>
- <link rel="stylesheet" type="text/css" href="css/common.css">
- <link rel="stylesheet" href="css/search.css">
- <script src="js/jquery-3.3.1.js">script>
- <script src="js/getParameter.js">
- script>
- <script>
- $(function () {
- var search = location.search;
- // alert(search);
- //获取切割字符串,拿到第二个值
- // var cid = search.split("=")[1];
- var cid = getParameter("cid");
- var rname = getParameter("rname");
- if (rname){
- rname=window.decodeURIComponent(rname);
- }
-
- //当页面加载完成后,调用load1方法发送ajax请求加载数据
- load1(cid,null,rname);
-
-
- });
- function load1(cid,currentPage,rname) {
- //发送ajax请求,请求route/pageQuery,传递cid
- $.get("/route/pageQuery",{cid:cid,currentPage:currentPage,rname:rname},function (pb) {
- $("#totalPage").html(pb.totalPage);
- $("#totalCount").html(pb.totalCount);
- /**
- * <li><a href="">首页a>li>
- <li class="threeword"><a href="#">上一页a>li>
- <li><a href="#">1a>li>
- <li><a href="#">2a>li>
- <li><a href="#">3a>li>
- <li><a href="#">4a>li>
- <li><a href="#">5a>li>
- <li><a href="#">6a>li>
- <li><a href="#">7a>li>
- <li><a href="#">8a>li>
- <li><a href="#">9a>li>
- <li><a href="#">10a>li>
- <li class="threeword"><a href="JavaScript:;">下一页a>li>
- <li class="threeword"><a href="JavaScript:;">末页a>li>
- */
-
- var beforePage=pb.currentPage-1;
- if (beforePage<=0){
- beforePage=1;
- }
-
-
- var fistPage='<li onclick="JavaScript:load1('+cid+',1,'+rname+')"><a href="JavaScript:void(0)">首页a>li>';
- var prePage='<li onclick="JavaScript:load1('+cid+','+beforePage+','+rname+')" class="threeword"><a href="#">上一页a>li>';
- var lis="";
- lis+=fistPage;
- lis+=prePage;
-
-
- //展示分页页码
- var begin;
- var end;
- if (pb.totalPage<10){
- begin=1;
- end=pb.totalPage;
- }else {
- begin=pb.currentPage-5;
- end=pb.currentPage+4;
- if (begin<1){
- begin=1;
- end=10;
- }
- if (end>pb.totalPage){
- end=pb.totalPage;
- begin=end-9;
-
- }
- }
-
- for (var i = begin; i <=end ; i++) {
- var li;
- if (pb.currentPage==i){
- var li='<li class="curPage" onclick="JavaScript:load1('+cid+','+i+','+rname+')"><a href="JavaScript:void(0)">'+i+'a>li>';
-
- }else {
- var li='<li onclick="JavaScript:load1('+cid+','+i+','+rname+')"><a href="JavaScript:void(0)">'+i+'a>li>';
- }
- //创建页码的li
-
- //拼接字符串
- lis+=li;
-
-
- }
- var nextPage=pb.currentPage+1;
- if (nextPage>=pb.totalPage){
- nextPage=pb.totalPage;
- }
-
- nextPage='<li li onclick="JavaScript:load1('+cid+','+nextPage+','+rname+')" class="threeword"><a href="#">下一页a>li>';
- var finalPage=' <li onclick="JavaScript:load1('+cid+','+pb.totalPage+','+rname+')" class="threeword"><a href="#">末页a>li>';
- lis+=nextPage;
- lis+=finalPage;
-
- //将lis内容设置到url
- var route_lis="";
- $("#pageNum").html(lis);
- for (var i = 0; i
- var route=pb.list[i];
- var li=' <li>\n' +
- '<div class="img"><img src="'+route.rimage+'" style="width: 299px">div>\n' +
- '<div class="text1">\n' +
- ' <p>'+route.rname+'p>\n' +
- '<br/>\n' +
- '<p>'+route.routeIntroduce+'p>\n' +
- 'div>\n' +
- '<div class="price">\n' +
- '<p class="price_num">\n' +
- '<span>¥span>\n' +
- '<span>'+route.price+'span>\n' +
- '<span>起span>\n' +
- 'p>\n' +
- '<p><a href="route_detail.html">查看详情a>p>' +
- 'div>\n' +
- 'li>';
-
- route_lis+=li;
-
- }
- $("#route").html(route_lis);
- //跳转到页面顶部
- window.scrollTo(0,0);
-
-
- });
- //分页工具条展示
- //解析数据,展示到页面上
-
- }
- script>
- head>
- <body>
- <div id="header">div>
- <div class="page_one">
- <div class="contant">
- <div class="crumbs">
- <img src="images/search.png" alt="">
- <p>黑马旅行><span>搜索结果span>p>
- div>
- <div class="xinxi clearfix">
- <div class="left">
- <div class="header">
- <span>商品信息span>
- <span class="jg">价格span>
- div>
- <ul id="route">
- <li>
- <div class="img"><img src="images/04-search_03.jpg" alt="">div>
- <div class="text1">
- <p>【减100元 含除夕/春节出发】广州增城三英温泉度假酒店/自由行套票p>
- <br/>
- <p>1-2月出发,网付立享¥1099/2人起!爆款位置有限,抢完即止!p>
- div>
- <div class="price">
- <p class="price_num">
- <span>¥span>
- <span>299span>
- <span>起span>
- p>
- <p><a href="route_detail.html">查看详情a>p>
- div>
- li>
- <li>
- <div class="img"><img src="images/04-search_03.jpg" alt="">div>
- <div class="text1">
- <p>浪花朵朵旅行普吉岛丛林飞跃空中飞人探险游中文服务泰国旅游p>
- <br/>
- <p>1-2月出发,网付立享¥1099/2人起!爆款位置有限,抢完即止!p>
- div>
- <div class="price">
- <p class="price_num">
- <span>¥span>
- <span>899span>
- <span>起span>
- p>
- <p><a href="route_detail.html">查看详情a>p>
- div>
- li>
- <li>
- <div class="img"><img src="images/04-search_03.jpg" alt="">div>
- <div class="text1">
- <p>黑妞皇家旅行普吉岛攀牙湾大船星光之旅皮划艇日落休闲特色体验p>
- <br/>
- <p>1-2月出发,网付立享¥1099/2人起!爆款位置有限,抢完即止!p>
- div>
- <div class="price">
- <p class="price_num">
- <span>¥span>
- <span>999span>
- <span>起span>
- p>
- <p><a href="route_detail.html">查看详情a>p>
- div>
- li>
- <li>
- <div class="img"><img src="images/04-search_03.jpg" alt="">div>
- <div class="text1">
- <p>浪花朵朵旅行普吉岛皇帝岛珊瑚岛香蕉船拖拽伞水上项目p>
- <br/>
- <p>1-2月出发,网付立享¥1099/2人起!爆款位置有限,抢完即止!p>
- div>
- <div class="price">
- <p class="price_num">
- <span>¥span>
- <span>99span>
- <span>起span>
- p>
- <p><a href="route_detail.html">查看详情a>p>
- div>
- li>
- <li>
- <div class="img"><img src="images/04-search_03.jpg" alt="">div>
- <div class="text1">
- <p>环游记 泰国清迈Lila massage女子监狱spa 丽菈泰式按摩马杀鸡p>
- <br/>
- <p>1-2月出发,网付立享¥1099/2人起!爆款位置有限,抢完即止!p>
- div>
- <div class="price">
- <p class="price_num">
- <span>¥span>
- <span>199span>
- <span>起span>
- p>
- <p><a href="route_detail.html">查看详情a>p>
- div>
- li>
- <li>
- <div class="img"><img src="images/04-search_03.jpg" alt="">div>
- <div class="text1">
- <p>【减100元 含除夕/春节出发】广州增城三英温泉度假酒店/自由行套票p>
- <br/>
- <p>1-2月出发,网付立享¥1099/2人起!爆款位置有限,抢完即止!p>
- div>
- <div class="price">
- <p class="price_num">
- <span>¥span>
- <span>899span>
- <span>起span>
- p>
- <p><a href="route_detail.html">查看详情a>p>
- div>
- li>
- <li>
- <div class="img"><img src="images/04-search_03.jpg" alt="">div>
- <div class="text1">
- <p>【减100元 含除夕/春节出发】广州增城三英温泉度假酒店/自由行套票p>
- <br/>
- <p>1-2月出发,网付立享¥1099/2人起!爆款位置有限,抢完即止!p>
- div>
- <div class="price">
- <p class="price_num">
- <span>¥span>
- <span>1199span>
- <span>起span>
- p>
- <p><a href="route_detail.html">查看详情a>p>
- div>
- li>
- <li>
- <div class="img"><img src="images/04-search_03.jpg" alt="">div>
- <div class="text1">
- <p>泰国芭提雅三合一日游芭提雅蒂芬妮人妖秀成人门票bigeye含接送p>
- <br/>
- <p>1-2月出发,网付立享¥1099/2人起!爆款位置有限,抢完即止!p>
- div>
- <div class="price">
- <p class="price_num">
- <span>¥span>
- <span>1589span>
- <span>起span>
- p>
- <p><a href="route_detail.html">查看详情a>p>
- div>
- li>
- ul>
- <div class="page_num_inf">
- <i>i> 共
- <span id="totalPage">12span>页<span id="totalCount">132span>条
- div>
- <div class="pageNum">
- <ul id="pageNum">
- <li><a href="">首页a>li>
- <li class="threeword"><a href="#">上一页a>li>
- <li><a href="#">1a>li>
- <li><a href="#">2a>li>
- <li><a href="#">3a>li>
- <li><a href="#">4a>li>
- <li><a href="#">5a>li>
- <li><a href="#">6a>li>
- <li><a href="#">7a>li>
- <li><a href="#">8a>li>
- <li><a href="#">9a>li>
- <li><a href="#">10a>li>
- <li class="threeword"><a href="JavaScript:;">下一页a>li>
- <li class="threeword"><a href="JavaScript:;">末页a>li>
- ul>
- div>
- div>
- <div class="right">
- <div class="top">
- <div class="hot">HOTdiv>
- <span>热门推荐span>
- div>
- <ul>
- <li>
- <div class="left"><img src="images/04-search_09.jpg" alt="">div>
- <div class="right">
- <p>清远新银盏温泉度假村酒店/自由行套...p>
- <p>网付价<span>¥<span>899span>起span>
- p>
- div>
- li>
- <li>
- <div class="left"><img src="images/04-search_09.jpg" alt="">div>
- <div class="right">
- <p>清远新银盏温泉度假村酒店/自由行套...p>
- <p>网付价<span>¥<span>899span>起span>
- p>
- div>
- li>
- <li>
- <div class="left"><img src="images/04-search_09.jpg" alt="">div>
- <div class="right">
- <p>清远新银盏温泉度假村酒店/自由行套...p>
- <p>网付价<span>¥<span>899span>起span>
- p>
- div>
- li>
- <li>
- <div class="left"><img src="images/04-search_09.jpg" alt="">div>
- <div class="right">
- <p>清远新银盏温泉度假村酒店/自由行套...p>
- <p>网付价<span>¥<span>899span>起span>
- p>
- div>
- li>
- <li>
- <div class="left"><img src="images/04-search_09.jpg" alt="">div>
- <div class="right">
- <p>清远新银盏温泉度假村酒店/自由行套...p>
- <p>网付价<span>¥<span>899span>起span>
- p>
- div>
- li>
- ul>
- div>
- div>
- div>
- div>
-
-
- <div id="footer">div>
-
- <script type="text/JavaScript" src="js/include.js">script>
- body>
-
- html>
实现我的收藏查看功能实质上也是同一个道理,只不过加一个用户登录验证的判断,但麻烦的依旧是标签设置和拼接问题。前台代码不如后台代码逻辑清晰。
后台代码:
- //RouteServlet
- @WebServlet("/route/*")
- public class RouteServlet extends BaseServlet {
-
- private RouteService routeService = new RouteServiceImpl();
-
- /**
- * 分页查询
- * @param request
- * @param response
- * @throws ServletException
- * @throws IOException
- */
- public void pageQuery(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- //1.接受参数
- String currentPageStr = request.getParameter("currentPage");
- String pageSizeStr = request.getParameter("pageSize");
- String cidStr = request.getParameter("cid");
-
- int cid = 0;//类别id
- //2.处理参数
- if(cidStr != null && cidStr.length() > 0){
- cid = Integer.parseInt(cidStr);
- }
- int currentPage = 0;//当前页码,如果不传递,则默认为第一页
- if(currentPageStr != null && currentPageStr.length() > 0){
- currentPage = Integer.parseInt(currentPageStr);
- }else{
- currentPage = 1;
- }
-
- int pageSize = 0;//每页显示条数,如果不传递,默认每页显示5条记录
- if(pageSizeStr != null && pageSizeStr.length() > 0){
- pageSize = Integer.parseInt(pageSizeStr);
- }else{
- pageSize = 5;
- }
-
- //3. 调用service查询PageBean对象
- PageBean
pb = routeService.pageQuery(cid, currentPage, pageSize); -
- //4. 将pageBean对象序列化为json,返回
- writeValue(pb,response);
-
- }
-
- }
-
- // RouteService
- public class RouteServiceImpl implements RouteService {
- private RouteDao routeDao = new RouteDaoImpl();
- @Override
- public PageBean
pageQuery(int cid, int currentPage, int pageSize) { - //封装PageBean
- PageBean
pb = new PageBean(); - //设置当前页码
- pb.setCurrentPage(currentPage);
- //设置每页显示条数
- pb.setPageSize(pageSize);
-
- //设置总记录数
- int totalCount = routeDao.findTotalCount(cid);
- pb.setTotalCount(totalCount);
- //设置当前页显示的数据集合
- int start = (currentPage - 1) * pageSize;//开始的记录数
- List
list = routeDao.findByPage(cid,start,pageSize); - pb.setList(list);
-
- //设置总页数 = 总记录数/每页显示条数
- int totalPage = totalCount % pageSize == 0 ? totalCount / pageSize :(totalCount / pageSize) + 1 ;
- pb.setTotalPage(totalPage);
-
-
- return pb;
- }
- }
-
- //RouteDao
- public class RouteDaoImpl implements RouteDao {
- private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
-
- @Override
- public int findTotalCount(int cid) {
- String sql = "select count(*) from tab_route where cid = ?";
- return template.queryForObject(sql,Integer.class,cid);
- }
-
- @Override
- public List
findByPage(int cid, int start, int pageSize) { - String sql = "select * from tab_route where cid = ? limit ? , ?";
-
- return template.query(sql,new BeanPropertyRowMapper
(Route.class),cid,start,pageSize); - }
- }
-
-
完成收藏功能:
- 旅游线路收藏功能
- 分析
- 判断当前登录用户是否收藏过该线路
当页面加载完成后,发送ajax请求,获取用户是否收藏的标记
根据标记,展示不同的按钮样式


后台代码:
- //后台代码
- //RouteServlet:
-
- public void isFavorite(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- //1. 获取线路id
- String rid = request.getParameter("rid");
-
- //2. 获取当前登录的用户 user
- User user = (User) request.getSession().getAttribute("user");
- int uid;//用户id
- if(user == null){
- //用户尚未登录
- uid = 0;
- }else{
- //用户已经登录
- uid = user.getUid();
- }
-
- //3. 调用FavoriteService查询是否收藏
- boolean flag = favoriteService.isFavorite(rid, uid);
-
- //4. 写回客户端
- writeValue(flag,response);
- }
-
- FavoriteService
-
- @Override
- public boolean isFavorite(String rid, int uid) {
-
- Favorite favorite = favoriteDao.findByRidAndUid(Integer.parseInt(rid), uid);
-
- return favorite != null;//如果对象有值,则为true,反之,则为false
- }
-
-
-
- //FavoriteDao
-
- @Override
- public Favorite findByRidAndUid(int rid, int uid) {
- Favorite favorite = null;
- try {
- String sql = " select * from tab_favorite where rid = ? and uid = ?";
- favorite = template.queryForObject(sql, new BeanPropertyRowMapper
(Favorite.class), rid, uid); - } catch (DataAccessException e) {
- e.printStackTrace();
- }
- return favorite;
- }
前台代码:
- //前台代码
- //route_detail.html
-
- $(function () {
- // 发送请求,判断用户是否收藏过该线路
- var rid = getParameter("rid");
- $.get("route/isFavorite",{rid:rid},function (flag) {
- if(flag){
- // 用户已经收藏过
- //<a class="btn already" disabled="disabled">
- //设置收藏按钮的样式
- $("#favorite").addClass("already");
- $("#favorite").prop("disabled",disabled);
-
-
-
- }else{
- // 用户没有收藏
- }
- });
收藏次数的动态展示:
前台:
//设置收藏次数
$("#favoriteCount").html("已收藏"+route.count+"次");
后台:
//RouteService
//4. 查询收藏次数
int count = favoriteDao.findCountByRid(route.getRid());
route.setCount(count);
//FavoriteDao
@Override
public int findCountByRid(int rid) {
String sql = "SELECT COUNT(*) FROM tab_favorite WHERE rid = ?";
return template.queryForObject(sql,Integer.class,rid);
}
- 编码
前台代码
- $(function () {
-
- // 发送请求,判断用户是否收藏过该线路
-
- var rid = getParameter("rid");
-
- $.get("route/isFavorite",{rid:rid},function (flag) {
-
- if(flag){
-
- // 用户已经收藏过
-
- //<a class="btn already" disabled="disabled">
-
- //设置收藏按钮的样式
-
- $("#favorite").addClass("already");
-
- $("#favorite").attr("disabled","disabled");
-
-
-
- //删除按钮的点击事件
-
- $("#favorite").removeAttr("onclick");
-
- }else{
-
- // 用户没有收藏
-
- }
-
- });
-
-
-
-
-
-
-
- });
-
-
-
- //点击收藏按钮触发的方法
-
- function addFavorite(){
-
- var rid = getParameter("rid");
-
- //1. 判断用户是否登录
-
- $.get("user/findOne",{},function (user) {
-
- if(user){
-
- //用户登录了
-
- //添加功能
-
- $.get("route/addFavorite",{rid:rid},function () {
-
-
-
- //代码刷新页面
-
- location.reload();
-
- });
-
-
-
- }else{
-
- //用户没有登录
-
- alert("您尚未登录,请登录");
-
- location.href="http://localhost/travel/login.html";
-
- }
-
- })
-
- }
记得在标签内绑定单击事件:
<a οnclick="addFavorite();" class="btn" id="favorite">点击收藏
<a οnclick="removeFavorite();" class="btn already" disabled="disabled" id="cancel_favorite">取消收藏
后台代码:
RouteServlet
- public void addFavorite(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-
- //1. 获取线路rid
-
- String rid = request.getParameter("rid");
-
- //2. 获取当前登录的用户
-
- User user = (User) request.getSession().getAttribute("user");
-
- int uid;//用户id
-
- if(user == null){
-
- //用户尚未登录
-
- return ;
-
- }else{
-
- //用户已经登录
-
- uid = user.getUid();
-
- }
-
-
-
-
-
- //3. 调用service添加
-
- favoriteService.add(rid,uid);
-
-
-
- }
FavoriteService
- @Override
-
- public void add(String rid, int uid) {
-
- favoriteDao.add(Integer.parseInt(rid),uid);
-
- }
FavoriteDao
- @Override
-
- public void add(int rid, int uid) {
-
- String sql = "insert into tab_favorite values(?,?,?)";
-
-
-
- template.update(sql,rid,new Date(),uid);
-
- }