JavaEE开发-第六节 JavaEE项目实战(四)
个人信息页面
- 展示、保存用户信息
jsp全局访问数据问题:
- 当个人信息页面的头像、名称等更改之后,左侧的导航栏上的信息也应该相应修改,但是左侧导航栏是嵌入到每一个页面的,那么当点击其他页面时(比如教育经验),如何获取这些信息呢?
-
代码示例如下:
//左侧导航的位置信息 <div class="name">${user.name}</div> <div class="email">${user.job}</div>
- jsp中这句话
${user.name}
的本质是- 先通过
request.getAttribute("user").getName();
来获取 - 如果上面的方法获取不到,再通过Session来获取
request.getSession().getAttribute("user").getName();
- 因此,只要Sesson中有值,可以全局获得,无论那个页面
- 先通过
代码示例
- 展示个人信息列表、保存用信息的接口如下:
//访问用户信息页面
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");
}
修改密码
-
改造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, "修改密码失败"); } }
个人简历页面
- 将front文件夹下的html代码抽取、整理成jsp(略)
- 配置默认访问首页
- 当用户直接输入域名+端口+根目录(
http://localhost:8080/xr/
)的时候直接跳转到个人简历页面 - 通常默认的是访问webapp下面的index.htm、index.html、index.jsp
- 也可以通过web.xml配置,在web.xml下配置访问首页
- 直接输入
http://localhost:8080/xr/
就会跳转到个人简历页面 - 本质是执行
http://localhost:8080/xr/user/front
<!-- 配置首页 --> <welcome-file-list> <welcome-file>user/front</welcome-file> </welcome-file-list>
- 当用户直接输入域名+端口+根目录(
-
个人简历页面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"); }
个人简历右侧的导航栏对应的页面
- 根据个人简历页面右边的导航栏,需要访问教育经验、工作经验、项目经验等简历模块页面(注意,跟管理端不一样)
-
导航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>
-
因此需要分别在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"); }
留言信息功能
- 同理新增留言信息模块的bean、dao、service、servlet以及对应的个人简历页面的jsp、后台管理页面的jsp
多条件查询、分页数据
- 多条件:根据是否已读、日期、主题、内容可以进行多条件查询
- 分页展示:当数据了大的时候分页展示数据给前端
- 前端需要将一些条件发送给服务器:
- 页码:要展示第几页数据
- 每页大小:每一页展示20条
- 开始时间
- 结束时间
- 关键字
- 阅读状态
代码示例
-
新建一个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方法... }
-
服务器返回的数据也不能是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方法... }
-
dao模块的代码(重要)
-
dao接口
public interface ContactDao extends BaseDao<Contact> { ContactListResult list(ContactListParam param); boolean read(Integer id); }
-
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; } }
- service实现
-
接口
public interface ContactService extends BaseService<Contact> { ContactListResult list(ContactListParam param); boolean read(Integer id); }
-
实现
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); } }
-
-
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 { } }
-