企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持知识库和私有化部署方案 广告
[TOC] ## 步骤 1 : 先运行,看到效果,再学习 先将完整的 tmall_ssm 项目(向老师要相关资料),配置运行起来,确认可用之后,再学习做了哪些步骤以达到这样的效果。 ## 步骤 2 : 模仿和排错 在确保可运行项目能够正确无误地运行之后,再严格照着教程的步骤,对代码模仿一遍。 模仿过程难免代码有出入,导致无法得到期望的运行结果,此时此刻通过比较**正确答案** ( 可运行项目 ) 和自己的代码,来定位问题所在。 采用这种方式,**学习有效果,排错有效率**,可以较为明显地提升学习速度,跨过学习路上的各个槛。 ## 步骤 3 : 界面效果 访问注册地址: `http://localhost:8080/tmall_ssm/registerPage` ![](https://box.kancloud.cn/3bed12ac4969ffac655ddcfdf1b639d9_662x418.png) 项目目录结构: ![](https://box.kancloud.cn/18a97f0d2a7b0bdecdb63249d0323b4b_364x487.png) ## 步骤 4 : register.jsp 与首页的home.jsp相仿,register.jsp也包含了header.jsp,top.jsp,footer.jsp等公共页面。 不同的是,没有使用首页的search.jsp,而是用的简单一点的 simpleSearch.jsp 中间是注册业务页面registerPage.jsp ~~~ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <%@include file="../include/fore/header.jsp"%> <%@include file="../include/fore/top.jsp"%> <%@include file="../include/fore/simpleSearch.jsp"%> <%@include file="../include/fore/registerPage.jsp"%> <%@include file="../include/fore/footer.jsp"%> ~~~ ## 步骤 5 : PageController **register.jsp** 是放在WEB-INF目录下的,是无法通过浏览器直接访问的。 为了访问这些放在WEB-INF下的jsp,准备一个专门的PageController类,专门做服务端跳转。 比如访问registerPage,就会服务端跳转到WEB-INF/jsp/fore/register.jsp 去,这样就解决了无法被访问的问题。 这个类很简单,就是单纯用来做服务端跳转用的,为了使学习更顺滑,把后面会用到的也都先贴出来了,都不难理解的。 ~~~ package com.dodoke.tmall.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping("") public class PageController { @RequestMapping("registerPage") public String registerPage() { return "fore/register"; } @RequestMapping("registerSuccessPage") public String registerSuccessPage() { return "fore/registerSuccess"; } @RequestMapping("loginPage") public String loginPage() { return "fore/login"; } @RequestMapping("forealipay") public String alipay() { return "fore/alipay"; } } ~~~ ## 步骤 6 : simpleSearch.jsp 与首页的**search.jsp**不太一样的是,这个搜索栏要更简单一些,并且左右分开。 注: 这里${cs} 中用到的数据将在后续拦截器中讲解 ![](https://box.kancloud.cn/fd39f2925e5dd17afecf9795ad1cae56_1007x79.png) ~~~ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <div > <a href="${contextPath}"> <img id="simpleLogo" class="simpleLogo" src="img/site/simpleLogo.png"> </a> <form action="foresearch" method="post" > <div class="simpleSearchDiv pull-right"> <input type="text" placeholder="平衡车 原汁机" name="keyword"> <button class="searchButton" type="submit">搜天猫</button> <div class="searchBelow"> <c:forEach items="${cs}" var="c" varStatus="st"> <c:if test="${st.count>=8 and st.count<=11}"> <span> <a href="forecategory?cid=${c.id}"> ${c.name} </a> <c:if test="${st.count!=11}"> <span>|</span> </c:if> </span> </c:if> </c:forEach> </div> </div> </form> <div style="clear:both"></div> </div> ~~~ ## 步骤 7 : registerPage.jsp 注册页面的主体功能,用于提交账号密码。 在提交之前会进行为空验证,以及密码是否一致验证。 这段代码用于当账号提交到服务端,服务端判断当前账号已经存在的情况下,显示返回的错误提示 **"用户名已经被使用,不能使用"** ~~~ <c:if test="${!empty msg}"> $("span.errorMessage").html("${msg}"); $("div.registerErrorMessageDiv").css("visibility","visible"); </c:if> ~~~ ~~~ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <script> $(function(){ <c:if test="${!empty msg}"> $("span.errorMessage").html("${msg}"); $("div.registerErrorMessageDiv").css("visibility","visible"); </c:if> $(".registerForm").submit(function(){ if(0==$("#name").val().length){ $("span.errorMessage").html("请输入用户名"); $("div.registerErrorMessageDiv").css("visibility","visible"); return false; } if(0==$("#password").val().length){ $("span.errorMessage").html("请输入密码"); $("div.registerErrorMessageDiv").css("visibility","visible"); return false; } if(0==$("#repeatpassword").val().length){ $("span.errorMessage").html("请输入重复密码"); $("div.registerErrorMessageDiv").css("visibility","visible"); return false; } if($("#password").val() !=$("#repeatpassword").val()){ $("span.errorMessage").html("重复密码不一致"); $("div.registerErrorMessageDiv").css("visibility","visible"); return false; } return true; }); }) </script> <form method="post" action="foreregister" class="registerForm"> <div class="registerDiv"> <div class="registerErrorMessageDiv"> <div class="alert alert-danger" role="alert"> <button type="button" class="close" data-dismiss="alert" aria-label="Close"></button> <span class="errorMessage"></span> </div> </div> <table class="registerTable" align="center"> <tr> <td class="registerTip registerTableLeftTD">设置会员名</td> <td></td> </tr> <tr> <td class="registerTableLeftTD">登陆名</td> <td class="registerTableRightTD"><input id="name" name="name" placeholder="会员名一旦设置成功,无法修改" > </td> </tr> <tr> <td class="registerTip registerTableLeftTD">设置登陆密码</td> <td class="registerTableRightTD">登陆时验证,保护账号信息</td> </tr> <tr> <td class="registerTableLeftTD">登陆密码</td> <td class="registerTableRightTD"><input id="password" name="password" type="password" placeholder="设置你的登陆密码" > </td> </tr> <tr> <td class="registerTableLeftTD">密码确认</td> <td class="registerTableRightTD"><input id="repeatpassword" type="password" placeholder="请再次输入你的密码" > </td> </tr> <tr> <td colspan="2" class="registerButtonTD"> <a href="registerSuccess.jsp"><button>提 交</button></a> </td> </tr> </table> </div> </form> ~~~ ## 步骤 8 : UserService UserService新增加isExist(String name)方法 ~~~ 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); } ~~~ ## 步骤 9 : UserServiceImpl UserServiceImpl 新增isExist(String name)的实现,判断某个名称是否已经被使用过了。 ~~~ 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; } } ~~~ ## 步骤 10 : ForeController.register() **registerPage.jsp** 的form提交数据到路径 foreregister,导致ForeController.register()方法被调用 1. 通过参数User获取浏览器提交的账号密码 2. 通过HtmlUtils.htmlEscape(name);把账号里的特殊符号进行转义 3. 判断用户名是否存在 3.1 如果已经存在,就服务端跳转到reigster.jsp,并且带上错误提示信息 3.2 如果不存在,则加入到数据库中,并服务端跳转到registerSuccess.jsp页面 注:为什么要用 HtmlUtils.htmlEscape? 因为有些同学在恶意注册的时候,会使用诸如 `<script>alert('papapa')</script`> 这样的名称,会导致网页打开就弹出一个对话框。 那么在转义之后,就没有这个问题了。 注:model.addAttribute("user", null); 这句话的用处是当用户存在,服务端跳转到register.jsp的时候不带上参数user, 否则当注册失败的时候,会在原本是“请登录”的超链位置显示刚才注册的名称。 可以试试把这一条语句注释掉观察这个现象。注意在参数里有 user,就会自动放到作用域里去了。 ~~~ package com.dodoke.tmall.controller; import java.util.List; 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.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"; } } ~~~ ## 步骤 11 : registerSuccess.jsp 也是各种包含,不再赘述。 内容页面在**registerSuccessPage.jsp** ![](https://box.kancloud.cn/cfefcba200f9b6dc13eec6345d3ba8fa_429x455.png) ## 步骤 12 : registerSuccessPage.jsp 很简单,就不说了~ ![](https://box.kancloud.cn/500e6fa212a22b403e1001efeb3855b8_259x127.png) ~~~ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <div class="registerSuccessDiv"> <img src="img/site/registerSuccess.png"> 恭喜注册成功 </div> ~~~ > 自己尝试添加md5加密