ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、视频、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] ## 步骤 1 : 先运行,看到效果,再学习 先将完整的 tmall_ssm 项目(向老师要相关资料),配置运行起来,确认可用之后,再学习做了哪些步骤以达到这样的效果。 ## 步骤 2 : 模仿和排错 在确保可运行项目能够正确无误地运行之后,再严格照着教程的步骤,对代码模仿一遍。 模仿过程难免代码有出入,导致无法得到期望的运行结果,此时此刻通过比较**正确答案** ( 可运行项目 ) 和自己的代码,来定位问题所在。 采用这种方式,**学习有效果,排错有效率**,可以较为明显地提升学习速度,跨过学习路上的各个槛。 ## 步骤 3 : 界面效果 访问登录地址: `http://localhost:8080/tmall_ssm/loginPage` ![](https://box.kancloud.cn/458fbd29defcceb6581371d0d255c4a1_1068x632.png) ## 步骤 4 : login.jsp 与register.jsp相仿,login.jsp也包含了header.jsp,footer.jsp等公共页面。 中间是登录业务页面loginPage.jsp ![](https://box.kancloud.cn/dc74549d3b0f74808958ee20b357dfae_296x204.png) ~~~ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@include file="../include/fore/header.jsp"%> <%@include file="../include/fore/loginPage.jsp"%> <%@include file="../include/fore/footer.jsp"%> ~~~ ## 步骤 5 : UserService 增加get(String name, String password)方法 ~~~ package com.dodoke.tmall.service; import java.util.List; import com.dodoke.tmall.pojo.User; public interface UserService { void add(User c); void delete(int id); void update(User c); User get(int id); List list(); boolean isExist(String name); User get(String name, String password); } ~~~ ## 步骤 6 : UserServiceImpl 增加User get(String name, String password) 方法 ~~~ package com.dodoke.tmall.service.impl; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.dodoke.tmall.mapper.UserMapper; import com.dodoke.tmall.pojo.User; import com.dodoke.tmall.pojo.UserExample; import com.dodoke.tmall.service.UserService; @Service public class UserServiceImpl implements UserService { @Autowired UserMapper userMapper; @Override public void add(User u) { userMapper.insert(u); } @Override public void delete(int id) { userMapper.deleteByPrimaryKey(id); } @Override public void update(User u) { userMapper.updateByPrimaryKeySelective(u); } @Override public User get(int id) { return userMapper.selectByPrimaryKey(id); } public List<User> list() { UserExample example = new UserExample(); example.setOrderByClause("id desc"); return userMapper.selectByExample(example); } @Override public boolean isExist(String name) { UserExample example = new UserExample(); example.createCriteria().andNameEqualTo(name); List<User> result = userMapper.selectByExample(example); if (!result.isEmpty()) { return true; } return false; } @Override public User get(String name, String password) { UserExample example = new UserExample(); example.createCriteria().andNameEqualTo(name).andPasswordEqualTo(password); List<User> result = userMapper.selectByExample(example); if (result.isEmpty()) { return null; } return result.get(0); } } ~~~ ## 步骤 7 : loginPage.jsp 登陆业务页面,用于向服务器提交账号和密码 1. 与registerPage.jsp类似的,用于显示登录密码错误 <c:if test="${!empty msg}"> $("span.errorMessage").html("${msg}"); $("div.loginErrorMessageDiv").show(); </c:if> 2. 其他js函数是用于为空验证 ~~~ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <script> $(function(){ <c:if test="${!empty msg}"> $("span.errorMessage").html("${msg}"); $("div.loginErrorMessageDiv").show(); </c:if> $("form.loginForm").submit(function(){ if(0==$("#name").val().length||0==$("#password").val().length){ $("span.errorMessage").html("请输入账号密码"); $("div.loginErrorMessageDiv").show(); return false; } return true; }); $("form.loginForm input").keyup(function(){ $("div.loginErrorMessageDiv").hide(); }); var left = window.innerWidth/2+162; $("div.loginSmallDiv").css("left",left); }) </script> <div id="loginDiv" style="position: relative"> <div class="simpleLogo"> <a href="${contextPath}"><img src="img/site/simpleLogo.png"></a> </div> <img id="loginBackgroundImg" class="loginBackgroundImg" src="img/site/loginBackground.png"> <form class="loginForm" action="forelogin" method="post"> <div id="loginSmallDiv" class="loginSmallDiv"> <div class="loginErrorMessageDiv"> <div class="alert alert-danger" > <button type="button" class="close" data-dismiss="alert" aria-label="Close"></button> <span class="errorMessage"></span> </div> </div> <div class="login_acount_text">账户登录</div> <div class="loginInput " > <span class="loginInputIcon "> <span class=" glyphicon glyphicon-user"></span> </span> <input id="name" name="name" placeholder="手机/会员名/邮箱" type="text"> </div> <div class="loginInput " > <span class="loginInputIcon "> <span class=" glyphicon glyphicon-lock"></span> </span> <input id="password" name="password" type="password" placeholder="密码" type="text"> </div> <span class="text-danger">不要输入真实的天猫账号密码</span><br><br> <div> <a class="notImplementLink" href="#nowhere">忘记登录密码</a> <a href="registerPage" class="pull-right">免费注册</a> </div> <div style="margin-top:20px"> <button class="btn btn-block redButton" type="submit">登录</button> </div> </div> </form> </div> ~~~ ## 步骤 8 : ForeController.login() **loginPage.jsp**的form提交数据到路径 forelogin,导致ForeController.login()方法被调用 1. 获取账号密码 2. 把账号通过HtmlUtils.htmlEscape进行转义 3. 根据账号和密码获取User对象 3.1 如果对象为空,则服务端跳转回login.jsp,也带上错误信息,并且使用 loginPage.jsp 中的办法显示错误信息 3.2 如果对象存在,则把对象保存在session中,并客户端跳转到首页"forehome" 注 为什么要用 HtmlUtils.htmlEscape? 因为注册的时候,ForeController.register(),就进行了转义,所以这里也需要转义。有些同学在恶意注册的时候,会使用诸如 <script>alert('papapa')</script> 这样的名称,会导致网页打开就弹出一个对话框。 那么在转义之后,就没有这个问题了。 > @RequestParam用于将请求参数区数据映射到功能处理方法的参数上。可以用来设置默认值或者判断非空等作用,在这里可以省略不写。当然这里也可以使用对象接受。 > ~~~ package com.dodoke.tmall.controller; import java.util.List; import javax.servlet.http.HttpSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.util.HtmlUtils; import com.dodoke.tmall.pojo.Category; import com.dodoke.tmall.pojo.User; import com.dodoke.tmall.service.CategoryService; import com.dodoke.tmall.service.OrderItemService; import com.dodoke.tmall.service.OrderService; import com.dodoke.tmall.service.ProductImageService; import com.dodoke.tmall.service.ProductService; import com.dodoke.tmall.service.PropertyValueService; import com.dodoke.tmall.service.UserService; @Controller @RequestMapping("") public class ForeController { @Autowired CategoryService categoryService; @Autowired ProductService productService; @Autowired UserService userService; @Autowired ProductImageService productImageService; @Autowired PropertyValueService propertyValueService; @Autowired OrderService orderService; @Autowired OrderItemService orderItemService; @RequestMapping("forehome") public String home(Model model) { List<Category> cs = categoryService.list(); productService.fill(cs); productService.fillByRow(cs); model.addAttribute("cs", cs); return "fore/home"; } @RequestMapping("foreregister") public String register(Model model, User user) { String name = user.getName(); // 把账号里的特殊符号进行转义 name = HtmlUtils.htmlEscape(name); user.setName(name); boolean exist = userService.isExist(name); if (exist) { String m = "用户名已经被使用,不能使用"; model.addAttribute("msg", m); model.addAttribute("user", null); return "fore/register"; } userService.add(user); return "redirect:registerSuccessPage"; } @RequestMapping("forelogin") public String login(@RequestParam("name") String name, @RequestParam("password") String password, Model model, HttpSession session) { name = HtmlUtils.htmlEscape(name); User user = userService.get(name,password); if(null==user){ model.addAttribute("msg", "账号密码错误"); return "fore/login"; } session.setAttribute("user", user); return "redirect:forehome"; } } ~~~