JavaEE开发-第六节 JavaEE项目实战(四)

个人信息页面

  1. 展示、保存用户信息

jsp全局访问数据问题:

  1. 当个人信息页面的头像、名称等更改之后,左侧的导航栏上的信息也应该相应修改,但是左侧导航栏是嵌入到每一个页面的,那么当点击其他页面时(比如教育经验),如何获取这些信息呢?
  2. 代码示例如下:

     //左侧导航的位置信息
     <div class="name">${user.name}</div>
     <div class="email">${user.job}</div>
    
  3. jsp中这句话${user.name}的本质是
    1. 先通过request.getAttribute("user").getName();来获取
    2. 如果上面的方法获取不到,再通过Session来获取 request.getSession().getAttribute("user").getName();
    3. 因此,只要Sesson中有值,可以全局获得,无论那个页面

代码示例

  1. 展示个人信息列表、保存用信息的接口如下:
//访问用户信息页面
public void admin(HttpServletRequest request, HttpServletResponse response) throws Exception {
    request.setAttribute("user", service.list().get(0));
    forward(request, response, "admin/user.jsp");
}
//保存用户信息
public void save(HttpServletRequest request, HttpServletResponse response) throws Exception {
    UploadParams params = Uploads.parseRequest(request);

    // 请求参数转成User
    User user = new User();
    BeanUtils.populate(user, params.getParams());

    // 从Session中拿到邮箱、密码
    User loginUser = (User) request.getSession().getAttribute("user");
    user.setEmail(loginUser.getEmail());
    user.setPassword(loginUser.getPassword());

    // 处理用户的头像
    FileItem item = params.getFileParam("photoFile");
    user.setPhoto(Uploads.uploadImage(item, request, user.getPhoto()));

    if (service.save(user)) { // 保存成功
        redirect(request, response, "user/admin");

        // 更新session中的用户信息
        request.getSession().setAttribute("user", user);
    } else {
        forwardError(request, response, "个人信息保存失败");
    }
}

退出登录

//退出登录-UserServlet
public void logout(HttpServletRequest request, HttpServletResponse response) throws Exception {
    // 清除登录信息(将session中的用户删除)
    request.getSession().removeAttribute("user");

    // 重定向到登录页面
    redirect(request, response, "page/login.jsp");
}

修改密码

  1. 改造password.jsp

     //展示修改密码页面-UserServlet
     public void password(HttpServletRequest request, HttpServletResponse response) throws Exception {
         forward(request, response, "admin/password.jsp");
     }
     //修改密码
     public void updatePassword(HttpServletRequest request, HttpServletResponse response) throws Exception {
         String oldPassword = request.getParameter("oldPassword");
         // 对比session中用户的密码
         User user = (User) request.getSession().getAttribute("user");
         if (!user.getPassword().equals(oldPassword)) {
             forwardError(request, response, "旧密码不正确");
             return;
         }
    
         // 保存新密码
         String newPassword = request.getParameter("newPassword");
         user.setPassword(newPassword);
         if (service.save(user)) { // 保存成功
             redirect(request, response, "page/login.jsp");
         } else {
             forwardError(request, response, "修改密码失败");
         }
     }
    

个人简历页面

  1. 将front文件夹下的html代码抽取、整理成jsp(略)
  2. 配置默认访问首页
    1. 当用户直接输入域名+端口+根目录(http://localhost:8080/xr/)的时候直接跳转到个人简历页面
    2. 通常默认的是访问webapp下面的index.htm、index.html、index.jsp
    3. 也可以通过web.xml配置,在web.xml下配置访问首页
    4. 直接输入http://localhost:8080/xr/就会跳转到个人简历页面
    5. 本质是执行http://localhost:8080/xr/user/front
     <!-- 配置首页 -->
     <welcome-file-list>
         <welcome-file>user/front</welcome-file>
     </welcome-file-list>
    
  3. 个人简历页面UserServlet代码如下

     private SkillService skillService = new SkillServiceImpl();
     private AwardService awardService = new AwardServiceImpl();
     private WebsiteService websiteService = new WebsiteServiceImpl();
    
     /*
     对http://localhost:8080/xr/请求做特殊处理
     上面讲过,调用根路径本质是访问http://localhost:8080/xr/user/front,因此会来到UserServlet,但是此时的实际路径仍然是http://localhost:8080/xr/
     那么经过BaseServlet的doGet切割后,调用的是xr方法,很显然没有该方法,那么就需要重写父类的doGet,专门处理
      */
     @Override
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         String uri = request.getRequestURI();
         //通过/切割
         String[] cmps = uri.split("/");
         //拿到最后一个访问路径名
         String methodName = "/" + cmps[cmps.length - 1];
         //1. 如果为根路径/xr,则就是访问个人简历页面
         if (methodName.equals(request.getContextPath())) {
             try {
                 front(request, response);
             } catch (Exception e) {
                 e.printStackTrace();
             }
         //2. 否则访问父类的doget方法
         } else {
             super.doGet(request, response);
         }
     }
     //个人简历页面
     public void front(HttpServletRequest request, HttpServletResponse response) throws Exception {
         //获取个人简历页面需要展示的数据信息
         // 用户信息
         User user = service.list().get(0);
         request.setAttribute("user", user);
    
         // 个人特质
         request.setAttribute("trait", user.getTrait().split(","));
    
         // 兴趣爱好
         request.setAttribute("interests", user.getInterests().split(","));
    
         // 专业技能
         request.setAttribute("skills", skillService.list());
         // 获奖成就
         request.setAttribute("awards", awardService.list());
         // 网站的底部信息
         request.setAttribute("footer", websiteService.list().get(0).getFooter());
         //转发到个人简历页面
         forward(request, response, "front/user.jsp");
     }
    

个人简历右侧的导航栏对应的页面

  1. 根据个人简历页面右边的导航栏,需要访问教育经验、工作经验、项目经验等简历模块页面(注意,跟管理端不一样)
  2. 导航jsp中访问如下

     <li><a href="${ctx}/education/front" data-tooltip="教育经验"><span 
     class="crt-icon crt-icon-book"></span></a></li>
     <li><a href="${ctx}/experience/front" data-tooltip="工作经验"><span 
     class="crt-icon crt-icon-experience"></span></a></li>
     <li><a href="${ctx}/project/front" data-tooltip="项目经验"><span 
     class="crt-icon crt-icon-wrench"></span></a></li>
     <li><a href="${ctx}/contact/front" data-tooltip="联系我吧"><span 
     class="crt-icon crt-icon-contact"></span></a></li>
     <li><a href="${ctx}/user/admin" data-tooltip="后台管理"><span
     class="crt-icon crt-icon-key"></span></a></li>
    
  3. 因此需要分别在EducationServlet/ExperienceServlet/ProjectServlet中添加相应的接口方法,例如项目经验

     //ProjectServlet中添加访问工作经验
     private UserService userService = new UserServiceImpl();
     private WebsiteService websiteService = new WebsiteServiceImpl();
    
     public void front(HttpServletRequest request, HttpServletResponse response) throws Exception {
         request.setAttribute("user", userService.list().get(0));
         request.setAttribute("footer", websiteService.list().get(0).getFooter());
         request.setAttribute("projects", service.list());
         forward(request, response, "front/project.jsp");
     }
    

留言信息功能

  1. 同理新增留言信息模块的bean、dao、service、servlet以及对应的个人简历页面的jsp、后台管理页面的jsp

多条件查询、分页数据

  1. 多条件:根据是否已读、日期、主题、内容可以进行多条件查询
  2. 分页展示:当数据了大的时候分页展示数据给前端
  3. 前端需要将一些条件发送给服务器:
    1. 页码:要展示第几页数据
    2. 每页大小:每一页展示20条
    3. 开始时间
    4. 结束时间
    5. 关键字
    6. 阅读状态

代码示例

  1. 新建一个bean(ContactListParam)用于接收前端的查询参数

     package com.zh.xr.bean;
     import java.util.Date;
     public class ContactListParam {
         public static final int READ_ALL = 2;
         private Integer pageNo;
         private Integer pageSize;
         private Date beginDay;
         private Date endDay;
         private String keyword;
         /** 0:未读 1:已读 2:全部 */
         private Integer alreadyRead;
         //所有属性的get方法、set方法...
     }
    
  2. 服务器返回的数据也不能是Contact模型的列表了,因此新建一个返回结果的bean(ContactListResult)

     package com.zh.xr.bean;
     import java.util.List;
     public class ContactListResult extends ContactListParam {
         /**
          * 总数量
          */
         private Integer totalCount;
         /**
          * 总页数
          */
         private Integer totalPages;
         private List<Contact> contacts;
         //所有属性的get方法、set方法...
     }
    
  3. dao模块的代码(重要

    1. dao接口

       public interface ContactDao extends BaseDao<Contact> {
           ContactListResult list(ContactListParam param);
           boolean read(Integer id);
       }
      
    2. dao实现

      public class ContactDaoImpl extends BaseDaoImpl<Contact> implements ContactDao {
           @Override
           public boolean save(Contact bean) {
               Integer id = bean.getId();
               List<Object> args = new ArrayList<>();
               args.add(bean.getName());
               args.add(bean.getEmail());
               args.add(bean.getComment());
               args.add(bean.getSubject());
               args.add(bean.getAlreadyRead());
              
               String sql;
               if (id == null || id < 1) { // 添加
                   sql = "INSERT INTO contact(name, email, comment, subject, already_read) VALUES(?, ?, ?, ?, ?)";
               } else {
                   sql = "UPDATE contact SET name = ?, email = ?, comment = ?, subject = ?, already_read = ? WHERE id = ?";
                   args.add(id);
               }
               return tpl.update(sql, args.toArray()) > 0;
           }
              
           @Override
           public Contact get(Integer id) {
               String sql = "SELECT id, created_time, name, email, comment, subject, already_read FROM contact WHERE id = ?";
               return tpl.queryForObject(sql, new BeanPropertyRowMapper<>(Contact.class), id);
           }
              
           @Override
           public List<Contact> list() {
               String sql = "SELECT id, created_time, name, email, comment, subject, already_read FROM contact";
               return tpl.query(sql, new BeanPropertyRowMapper<>(Contact.class));
           }
              
           @Override
           public ContactListResult list(ContactListParam param) {
               ContactListResult result = new ContactListResult();
              
               StringBuilder sql = new StringBuilder();
               sql.append("SELECT id, created_time, name, email, comment, subject, already_read FROM contact WHERE 1 = 1 ");
              
               // 参数
               List<Object> args = new ArrayList<>();
              
               // 条件
               StringBuilder condition = new StringBuilder();
              
               if (param.getBeginDay() != null) { // 开始时间
                   condition.append("AND created_time >= ? ");
                   args.add(param.getBeginDay());
                   result.setBeginDay(param.getBeginDay());
               }
              
               if (param.getEndDay() != null) { // 结束时间
                   condition.append("AND created_time <= ? ");
                   args.add(param.getEndDay());
                   result.setEndDay(param.getEndDay());
               }
              
               String keyword = param.getKeyword();
               if (keyword != null && keyword.length() > 0) { // 关键字
                   result.setKeyword(keyword);
                   condition.append("AND (name LIKE ? OR email LIKE ? OR subject LIKE ? OR comment LIKE ?) ");
                   keyword = "%" + keyword + "%";
                   args.add(keyword);
                   args.add(keyword);
                   args.add(keyword);
                   args.add(keyword);
               }
              
               Integer read = param.getAlreadyRead();
               if (read != null && read < ContactListParam.READ_ALL) { // 阅读状态
                   condition.append("AND already_read = ? ");
                   args.add(read);
                   result.setAlreadyRead(read);
               }
              
               // 总数量、总页数
               Integer pageSize = param.getPageSize();
               if (pageSize == null || pageSize < 10) {
                   pageSize = 10;
               }
              
               /*
               总数量:101
               每一页显示20条
               总页数 = (总数量 + 每页的数量 - 1) / 每页的数量
                */
               String countSql = "SELECT COUNT(*) FROM contact WHERE 1 = 1 " + condition;
               Integer totalCount = tpl.queryForObject(countSql, Integer.class, args.toArray());
               if (totalCount == 0) return result;
              
               int totalPages = (totalCount + pageSize - 1) / pageSize;
               result.setTotalPages(totalPages); // 2
               result.setTotalCount(totalCount);
              
               // 分页
               sql.append(condition);
               sql.append("LIMIT ?, ?");
               Integer pageNo = param.getPageNo(); // 9
               if (pageNo == null || pageNo < 1) {
                   pageNo = 1;
               } else if (pageNo > totalPages) { // 页码如果已经超过了总页数
                   pageNo = totalPages;
               }
               args.add((pageNo - 1) * pageSize);
               args.add(pageSize);
               result.setPageNo(pageNo);
               result.setPageSize(pageSize);
              
               List<Contact> contacts = tpl.query(sql.toString(), new BeanPropertyRowMapper<>(Contact.class), args.toArray());
               result.setContacts(contacts);
              
               return result;
           }
              
           @Override
           public boolean read(Integer id) {
               String sql = "UPDATE contact SET already_read = 1 WHERE id = ?";
               return tpl.update(sql, id) > 0;
           }
       }
      
    3. service实现
      1. 接口

         public interface ContactService extends BaseService<Contact> {
             ContactListResult list(ContactListParam param);
             boolean read(Integer id);
         }
        
      2. 实现

         public class ContactServiceImpl extends BaseServiceImpl<Contact> implements ContactService {
             @Override
             public ContactListResult list(ContactListParam param) {
                 return ((ContactDao) dao).list(param);
             }
             @Override
             public boolean read(Integer id) {
                 return ((ContactDao) dao).read(id);
             }
         }
        
    4. Servlet

       @WebServlet("/contact/*")
       public class ContactServlet extends BaseServlet<Contact> {
           private UserService userService = new UserServiceImpl();
           private WebsiteService websiteService = new WebsiteServiceImpl();
              
           //个人简历页面展示留言信息页面
           public void front(HttpServletRequest request, HttpServletResponse response) throws Exception {
               request.setAttribute("user", userService.list().get(0));
               request.setAttribute("footer", websiteService.list().get(0).getFooter());
               // 转发
               forward(request, response, "front/contact.jsp");
           }
              
           //后台管理页面展示留言信息页面
           public void admin(HttpServletRequest request, HttpServletResponse response) throws Exception {
               //查询条件
               ContactListParam param = new ContactListParam();
               BeanUtils.populate(param, request.getParameterMap());
              
               request.setAttribute("result", ((ContactService) service).list(param));
               forward(request, response, "admin/contact.jsp");
           }
           //个人简历页面保存留言信息页面
           public void save(HttpServletRequest request, HttpServletResponse response) throws Exception {
               // 检查验证码
               String code = (String) request.getSession().getAttribute("code");
               String captcha = request.getParameter("captcha");
               if (!code.equals(captcha)) {
                   forwardError(request, response, "验证码错误");
                   return;
               }
              
               Contact contact = new Contact();
               BeanUtils.populate(contact, request.getParameterMap());
               if (service.save(contact)) { // 保存成功
                   redirect(request, response, "contact/front");
               } else {
                   forwardError(request, response, "留言信息保存失败");
               }
           }
              
           //后台管理端,点击查看留言数据,需要改变这条留言的状态
           public void read(HttpServletRequest request, HttpServletResponse response) throws Exception {
               Integer id = Integer.valueOf(request.getParameter("id"));
              
               Map<String, Object> result = new HashMap<>();
               if (((ContactService) service).read(id)) {
                   result.put("success", true);
                   result.put("msg", "查看成功");
               } else {
                   result.put("success", false);
                   result.put("msg", "查看失败");
               }
              
               response.setContentType("text/json; charset=UTF-8");
               response.getWriter().write(new ObjectMapper().writeValueAsString(result));
           }
              
           public void remove(HttpServletRequest request, HttpServletResponse response) throws Exception {
              
           }
       }
      
Table of Contents