利用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";
}
}