代码见 https://github.com/betterGa/ChangGou

文章目录

  • 一、用户注册
    • 1、使用 ajax (POST 方法)
    • 2、使用 thymeleaf
    • 3、解决跨域问题
  • 二、用户登录
    • 1、ajax 使用 GET 方法
  • 三、商家注册
    • 1、dao、service、controller 层搭建
  • 四、商家登录
  • 五、后台管理员登录

现在整个商城系统的后端逻辑基本上都实现了,接下来需要与前端页面联调起来。

一、用户注册

用户注册需要以下信息:

(注意到 created、updated 都是不为 null 的,所以需要对 UserServiceImpl 的 add 方法进行设置:

 public void add(User user){// 设置创建时间和更新时间为当前时间Date created=new Date();Date updated=new Date();user.setCreated(created);user.setUpdated(updated);userMapper.insert(user);}


前端页面:

对应后端方法:

 /**** 新增User数据* @param user* @return*/@PostMappingpublic Result add(@RequestBody   User user){//调用UserService实现添加UseruserService.add(user);return new Result(true,StatusCode.OK,"添加成功");}

需要先对该路径进行放行:

进行测试:

接下来需要由前端传来数据。前端页面调用后端端口,使用 ajax,

1、使用 ajax (POST 方法)

使用 ajax 之前需要先导入 jquery 依赖,jQuery 是一个 JavaScript 函数库, 是一个轻量级的 “写的少,做的多” 的 JavaScript 库,其中包含 ajax 功能。在 js 文件夹下拷贝 jquery.js 文件,并且把引入 jquery.js 的 放在前面,不能写在一个标签里。

<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/javascript">

整个 script 代码:

<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/javascript">function entity(username, password, email, phone) {this.username = username;this.password = password;this.email = email;this.phone = phone;}$(function () {$('#registerBut').on('click', function () {var username = $('#username').val()var password = $('#password').val()var email = $('#email').val()var phone = $('#phone').val()returnData = new entity(username, password, email, phone);$.ajax({url: "http://localhost:18087/user",type: "POST",dataType: "JSON",contentType: "application/json;charset=UTF-8",data: JSON.stringify(returnData),success: function (result) {alert("注册成功!");},error: function (result) {console.log(result);alert("用户名重复!");},cache: false})})})
</script>

在 jquery 中,$ 是常用的一个回传函数,定义为 “选取” , 英文是 selector 的缩写,表示选取。
$.function(); 就是 选取 JQuery 定义的 function() 执行。
$('input') 就是 选取 HTML 当中全部的 input 标签。
$('#abc') 就是 选取 HTML 当中 ID 名称为 abc 的物件。
$.fn.testing = function() {} 就是 选取 JQuery 内核函数 fn (函数) 回传给 testing 这个名称、定义为一个功能 function()。
    
    把 script 标签写在 head 之后,body 之前,这样会先加载 script ,再加载页面,因为页面的 “完成登录” 按钮:

<button class="sui-btn btn-block btn-xlarge btn-danger" type="button" target="_blank"id="registerBut">完成注册</button>

JQuery 的代码通常会包裹在一个 $(function(){}) 函数中,$(function(){}) 也就是 $(document).ready(function(){}) 的简写,与之对应的原生 js 的window.onload 事件。
     注意 ,ajax 里面的 data 不能是 json 格式,否则会报 400、415 错误状态码。

2、使用 thymeleaf

访问后端端口时,渲染前端页面,使用 thymeleaf,新建子工程 changgou-web-register,因为父工程 web 工程里已经导入过 thymeleaf 依赖了,所以子工程就不需要导了(实际上清除缓存并重启了一次整个项目之后,thymeleaf 才奏效)
     此处踩了个坑,使用 thymeleaf 需要确保 Controller 类 放在与 @SpringBootApplication 注解的启动类 相同包 或者 子包 下。

@Controller@RequestMapping("/user")public class RegisterController {@CrossOrigin@GetMapping("/register")public String search() {return "register";}}

集成好 thymeleaf 后,通过后端控制层路径可以访问到前端页面了,但是现在没有加载出样式。

原先 css 路径:

 <link rel="stylesheet" type="text/css" href="../static/css/all.css" /><link rel="stylesheet" type="text/css" href="../static/css/pages-register.css" />

注意,Thymeleaf 使用的是绝对路径,而不是相对路径。
需要把路径修改为:

 <link rel="stylesheet" type="text/css" href="/css/all.css" /><link rel="stylesheet" type="text/css" href="/css/pages-register.css" />

(因为我们在 application.yml 中配置过了:

有空了去掉,再看看效果。)
同样地,jquery 的路径也需要修改:

<script type="text/javascript" src="/js/jquery.js"></script>

至此,通过 http://localhost:18094/user/register 可以访问到用户登录页面。

启动 changgou-web-register,访问 http://localhost:18094/user/register ,这时出现了问题,它弹框 “用户名重复”,而此时到数据库中查看,新增记录是成功的。
     根本原因在于,在进行 post 请求之前,进行了一次 options 请求。
     众所周知, ajax 请求是由 XMLHttpReques 对象实现的 (部分低版本ID浏览器不是), 而 XMLHttpRequest 会遵守 同源策略(same-origin policy). 也就是说,脚本只能访问 相同协议/相同主机名/相同端口 的资源, 如果要突破这个限制, 那就是所谓的 跨域 , 此时需要遵守 CORS(Cross-Origin Resource Sharing) 机制。也就是说,现在 http://localhost:18094/user/register 的 register.html 代码的 ajax 中,试图访问 http://localhost:18087/user ,跨域了。
     而在 W3C 规范中,跨域请求,分为简单请求(GET ;HEAD; POST;除了使用用户代理自动生成的 headers,或者在 Fetch 规范中定义为 “forbidden header name” 的其他 headers,只有以下 headers 被允许用作 人工地设置为 Fetch 规范定义为 “CORS-safelisted request-header” :Accept,Accept-Language,Content-Language,Content-Type;content-type 是 application/x-www-form-urlencoded、multipart 或 text/plain ;XMLHttpRequest对象发出的请求 ) 和复杂请求。而复杂请求发出之前,就会出现一次 options 请求。
(简单请求的定义见 https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#the_http_request_headers:


     options 请求是一种探测性的请求,通过这个方法,客户端可以在采取具体资源请求之前,决定对该资源采取何种必要措施,或者了解服务器的性能。
     在 ajax 中,跨域请求时,json,就属于复杂请求,因此需要提前发出一次 options 请求,用以检查请求是否是可靠安全的,如果 options 获得的回应是拒绝性质的,比如 404\403\500 等 http 状态,就会停止 post、put 等请求的发出。
    在代码中, ajax 使用的是跨域请求,而且 contentType 使用的是 application/json,归为复杂请求啦,就会在 POST 方法之前,先使用 OPTIONS ,所以会出现重复提交的情况。
    把请求整成不跨域的就OK。

3、解决跨域问题

在 UserController 上使用 @CrossOrigin 支持跨域(这里好像也是需要清除缓存、重新启动项目才能奏效 ),然后进行测试:

现在还有个问题,如果用户名重复的话:

控制台:

     后台代码并没有对这样的情况捕获异常,等之后对异常处理熟悉了之后,考虑完善这里的逻辑。
【已解决】在插入数据之前先对数据进行查询,如果已经存在记录,返回 false:

@Overridepublic boolean add(User user) {if (userMapper.selectByPrimaryKey(user) == null) {// 设置创建时间和更新时间为当前时间Date created = new Date();Date updated = new Date();// 设置用户使用状态为正常user.setStatus("1");user.setCreated(created);user.setUpdated(updated);userMapper.insert(user);return true;}// 如果数据库中已经存在用户名,返回 falsereturn false;}
 @PostMappingpublic Result add(@RequestBody   User user){//调用UserService实现添加Userboolean isInsert=userService.add(user);if(isInsert){return new Result(true,StatusCode.OK,"添加成功");}else return new Result(false,StatusCode.LOGINERROR,"添加失败,用户名重复");}

在 ajax 中修改逻辑,根据调用接口的返回值进行提示:

 $.ajax({url: "http://localhost:18087/user",type: "POST",dataType: "JSON",contentType: "application/json;charset=UTF-8",data: JSON.stringify(returnData),success: function (result) {var flag=result.flag;if(flag===true){alert("注册成功!");}else alert("用户名重复!");},error: function (result) {console.log(result);alert("访问用户注册接口失败!");},cache: false})

二、用户登录

前端登录页面是这样的:
     用户登录的逻辑是,到数据库中校验邮箱/用户名/手机号和密码,一致的话,跳转至商城首页。
     需要先提供校验的逻辑:
在 mapper 中使用 SQL 语句:

  @Select("SELECT * FROM tb_user where (password=#{password} and email=#{param1} or (password=#{password} and phone=#{param1} or (password=#{password} and username=#{param1})")void registerCheck(String param1, String password);

服务层:

@Overridepublic User registerCheck(String param1, String password) {List<User> users = userMapper.registerCheck(param1, password);// 查询无果if (users == null || users.size() == 0) return null;else return users.get(0);}

控制层:

 @GetMapping("/login")public Result registerCheck(@RequestParam(value = "param") String param1,@RequestParam("password") String password) {User user = userService.registerCheck(param1,password);if (user == null) {return new Result(false, StatusCode.ERROR, "用户不存在");} else {return new Result(true, StatusCode.OK, "用户登录校验成功", user);}}

测试结果:


需要对该路径进行放行:

1、ajax 使用 GET 方法

使用 ajax 调用该 GET 方法,并把参数传过去,data 要求为 Object 或 String 类型的参数,发送到服务器的数据。如果已经不是字符串,将自动转换为字符串格
式。get 请求中将附加在 url 后。防止这种自动转换,可以查看 processData 选项。对象必须为key/value 格式,例如 {foo1:“bar1”,foo2:“bar2”} 转换为 &foo1=bar1&foo2=bar2 。如果是数组,JQuery 将自动为不同值对应同一个名称。例如 {foo:[“bar1”,“bar2”]} 转换为 &foo=bar1&foo=bar2。

设置登录按钮:

 <button class="sui-btn btn-block btn-xlarge btn-danger" target="_blank"
id="loginBut" type="button">登&nbsp;&nbsp;录</button>

注意:这里的 type=button 是必须的,否则后续点击后无法完成跳转到其他页面。
使用 ajax 访问登录接口:

<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/javascript">$(function () {$('#loginBut').on('click', function () {$.ajax({url: "http://localhost:18087/user/login",type: "GET",dataType: "JSON",contentType: "application/json;charset=UTF-8",data: {param: $('#inputName').val(), password: $('#inputPassword').val()},success: function (result) {var flag = result.flag;if (flag === true) {var status = result.data.status;if (status == 1) {alert("登录校验成功!即将跳转至商城首页");window.location.href = "http://localhost:18086/search/list";} else {alert("用户使用状态异常,已被限制访问");}} else alert("用户不存在,请重新登录或注册!");},error: function (result) {console.log(result);alert("访问用户登录接口失败!");},cache: false})})})
</script>

三、商家注册

前端页面:

1、dao、service、controller 层搭建

数据库建表:

CREATE TABLE `tb_store` (`storename` varchar(50) NOT NULL COMMENT '商家名称',`password` varchar(100) NOT NULL COMMENT '商家密码',`invitecode` varchar(50) NOT NULL COMMENT '平台邀请码',`centerstatus` varchar(1) DEFAULT NULL COMMENT '入驻状态。1表示允许入驻,0表示未入驻',`created` datetime DEFAULT NULL COMMENT '创建时间',`updated` datetime DEFAULT NULL COMMENT '修改时间',PRIMARY KEY (`storename`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

dao 层继承通用 mapper:

public interface StoreMapper extends Mapper<Store> {}

服务层实现:

@Service
public class StoreServiceImpl implements StoreService {@AutowiredStoreMapper storeMapper;@Overridepublic boolean add(Store store) {Store storeResult = storeMapper.selectByPrimaryKey(store);if (storeResult == null) {Date date = new Date();store.setUpdated(date);store.setCreated(date);// 设置状态未入驻store.setCenterStatus("0");storeMapper.insert(store);// 插入成功return true;}// 说明商户名已存在,返回插入失败return false;}

控制层:

@RestController
@RequestMapping("/store")
public class StoreController {@AutowiredStoreService storeService;@CrossOrigin@PostMapping("/register")public Result register(@RequestBody Store store) {boolean isSuccess = storeService.add(store);if (isSuccess) {return new Result(true, StatusCode.OK, "插入商家记录成功");} else return new Result(false, StatusCode.ERROR, "用户名已存在,插入失败");}

测试结果:


ajax 逻辑:

 $.ajax({url: "http://localhost:18089/store/register",type: "POST",dataType: "JSON",contentType: "application/json;charset=UTF-8",data: JSON.stringify(returnData),success: function (result) {var flag=result.flag;if(flag===true){alert("注册成功!");}else alert("商家名重复!");},error: function (result) {console.log(result);alert("访问商家注册接口失败!");},cache: false})

四、商家登录

前端页面:

服务层实现:

@Override
public Store checkLogin(String storeName, String password) {Store store=new Store();store.setStoreName(storeName);store.setPassword(password);List<Store> storeList=storeMapper.select(store);// 查询无果if(storeList==null||storeList.size()==0){return null;}else {return storeList.get(0);}
}

控制层:

@CrossOrigin@GetMapping("/login")public Result login(@RequestParam(value = "storeName") String storename,@RequestParam(value = "password") String password) {Store store=storeService.checkLogin(storename, password);if (store!=null) {return new Result(true, StatusCode.OK, "登录成功!",store);} else {return new Result(false, StatusCode.ERROR, "登录失败,查询无果!");}}

测试结果:

前端调用 ajax 逻辑:

 $.ajax({url: "http://localhost:18089/store/login",type: "GET",dataType: "JSON",contentType: "application/json;charset=UTF-8",data: {storeName: $('#storeName').val(), password: $('#inputPassword').val()},success: function (result) {var flag = result.flag;if (flag === true) {var centerStatus = result.data.centerStatus;if (centerStatus == 1) {alert("登录校验成功!即将跳转至商家管理页面");window.location.href = "http://localhost:18086/search/list";} else {alert("商家未入驻,需等待管理员审核");}} else alert("商家不存在,请重新登录或注册!");},error: function (result) {console.log(result);alert("访问用户登录接口失败!");},cache: false})

五、后台管理员登录

不在后端代码中做逻辑判断,只是在 js 里判断用户名和密码是否同时是 “admin”,是的话登录成功,后续跳转到管理页面,否则提示登录失败。

<script type="text/javascript">function login(username, password) {if (username === 'admin' && password === 'admin') {alert('登录成功,即将进入管理页面');//window.location.href('');} else alert('请输入正确的管理员用户名和密码');}</script>

微服务商城系统 实战记录 用户、商家、后台管理员注册与登录功能实现相关推荐

  1. 微服务商城系统实战 后台管理页面、商家管理页面、商品列表跳转详情页

    文章目录 一.后台管理 1.根据点击的 div 展示相应页面 2.解决 height: 100% 不起作用问题 3. th:onclick 引用的函数参数是 model值 二.商家管理 1.th:ea ...

  2. springcloud 整合 gateway_GitHub上最火的SpringCloud微服务商城系统项目,附全套教程

    项目介绍 mall-swarm是一套微服务商城系统,采用了 Spring Cloud Greenwich.Spring Boot 2.MyBatis.Docker.Elasticsearch等核心技术 ...

  3. mall-swarm是一套微服务商城系统

    介绍: mall-swarm是一套微服务商城系统,采用了 Spring Cloud Hoxton & Alibaba.Spring Boot 2.3.Oauth2.MyBatis.Elasti ...

  4. mall-swarm微服务商城系统

    mall-swarm是一套微服务商城系统,采用了 Spring Cloud 2021 & Alibaba.Spring Boot 2.7.Oauth2.MyBatis.Docker.Elast ...

  5. 微服务商城系统(十) Spring Security Oauth2 + JWT 用户认证

    文章目录 一.用户认证分析 1.认证 与 授权 2.单点登录 3.第三方账号登录 4.第三方认证 5.认证技术方案 6.Security Oauth 2.0 入门 7. 资源服务授权 (1)资源服务授 ...

  6. 微服务商城系统(十六)秒杀核心

    代码链接: https://github.com/betterGa/ChangGou 文章目录 一.防止秒杀重复排队 二. 并发超卖问题解决 三. 订单支付 1.实现根据不同类型订单识别不同操作队列 ...

  7. 微服务商城系统(十四)微信支付

    文章目录 一.支付微服务 1.微信支付 API 2.HttpClient 工具类 3.支付微服务搭建 二.微信支付二维码生成 三.检测支付状态 四.内网穿透 五.支付结果通知 1.支付结果回调通知 2 ...

  8. 优品购电商3.0微服务商城项目实战小结

    优品购电商3.0分布式微服务项目由业务集群系统+后台管理系统构成,打通了微服务分布式开发及全栈开发技能,前后分离全栈开发.该项目是开发一个全品类的电商购物平台(B2C). 技术选型: 前端:Vue+服 ...

  9. 微服务商城系统(六)商品搜索 SpringBoot 整合 Elasticsearch

    文章目录 一.Elasticsearch 和 IK 分词器的安装 二.Kibana 使用 三.数据导入 Elasticsearch 1.SpringData Elasticsearch 介绍 2.搜索 ...

最新文章

  1. 【华为出品】智能体白皮书2020(附全文下载)
  2. 【Qt开发】【VS开发】【Linux开发】OpenCV、Qt-MinGw、Qt-msvc、VS2010、VS2015、Ubuntu Linux、ARM Linux中几个特别容易混淆的内容...
  3. JAVA实现数值的整数次方(《剑指offern》)
  4. redis集群搭建及设置账户(转)
  5. 转: ubuntu apt-get 与 aptitude 用法与区别
  6. 项目的数据存储c语言,C语言项目实战项目8__项目中学生数据的存储与重用.ppt
  7. 优化案例 | CASE WHEN进行SQL改写优化
  8. make文件基础用法
  9. 浅析云控平台画面传输的视频流方案
  10. 微服务学习之Hystrix容错保护【Hoxton.SR1版】
  11. K60(Cortex-M4)开源开发探索(一)—— K60简介
  12. FTP客户端-C++
  13. 科研工作者要会的技能----查找顶刊会议或期刊的方法
  14. 删库是不可能删库的,这辈子是不可能删库的
  15. 破解光纤入户,电信送的上海贝尔RG2000-CA,过程说明·~~
  16. 没有文件夹则创建文件夹
  17. wamp5 mysql 启动不了_wamp5安装问题之mysql无法启动
  18. JavaSE数组基础练习题
  19. 常用流程图符号和基本流程图
  20. 模拟QQ软件的基于多线程的流媒体加密传输软件技术

热门文章

  1. 春节感悟 - 成就越大的人越谦和是错觉
  2. 编译链接运行原理——(二)进程,虚拟地址空间,分段,分页机制
  3. 【小小demo】微信机器人开放接口对接
  4. 这是一个悲伤的程序员爱情故事 ? !
  5. 如何提高信奥的做题速度?
  6. 动态设置input设置只读属性
  7. 闲鱼基于Dart生态的FaaS前端一体化建设
  8. 使用事件代理实现vue的手风琴组件
  9. fmod函数 和 modf函数
  10. 2021-04 30