利用SpringBoot实现RestFul风格的增删改查操作
会遇到的问题:1、在提交delete请求时,可能会报405错误,解决办法在配置文件中加入在配置文件中加入spring.mvc.hiddenmethod.filter.enabled=true启用隐藏方法过滤器
2、可能会遇到Error creating bean with name ‘requestMappingHandlerMapping‘ defined in class path resource ,解决办法:自己检查controller的请求头是不是有重复的
说明:这个小项目没有使用数据库,利用map容器模拟了几条数据。我是在b站上学习了尚硅谷的SpringBoot教程。
开搞~!!!
我的环境(idea 2019.3.3、maven3.6)
准备工作:
一、准备好静态页面(bootstrap中文网很多)
二、创建一个SpringBoot工程,加入Web、Thymeleaf依赖。
三、引入静态资源,页面放在templates文件夹下,*.js、*.css和图片放在static文件夹下
四、修改页面,因为使用了Thymeleaf模板引擎,为了保证正常使用时有提示,在页面html标签中加入
xmlns:th="http://www.thymeleaf.org"
修改静态资源的超链接格式举例:
<link th:href="@{/asserts/css/bootstrap.min.css}" rel="stylesheet">
根据自己下载的页面选择是否抽取公共页面,thymeleaf抽取页面的三种格式
th:insert:将公共片段整个插入到声明引入的元素中,带div标签
th:replace:将声明引入的元素替换为公共片段,不带div标签
th:include:将被引入的片段的内容包含进这个标签中,带div标签但是不带公共片段的标签头,也就是直接将内容放进一个div中
<footer th:fragment="copy"> © 2011 The Good Thymes Virtual Grocery </footer> 引入方式 <div th:insert="footer :: copy"></div> <div th:replace="footer :: copy"></div> <div th:include="footer :: copy"></div> 效果 <div> <footer> © 2011 The Good Thymes Virtual Grocery </footer> </div> <footer> © 2011 The Good Thymes Virtual Grocery </footer> <div> © 2011 The Good Thymes Virtual Grocery </div>
五、准备实体类、持久层接口(本项目业务简单,暂时不加业务层)
Employee实体类(构造器、gette/setter方法省略)
private Integer id; private String lastName; private String email; //1 男, 0 女 private Integer gender; private Department department; private Date birth;
Department实体类
private Integer id; private String departmentName;
EmployeeDao接口
@Repository public class EmployeeDao { private static Map<Integer, Employee> employees = null; @Autowired private DepartmentDao departmentDao; static{ employees = new HashMap<Integer, Employee>(); employees.put(1001, new Employee(1001, "E-AA", "", 1, new Department(101, "D-AA"))); employees.put(1002, new Employee(1002, "E-BB", "", 1, new Department(102, "D-BB"))); employees.put(1003, new Employee(1003, "E-CC", "", 0, new Department(103, "D-CC"))); employees.put(1004, new Employee(1004, "E-DD", "", 0, new Department(104, "D-DD"))); employees.put(1005, new Employee(1005, "E-EE", "", 1, new Department(105, "D-EE"))); } private static Integer initId = 1006; public void save(Employee employee){ if(employee.getId() == null){ employee.setId(initId++); } employee.setDepartment(departmentDao.getDepartment(employee.getDepartment().getId())); employees.put(employee.getId(), employee); } public Collection<Employee> getAll(){ return employees.values(); } public Employee get(Integer id){ return employees.get(id); } public void delete(Integer id){ employees.remove(id); } }
DepartmentDao
@Repository public class DepartmentDao { private static Map<Integer, Department> departments = null; static{ departments = new HashMap<Integer, Department>(); departments.put(101, new Department(101, "D-AA")); departments.put(102, new Department(102, "D-BB")); departments.put(103, new Department(103, "D-CC")); departments.put(104, new Department(104, "D-DD")); departments.put(105, new Department(105, "D-EE")); } public Collection<Department> getDepartments(){ return departments.values(); } public Department getDepartment(Integer id){ return departments.get(id); } }
准备工作差不多了,接下就是编写CRUD
一、
1、做一个用户名密码校验
@Controller public class LoginController { @PostMapping("/user/login") // @RequestMapping(value = "/user/login",method = RequestMethod.POST) public String login(@RequestParam("username") String username,@RequestParam("password") String password, Map<String,Object> map,HttpSession session ){ if(!StringUtils.isEmpty(username)&&"123".equals(password)){ // 登陆成功,防止表单重复提交,可以重定向到主页 session.setAttribute("loginUser",username); return "redirect:/main.html"; }else{ map.put("msg","用户名或密码错误"); return "login"; } } }
2、做一个非法请求过滤
/** * 登录检查 */ public class LoginHandlerInterceptor implements HandlerInterceptor { @Override // 执行前 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Object loginUser = request.getSession().getAttribute("loginUser"); if (loginUser == null) { // 未登录,返回登录页 request.setAttribute("msg", "没有权限请先登录"); request.getRequestDispatcher("/index.html").forward(request, response); return false; } else { // 已登录,放行 return true; } } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }
配置完记得在@Configuration标识的配置类中注册
CRUD代码比较简单,直接贴代码
@Controller public class EmployeeController { @Autowired EmployeeDao employeeDao; @Autowired DepartmentDao departmentDao; // 查询所有员工返回列表页面 @GetMapping("emps") public String list(Model model) { Collection<Employee> all = employeeDao.getAll(); // 放在请求域中 model.addAttribute("emps", all); return "emp/list"; } // 来到员工添加页面 @GetMapping("/emp") public String toAddPage(Model model) { // 去添加页面之前,先查出所有部门在页面显示 Collection<Department> departments = departmentDao.getDepartments(); model.addAttribute("depts", departments); return "emp/add"; } // 员工添加 // SpringMVC 自动将请求参数和入参对象的属性进行一一绑定:要求了请求参数的名字和JavaBean入参对象里面的属性名是一样的 @PostMapping("/emp") public String AddEmp(Employee employee) { // 添加完成后来到员工列表页面 System.out.println("保存的员工信息"+employee); employeeDao.save(employee); // redirect: 表示重定向到一个地址 / 代表当前项目路径 // forward:表示转发到一个地址 return "redirect:/emps"; } // 去修改页面,查出信息并回显 @GetMapping("/emp/{id}") public String toEditPaage(@PathVariable("id") Integer id ,Model model){ Employee employee = employeeDao.get(id); model.addAttribute("emp",employee); // 页面要显示所有的部门列表 Collection<Department> departments = departmentDao.getDepartments(); model.addAttribute("depts", departments); // 回到修改页面(add是一个修改添加二合一的页面) return "emp/add"; } // 员工修改:需要提交员工id @PutMapping("/emp") public String updateEmployee(Employee employee){ System.out.println("修改的数据"+employee); employeeDao.save(employee); return "redirect:/emps"; } // 员工删除 @DeleteMapping("/emp/{id}") public String deleteEmployee(@PathVariable("id") Integer id){ employeeDao.delete(id); return "redirect:/emps"; } }