restful风格设计API的特点:
1)使用JSON来进行传递数据
2)使用不同的HTTP方法来进行描述不同的操作
3)使用HTTP状态码来进行表示返回结果是否正确
4)使用路径表示要进行操作的资源是什么
1)创建一个SpringBoot项目
2)编写对应的配置文件,数据库的配置文件
3)编写对应的SQL语句:
当时我们工大有一家店叫做吉祥馄沌,老板还是使用手工记账的方式来进行记账,我就和老板商量了一下要做一个点餐系统出来
drop database if exists OrderDish; create database if not exists OrderDish; use OrderDish; drop table if exists User; create table User( userID int primary key auto_increment, userName varchar(50), passWord varchar(100), isAdmin int default 0 ); drop table if exists Dish; create table Dish( dishID int primary key auto_increment, dishName varchar(50), dishMoney int ); drop table if exists Order_User; create table Order_User( orderID int primary key auto_increment, userID int, isDown int, orderTime timeStamp, foreign key Order_User(userID) references User(userID) ); drop table if exists Order_Dish; create table order_Dish( orderID int, dishID int, foreign key(orderID) references Order_User(orderID), foreign key(dishID) references Dish(dishID) );4)创建对应的实体类
@Data public class Dish {private int dishID;private String dishName;private String dishMoney; }@Data public class Order {private int orderID;private int userID;private ListdishList;private int isDown;private Timestamp timestamp; }@Data public class User {private int userID;private String userName;private String passWord;private int isAdmin; } 约定前后端交互的接口:
1){}表示一个JSON对象,他是一个键值对结构,里面包含了若干个键值对,键值对之间使用,进行分割,键和值之间使用:来进行分割,这里面的键必须是字符串
2.[]用来表示一个数组,里面包含了若干个元素,每一个元素可以是整数,字符串,或者是JSON对象
我们在这里面要用到11个API,需要约定前后端的接口;
1)用户管理:注册,登录,检测登陆状态,注销
2)菜品管理:新增菜品,查看菜品,删除菜品
3)订单管理:新增订单(用户在这里面点菜),查看指定订单,查看所有订单,修改状态
1)实现注册功能:
约定前后端交互的接口: POST /resigter HTTP/1.1 contentType:application/json;{"userName":"李佳伟","passWord":"778896","isAdmin":"0" }注册成功的时候: {"data": 1,"message": "注册成功" } 注册失败的时候: {"data": -1,"message": "当前前段传递的用户名重复" }2)后端代码:
@RestController @RequestMapping("/Java100") public class XMLController {@AutowiredXMLMapper mapper;Logger logger= LoggerFactory.getLogger(XMLController.class);@RequestMapping("/resigter")public HashMapAddUser(@RequestBody User RequestUser){ //1.进行前端校验参数String username=RequestUser.getUserName();System.out.println(username);String password=RequestUser.getPassWord();System.out.println(password);HashMap result=new HashMap<>();int data=0;String message="";if(username==null||username.equals("")||password==null||password.equals("")){data=0;message="当前前端传递的用户名和密码有一个为空";}else { //2.进行判断用户名是否重复User user = mapper.selectUserByUserName(username);if (user!=null){data=-1;message="当前前段传递的用户名重复";}else { //3.进行密码加密操作;String finalPassword = encrypt.AddPassword(password); //4将加密之后的密码和用户名传入到数据库里面RequestUser.setPassWord(finalPassword);int len = mapper.addUser(RequestUser);if (len == 1) {message = "注册成功";data = 1;} else {message = "注册失败";data = -1;}}}result.put("data",data);result.put("message",message);return result;} } 2)实现登陆功能:必须只有管理员才可以进行登录,这个是在后端根据用户名来进行查询的;
进行密码加密操作:
public class encrypt {public static String AddPassword(String password){//进行参数校验if(!StringUtils.hasLength(password)){return "";}//1.先得到盐值String salt= IdUtil.simpleUUID();//2.对密码进行加密String finalPassWord= SecureUtil.md5(salt+password);//3.进行最终密码拼装return salt+"@"+finalPassWord;}public static boolean SubPassword(String password,String finalPassword){String[] strings=finalPassword.split("@");System.out.println(finalPassword);String salt=strings[0];String extPassWord=strings[1];String linPassword=SecureUtil.md5(salt+password);System.out.println(linPassword);if(linPassword.equals(extPassWord)) return true;return false;} }进行登录操作:
@RequestMapping("/login")public HashMaplogin(@RequestBody User user, HttpServletRequest req){//1.进行用户名和密码的校验String username=user.getUserName();String password=user.getPassWord();int data=-1;String message="";//2.进行密码解迷和判断当前是否是管理员User loginUser= mapper.selectUserByUserName(username);if(loginUser==null||loginUser.equals("")){data=-1;message="当前没有这个用户";}else{//判断当前是不是管理员if(loginUser.getIsAdmin()==0){data=-1;message="您不是管理员";}else{//进行密码解密操作boolean flag=encrypt.SubPassword(user.getPassWord(),loginUser.getPassWord());if(flag==true){data=1;message="登陆成功";HttpSession httpSession=req.getSession(true);httpSession.setAttribute("user",loginUser);}else{data=-1;message="登陆失败";}}}HashMap result=new HashMap<>();result.put("data",data);result.put("message",message);return result;}} 3)监测登录状态(通过拦截器已经进行实现)
4)实现注销功能:
@RequestMapping("/logout")public void logout(HttpServletRequest req){//1.进行注销HttpSession httpSession=req.getSession(false);//2.删除session对象httpSession.removeAttribute("user");}5)新增菜品:只有管理员才可以进行新增菜品,普通用户不可以进行新增菜品
约定前后端交互的接口:
前端传递: {"dishMoney":"90","dishName":"红烧茄子" } 后端接收: {"data": 1,"message": "新增菜品成功" }6)菜品管理:删除菜品:还是只有管理员才可以进行删除菜品,普通用户不可以进行删除菜品
前端:POST 127.0.0.1:8080/Java100/deleteDish?dishID=1 HTTP/1.1删除成功的时候: {"data": 1,"message": "删除菜品成功" } 删除失败的时候: {"data": -1,"message": "删除菜品失败" }@RequestMapping("/deleteDish")public HashMapdeleteDish(Integer dishID,HttpServletRequest req){//1.进行前端参数校验int data=-1;String message="";if(dishID==null||dishID.equals("")){data=-1;message="当前前段传递的message为空";}else{//判断当前登录的人是否是管理员HttpSession httpSession=req.getSession(false);User user= (User) httpSession.getAttribute("user");if(user.getIsAdmin()==0){data=-1;message="您当前不是管理员,无法进行删除菜品操作";}else{int len= mapper.deleteDish(dishID);if(len==1){data=1;message="删除菜品成功";}else {data = -1;message = "删除菜品失败";}}}HashMap hashMap=new HashMap<>();hashMap.put("data",data);hashMap.put("message",message);return hashMap;} 7)查看菜品:普通用户和管理员都可以查看所有菜品
约定前后端交互的接口:
GET 127.0.0.1:8080/Java100/getAllDish HTTP/1.1 [{"dishID": 2,"dishName": "红烧茄子","dishMoney": "90"},{"dishID": 3,"dishName": "红烧里脊","dishMoney": "100"} ]@RequestMapping("/getAllDish")public ListGetAllDish(){return mapper.SelectAllDish();} 之前用户表和菜品表的所有XML:
insert into User values(null,#{userName},#{passWord},#{isAdmin}); insert into Dish values(null,#{dishName},#{dishMoney}); delete from Dish where dishID=#{dishID} update set dishMoney=#{dishMoney} where dishID=#{dishID}
8)新增订单:
约定前后端交互的接口: 前端用户是要进行点菜的,肯定要进行选中菜品,所以前端给后端传递过来的肯定是一大堆的菜品ID 我们的后端要根据这些菜品ID生成一个订单 前段传递的参数: {"list":"2,3,4,5" }{"data": 1,"message": "订单插入成功" }后端代码:
@RequestMapping("/addOrder")@Transactionalpublic HashMapaddOrder(@RequestBody HashMap hashMap,HttpServletRequest req){ //将前端传递的字符串转化成JSON数组List dishIDList=new ArrayList<>();String list=hashMap.get("list");System.out.println(list);String[] strings=list.split(",");for(String string:strings){dishIDList.add(Integer.parseInt(string));}//1.先进行插入订单用户表,拿到生成的订单IDHttpSession httpSession=req.getSession(false);User loginUser= (User) httpSession.getAttribute("user");Order order=new Order();order.setDishList(dishIDList);order.setIsDown(0);order.setTimeStamp(new Timestamp(System.currentTimeMillis()));order.setUserID(loginUser.getUserID());mapper.addOrderUser(order);//2.再继续进行插入订单-菜品表//我们在这里面要进行循环插入,因为有多个菜品mapper.addOrderDish(dishIDList,order.getOrderID());int data=1;String message="订单插入成功";HashMap result=new HashMap<>();result.put("data",data);result.put("message",message);return result;} 对应的XML的代码:
insert into order_user values(null,#{userID},#{timeStamp}); insert into order_dish (#{orderID},#{dishID}) 9)查看订单(管理员可以查看所有订单,用户可以查看指定用户的订单),但是从这方面来说无论是管理员和用户,看到的都是多个订单)
我们在这里面查询订单,只是看一下订单的大致信息,比如说订单下单时间,订单的是否完成状态,订单的ID,订单的UserID
约定前后端交互的接口:
GET 127.0.0.1:8080/Java100/SelectAllOrder HTTP/1.1响应: [{"orderID": 7,"userID": 1,"dishList": null,"isDown": 0,"timeStamp": null},{"orderID": 8,"userID": 1,"dishList": null,"isDown": 0,"timeStamp": null} ]//1)如果是管理员,那么可以看到所有用户的订单 //2)如果是普通用户,那么只能看到自己的订单 //3)我们可以根据HttpSession中的User对象,也就是里面的isAdmin来进行判断@RequestMapping("/SelectAllOrder")public ListSelectAllOrder(HttpServletRequest req){//1.进行判断当前用户是管理员,还是普通用户,因为最终返回的肯定是一个订单列表HttpSession httpSession=req.getSession(false);User user= (User) httpSession.getAttribute("user");List list=null;if(user.getIsAdmin()==0){list= mapper.SelectAllOrder();}else{list=mapper.SelectOneAllOrder(user.getUserID());}//2.返回数据return list;} 10)查看指定订单详情:我们之前给用户显示的是一个一个的订单列表,当我们想看某一个订单的时候,就会给后端传递一个订单ID
约定前后端交互的接口: GET 127.0.0.1:8080/Java100/GetDetailOrder?orderID=7 HTTP/1.1返回响应: {"data": 1,"returnResult": [{"dishID": 2,"dishName": "红烧茄子","dishMoney": "90"},{"dishID": 3,"dishName": "红烧里脊","dishMoney": "100"},{"dishID": 4,"dishName": "红烧牛肉","dishMoney": "700"},{"dishID": 5,"dishName": "牛肉干","dishMoney": "70"}],"message": "当前用户查询所有订单成功" }@RequestMapping("/GetDetailOrder")public HashMapGetDetailOrder(Integer orderID){//1.进行前端参数校验HashMap result = new HashMap<>();int data=-1;String message="";List list=null;List dishList=null;if(orderID==null||orderID.equals("")){data=-1;}else {//2.进行数据库查询//2.1先根据orderID来进行查询到所有的菜品信息list = mapper.SelectAllDishIDs(orderID);//2.2再根据里面所有的dishID查询所有的DishdishList = mapper.SelectAllDishByDishIDTwo(list);//3.统一返回数据封装结果data=1;message="当前用户查询所有订单成功";}result.put("data",data);result.put("message",message);result.put("returnResult",dishList);return result;} } 11)修改订单状态:我们在这里面约定只有管理员才可以进行修改订单状态
约定前后端交互的接口:我们要给后端传递一个orderID和isDone,后端根据这个来进行修改
前端:GET /UpdateState?orderID=1?isDone=1 响应: {"OK":1,"message":"修改订单状态成功" }@RequestMapping("/UpdateState")public HashMapUpdateState(@RequestBody HashMap hashMap,HttpServletRequest req){//1.先进行获取到前端的参数并进行校验int data=1;String message="";HashMap result=new HashMap<>();Integer isDone=hashMap.get("isDone");Integer orderID=hashMap.get("orderID");if(isDone==null||isDone.equals("")||orderID==null||orderID.equals("")){data=-1;message="前端传低参数有问题";}else {//2.判断当前登录的人是不是管理员HttpSession httpSession = req.getSession(false);User user = (User) httpSession.getAttribute("user");if (user.getIsAdmin() == 0) {data = -1;message = "您当前并不是管理员请进行登录";} else {int len = mapper.UpdateState(isDone, orderID);if (len == 1) {data = 1;message = "修改成功";} else {data = -1;message = "修改失败";}}}result.put("data",data);result.put("message",message);return result;} }