本文共 19513 字,大约阅读时间需要 65 分钟。
--- 创建数据库CREATE DATABASE IF NOT EXISTS `db_test`;USE db_test;-- 管理员表CREATE TABLE IF NOT EXISTS `admin`( `aid` INT NOT NULL AUTO_INCREMENT COMMENT '管理员账号id', `name` VARCHAR(20) NOT NULL COMMENT '管理员账号id', `pwd` VARCHAR(20) NOT NULL COMMENT '管理员密码', PRIMARY KEY `pk_aid` (`aid`)) ENGINE = InnoDB;-- 用户表CREATE TABLE IF NOT EXISTS `user`( `id` INT NOT NULL AUTO_INCREMENT COMMENT '用户id', `username` VARCHAR(20) NOT NULL COMMENT '账户名', `password` VARCHAR(20) NOT NULL COMMENT '密码', `sex` CHAR(1) DEFAULT 'M' COMMENT '性别M nan F 女', `birth` DATE COMMENT '出生日期', PRIMARY KEY `pk_uid` (`id`)) ENGINE = InnoDB;INSERT INTO admin VALUES (null,'admin','admin');SELECT * FROM admin;
insert into user (id, username, password, sex, birth) values (1, 'cogles0', 'g9saZ4BJ9Xn', 'M', '2009-06-11');insert into user (id, username, password, sex, birth) values (2, 'kboor1', 'QxTltEzxz', 'F', '2005-06-23');insert into user (id, username, password, sex, birth) values (3, 'llongfield2', '5e7TH6lplp', 'F', '2006-05-16');insert into user (id, username, password, sex, birth) values (4, 'drosentholer3', 'g4f0ZKImxv', 'F', '2016-10-05');insert into user (id, username, password, sex, birth) values (5, 'asilverthorne4', 'Z5UjjX3', 'M', '2011-11-24');insert into user (id, username, password, sex, birth) values (6, 'ndigan5', 'UC7pnoJW', 'M', '2013-01-09');insert into user (id, username, password, sex, birth) values (7, 'mbriddock6', '8Ujnm0c0', 'F', '2019-06-30');insert into user (id, username, password, sex, birth) values (8, 'dsueter7', 'LpluQlPoN2kl', 'F', '2018-02-08');insert into user (id, username, password, sex, birth) values (9, 'eberzons8', 'GsEG3O1USej', 'F', '2017-08-27');insert into user (id, username, password, sex, birth) values (10, 'mkelmere9', 'gjyWR8f9f9', 'M', '2010-06-19');SELECT * FROM user;
4.0.0 org.springframework.boot spring-boot-starter-parent 2.2.5.RELEASE com.antRain restful 0.0.1-SNAPSHOT restful Demo project for Spring Boot 1.8 org.springframework.boot spring-boot-starter-thymeleaf spring-boot-starter-logging org.springframework.boot org.springframework.boot spring-boot-starter-web org.springframework.boot spring.boot.starter-logging org.mybatis.spring.boot mybatis-spring-boot-starter 2.1.2 org.springframework.boot spring-boot-devtools runtime true mysql mysql-connector-java runtime org.springframework.boot spring-boot-starter-test test org.junit.vintage junit-vintage-engine com.github.penggle kaptcha 2.3.2 org.springframework.boot spring-boot-starter-log4j2 org.springframework.boot spring-boot-maven-plugin true true
#配置端口号server.port = 8080server.tomcat.uri-encoding=UTF-8#禁用缓存spring.thymeleaf.cache=falsespring.thymeleaf.encoding=UTF-8#配置数据源spring.datasource.name=springboot-site-datasourcespring.datasource.driverClassName=com.mysql.cj.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/db_test?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&serverTimezone=UTCspring.datasource.username=rootspring.datasource.password=654321#需要实时更新的目录spring.devtools.restart.enabled=truespring.devtools.restart.additional-paths=resources/**,static/**,templates/**#配置mapper映射文件#mybatis.mapper-locations=classpath:mapper/*Mapper.xml#mybatis.type-aliases-package=com.antrain.play.beanspring.jackson.date-format=yyyy-MM-dd spring.jackson.time-zone=GMT+8mybatis.configuration.log-prefix=org.apache.ibatis.logging.log4j2.Log4j2Impl# 指定log4j2作为日志记录logging.config= classpath:log4j2-dev.xmllogging.level.com.antrain.restful.mapper =# 版本需要手动开启配置 restful put delete 有效spring.mvc.hiddenmethod.filter.enabled = true
package com.antrain.restful;import org.mybatis.spring.annotation.MapperScan;import org.springframework.boot.Banner;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@MapperScan("com.antrain.restful.mapper")@SpringBootApplicationpublic class RestfulApplication { public static void main(String[] args) { SpringApplication application = new SpringApplication(RestfulApplication.class); application.setBannerMode(Banner.Mode.OFF);//关闭 application.run(args); }}
package com.antrain.restful.util;import java.io.Serializable;import java.util.List;public class PageResult implements Serializable { private int totalCount; //总记录数 private int pageSize; //每页记录数 private int totalPage;//总页数 private int currPage;//当前页数 private List list;//列表数据 /** * 分页 * * @param list 列表数据 * @param totalCount 总记录数 * @param pageSize 每页记录数 * @param currPage 当前页数 */ public PageResult(List list, int totalCount, int pageSize, int currPage) { this.list = list; this.totalCount = totalCount; this.pageSize = pageSize; this.currPage = currPage; this.totalPage = (int) Math.ceil((double) totalCount / pageSize); } public int getTotalCount() { return totalCount; } public void setTotalCount(int totalCount) { this.totalCount = totalCount; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public int getTotalPage() { return totalPage; } public void setTotalPage(int totalPage) { this.totalPage = totalPage; } public int getCurrPage() { return currPage; } public void setCurrPage(int currPage) { this.currPage = currPage; } public List getList() { return list; } public void setList(List list) { this.list = list; } @Override public String toString() { return "PageResult{" + "totalCount=" + totalCount + ", pageSize=" + pageSize + ", totalPage=" + totalPage + ", currPage=" + currPage + ", list=" + list + '}'; }}
package com.antrain.restful.util;import java.util.LinkedHashMap;import java.util.Map;public class PageUtil extends LinkedHashMap{ private int offset;//偏移量 private int page;//当前页码 private int limit;//每页条数 public PageUtil(Map params) { this.putAll(params); //分页参数 this.offset = Integer.parseInt(params.get("offset").toString()); this.limit = Integer.parseInt(params.get("limit").toString()); this.page = offset/(limit+1); this.put("offset", offset); this.put("page", page); this.put("limit", limit); } public int getPage() { return page; } public void setPage(int page) { this.page = page; } public int getLimit() { return limit; } public void setLimit(int limit) { this.limit = limit; } public int getOffset() { return offset; } public void setOffset(int offset) { this.offset = offset; } @Override public String toString() { return "PageUtil{" + "offset=" + offset + ", page=" + page + ", limit=" + limit + '}'; }}
package com.antrain.restful.mapper;import com.antrain.restful.entity.Admin;import org.apache.ibatis.annotations.Select;import org.springframework.stereotype.Component;@Componentpublic interface AdminMapper { @Select("SELECT * FROM admin WHERE name=#{name} AND pwd =#{pwd}") Admin login(String name, String pwd);}
package com.antrain.restful.mapper;import com.antrain.restful.entity.User;import org.apache.ibatis.annotations.Delete;import org.apache.ibatis.annotations.Insert;import org.apache.ibatis.annotations.Select;import org.apache.ibatis.annotations.Update;import org.springframework.stereotype.Component;import java.util.List;import java.util.Map;@Componentpublic interface UserMapper { @Insert("insert into "+ " user(id, username, password, sex, birth)"+ "values (null, #{username,jdbcType=VARCHAR}, " + "#{password,jdbcType=VARCHAR}, #{sex,jdbcType=CHAR},#{birth, jdbcType=DATE} );") int insert(User user); @Delete("DELETE FROM user WHERE id=#{id};") int del(int id); @Update("UPDATE user SET username=#{username,jdbcType=VARCHAR}, password=#{password,jdbcType=VARCHAR} ,"+ " sex= #{sex,jdbcType=CHAR},birth=#{birth,jdbcType=DATE} WHERE id=#{id,jdbcType=INTEGER};") int update(User user); @Select("SELECT * FROM user WHERE id=#{id};") User queryById(int id); @Select("SELECT * FROM user ;") ListqueryAll(); @Select(" ") List getBatch(Map params); @Select("select count(*) from user") int getTotal();}
package com.antrain.restful.service.impl;import com.antrain.restful.entity.User;import com.antrain.restful.mapper.UserMapper;import com.antrain.restful.service.UserService;import com.antrain.restful.util.PageResult;import com.antrain.restful.util.PageUtil;import org.springframework.stereotype.Service;import javax.annotation.Resource;import java.util.List;@Servicepublic class UserServiceImpl implements UserService { @Resource private UserMapper userMapper; @Override public int insert(User user) { return userMapper.insert(user); } @Override public int del(int id) { return userMapper.del(id); } @Override public int update(User user) { return userMapper.update(user); } @Override public User queryById(int id) { return userMapper.queryById(id); } @Override public ListqueryAll() { return userMapper.queryAll(); } @Override public PageResult queryUsers(PageUtil pageUtil) { List users = userMapper.getBatch(pageUtil); int total = userMapper.getTotal(); PageResult pageResult = new PageResult(users, total, pageUtil.getLimit(), pageUtil.getPage()); return pageResult; }}
AdminLoginInterceptorpackage com.antrain.restful.filter;import org.springframework.stereotype.Component;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;@Componentpublic class AdminLoginInterceptor implements HandlerInterceptor { /** * 在DispatcherServlet之前执行。 * */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception { String uri = request.getRequestURI(); if (uri.startsWith("/admin") && null == request.getSession().getAttribute("loginUser")&&uri.endsWith("/admin/login")==false) { request.getSession().setAttribute("errorMsg", "请重新登陆"); response.sendRedirect(request.getContextPath() + "/admin/login"); return false; } else { request.getSession().removeAttribute("errorMsg"); return true; } } /** * 在controller执行之后的DispatcherServlet之后执行。 * */ @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { } /** * 在页面渲染完成返回给客户端之前执行。一般用于资源清理操作 * */ @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { }}
package com.antrain.restful.config;import com.antrain.restful.filter.AdminLoginInterceptor;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.*;@Configurationpublic class SiteWebMvcConfigurer implements WebMvcConfigurer { private final AdminLoginInterceptor adminLoginInterceptor; @Autowired public SiteWebMvcConfigurer(AdminLoginInterceptor adminLoginInterceptor) { this.adminLoginInterceptor = adminLoginInterceptor; } @Override public void addInterceptors(InterceptorRegistry registry) { // 添加一个拦截器,拦截以/admin为前缀的url路径 registry.addInterceptor(adminLoginInterceptor).addPathPatterns("/admin/**") .excludePathPatterns("/admin/login"); } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { //使外部能访问静态资源 registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/"); }}
package com.antrain.restful.controller;import com.antrain.restful.entity.Admin;import com.antrain.restful.service.AdminService;import org.springframework.stereotype.Controller;import org.springframework.util.StringUtils;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import java.util.Map;@Controller@RequestMapping("/admin")public class AdminController { @Resource private AdminService adminService; @GetMapping("/login") public String login(){ return "admin/login"; } @PostMapping("/login") public String login(@RequestParam("userName") String userName, @RequestParam("password") String password, Mapmap, HttpSession session){ if (StringUtils.isEmpty(userName) || StringUtils.isEmpty(password)) { map.put("errorMsg", "用户名或密码不能为空"); return "admin/login"; } Admin adminUser = adminService.login(userName, password); if (adminUser != null) { session.setAttribute("loginUser", adminUser.getName()); session.setAttribute("loginUserId", adminUser.getAid()); //session过期时间设置为7200秒 即两小时 session.setMaxInactiveInterval(60 * 60 * 2); return "redirect:/admin/index"; } else { map.put("errorMsg", "登陆失败"); return "admin/login"; } } @GetMapping({ "", "/", "/index", "/index.html"}) public String index(HttpServletRequest request) { request.setAttribute("path", "index"); return "admin/index"; }}
package com.antrain.restful.controller;import com.antrain.restful.entity.User;import com.antrain.restful.service.UserService;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;@Controller@RequestMapping("/admin")public class UserController { @Resource private UserService userService; @GetMapping("/users") public String list(Model model){ model.addAttribute("users",userService.queryAll()); return "admin/list"; } @GetMapping("/user") public String toAdd(Model model){ return "admin/add"; } @PostMapping("/user") public String add(User user){ System.out.println(user); userService.insert(user); return "redirect:/admin/users"; } @GetMapping("/user/{id}") public String toEdit(@PathVariable("id") Integer id, Model model){ model.addAttribute("user",userService.queryById(id)); return "admin/add"; } @PutMapping("/user") public String update(@RequestBody User user){ System.out.println(user); userService.update(user); System.out.println("修改"); return "redirect:/admin/users"; } @DeleteMapping("/user/{id}") public String del(@PathVariable("id") Integer id){ userService.del(id); return "redirect:/admin/users"; }}
1. 原因:使用restful的put delete 方法无效2. 解决:在配置加入:# 版本需要手动开启配置 restful put delete 有效spring.mvc.hiddenmethod.filter.enabled = true
// 问题代码 @PutMapping("/user") public String update(@RequestBody User user){ userService.update(user); return "redirect:/admin/users"; } // 参考:https://blog.csdn.net/feiyst/article/details/88431621 // 解决:去掉@RequestBody即可