zoukankan      html  css  js  c++  java
  • SpringBoot实现restuful风格的CRUD

    restuful风格:

    百度百科:

    RESTFUL是一种网络应用程序的设计风格和开发方式,基于HTTP,可以使用XML格式定义或JSON格式定义。RESTFUL适用于移动互联网厂商作为业务使能接口的场景,实现第三方OTT调用移动网络资源的功能,动作类型为新增、变更、删除所调用资源。 

    RESTFUL特点
    1、每一个URI代表1种资源;
    2、客户端使用GET、POST、PUT、DELETE4个表示操作方式的动词对服务端资源进行操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源;
    3、通过操作资源的表现形式来操作资源;
    4、资源的表现形式是XML或者HTML;
    5、客户端与服务端之间的交互在请求之间是无状态的,从客户端到服务端的每个请求都必须包含理解请求所必需的信息。
     
    规范列表:
     

    由于采用的是thymeleaf+bootstarp(springBoot)的结构实现

    所以对于一些公共片段的抽取必须得满足thymeleaf的语法规则:

    抽取:

     引入:

     三种引入的效果:

     详见:https://www.thymeleaf.org/

    工程结构:

    登录拦截器:LoginHanderInterceptor

    package com.zyb.webdemo.handlerInterceptor;
    
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * 登陆拦截器
     */
    public class LoginHanderInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            Object isLogin=request.getSession().getAttribute("isLogin");
            //没有登陆直接进主页
            if(isLogin==null){
                request.setAttribute("msg","没有权限请登录");
                request.getRequestDispatcher("/login").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 {
    
        }
    }

    员工操作控制器代码:EmployeeController

    package com.zyb.webdemo.controller;
    
    import com.zyb.webdemo.dao.DepartmentDao;
    import com.zyb.webdemo.dao.EmployeeDao;
    import com.zyb.webdemo.entities.Department;
    import com.zyb.webdemo.entities.Employee;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.*;
    
    import java.util.Collection;
    import java.util.Collections;
    
    @Controller
    public class EmployeeController {
    
        @Autowired
        EmployeeDao employeeDao;
        @Autowired
        DepartmentDao departmentDao;
        //返回员工列表页面
        @GetMapping("/emps")
        public String list(Model model){
            //thymeleaf默认就会拼串
            //前缀:classpath:/templates/
            //后缀:.html
            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){
            //redirect:重定向
            //forword:转发
            //System.out.println("员工信息:"+employee);
            //保存员工
            employeeDao.save(employee);
            return "redirect:/emps";
        }
    
        @GetMapping("/emp/{id}")
        public String toEditPage(@PathVariable("id") Integer id,
                                 Model model){
            Employee employee = employeeDao.get(id);
            model.addAttribute("emp",employee);
    
            Collection<Department> departments = departmentDao.getDepartments();
            model.addAttribute("depts",departments);
            //回到修改界面
            return "emp/edit";
        }
    
        //员工修改
        @PutMapping("/emp")
        public String updateEmployee(Employee employee){
            employeeDao.save(employee);
            return "redirect:/emps";
        }
        @DeleteMapping("/emp/{id}")
        public String deleteEmployee(@PathVariable("id") Integer id){
        employeeDao.delete(id);
        return "redirect:/emps";
        }
    }

    MySpringMvcConfig的配置:

    package com.zyb.webdemo.config;
    
    
    import com.zyb.webdemo.component.MyLocaleResolver;
    import com.zyb.webdemo.handlerInterceptor.LoginHanderInterceptor;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.LocaleResolver;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    @Configuration
    //2.0之后直接实现 WebMvcConfigurer就行
    public class MySpringmvcConfig implements WebMvcConfigurer {
        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
            registry.addViewController("/").setViewName("login");
            registry.addViewController("/login").setViewName("login");
            registry.addViewController("/main").setViewName("dashboard");//后面自动加html
        }
    
        //注册拦截器
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new LoginHanderInterceptor()).addPathPatterns("/**")
                    .excludePathPatterns("/login","/user/login","/","/assert/**","/webjars/**");
        }
    
    
        @Bean//将组件注册在容器中
        public LocaleResolver localeResolver(){
    
            return new MyLocaleResolver();
        }
    
    }

    因为浏览器不直接支持put、delete的请求,所以需要post请求作为中间请求进行变换

    edit.html:(修改页面)

    <!DOCTYPE html>
    <!-- saved from url=(0052)http://getbootstrap.com/docs/4.0/examples/dashboard/ -->
    <html lang="en"  xmlns:th="http://www.thymeleaf.org">
    
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <meta name="description" content="">
        <meta name="author" content="">
    
        <title>Dashboard Template for Bootstrap</title>
        <!-- Bootstrap core CSS -->
        <link href="../../static/asserts/css/bootstrap.min.css" th:href="@{/asserts/css/bootstrap.min.css}" rel="stylesheet">
    
        <!-- Custom styles for this template -->
        <link href="../../static/asserts/css/dashboard.css" th:href="@{/asserts/css/dashboard.css}" rel="stylesheet">
        <style type="text/css">
            /* Chart.js */
    
            @-webkit-keyframes chartjs-render-animation {
                from {
                    opacity: 0.99
                }
                to {
                    opacity: 1
                }
            }
    
            @keyframes chartjs-render-animation {
                from {
                    opacity: 0.99
                }
                to {
                    opacity: 1
                }
            }
    
            .chartjs-render-monitor {
                -webkit-animation: chartjs-render-animation 0.001s;
                animation: chartjs-render-animation 0.001s;
            }
        </style>
    </head>
    
    <body>
    <!--    引入头部搜索栏-->
    <div th:replace="~{commons/common::topbar}"></div>
    
    <div class="container-fluid">
        <div class="row">
            <div th:replace="~{commons/common::#menu(activeUri='emplist')}"></div>
    
            <main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
                <form th:action="@{/emp}" method="post">
                    <!--发送put请求修改员工数据-->
                    <!--
                    1、SpringMVC中配置HiddenHttpMethodFilter;(SpringBoot自动配置好的)
                    2、页面创建一个post表单
                    3、创建一个input项,name="_method";值就是我们指定的请求方式
                    -->
                    <input type="hidden" name="_method" value="put" />
                    <input type="hidden" name="id"  th:value="${emp.id}">
                    <div class="form-group">
                        <label>LastName</label>
                        <input name="lastName" type="text" class="form-control" placeholder="zhangsan" th:value="${emp.lastName}">
                    </div>
                    <div class="form-group">
                        <label>Email</label>
                        <input name="email" type="email" class="form-control" placeholder="zhangsan@atguigu.com" th:value="${emp.email}">
                    </div>
                    <div class="form-group">
                        <label>Gender</label><br/>
                        <div class="form-check form-check-inline">
                            <input class="form-check-input" type="radio" name="gender" value="1" th:checked="${emp.gender==1}">
                            <label class="form-check-label"></label>
                        </div>
                        <div class="form-check form-check-inline">
                            <input class="form-check-input" type="radio" name="gender" value="0" th:checked="${emp.gender==0}">
                            <label class="form-check-label"></label>
                        </div>
                    </div>
                    <div class="form-group">
                        <label>department</label>
                        <!--提交的是部门的id-->
                        <select class="form-control" name="department.id">
                            <option th:selected="${dept.id == emp.department.id}" th:value="${dept.id}" th:each="dept:${depts}" th:text="${dept.departmentName}">1</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <label>Birth</label>
                        <input name="birth" type="text" class="form-control" placeholder="zhangsan" th:value="${#dates.format(emp.birth, 'yyyy-MM-dd')}">
                    </div>
                    <button type="submit" class="btn btn-primary" >修改</button>
                </form>
    
            </main>
        </div>
    </div>
    
    <!-- Bootstrap core JavaScript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script type="text/javascript" src="../../static/asserts/js/jquery-3.2.1.slim.min.js" th:src="@{/asserts/js/jquery-3.2.1.slim.min.js}"></script>
    <script type="text/javascript" src="../../static/asserts/js/popper.min.js" th:src="@{/asserts/js/popper.min.js}"></script>
    <script type="text/javascript" src="../../static/asserts/js/bootstrap.min.js" th:src="@{/asserts/js/bootstrap.min.js}"></script>
    
    <!-- Icons -->
    <script type="text/javascript" src="../../static/asserts/js/feather.min.js" th:href="@{/asserts/js/feather.min.js}"></script>
    <script>
        feather.replace()
    </script>
    
    <!-- Graphs -->
    <script type="text/javascript" src="../../static/asserts/js/Chart.min.js" th:src="@{/asserts/js/Chart.min.js}"></script>
    <script>
        var ctx = document.getElementById("myChart");
        var myChart = new Chart(ctx, {
            type: 'line',
            data: {
                labels: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
                datasets: [{
                    data: [15339, 21345, 18483, 24003, 23489, 24092, 12034],
                    lineTension: 0,
                    backgroundColor: 'transparent',
                    borderColor: '#007bff',
                    borderWidth: 4,
                    pointBackgroundColor: '#007bff'
                }]
            },
            options: {
                scales: {
                    yAxes: [{
                        ticks: {
                            beginAtZero: false
                        }
                    }]
                },
                legend: {
                    display: false,
                }
            }
        });
    </script>
    
    </body>
    
    </html>
    相关实体类:

    删除的实现技巧:

    不能将delete按钮直接包含在form表单中:

     通过js进行进行调用一个表单,不用为删除而创建多个表单

    效果图:

    修改页面:

    不一样的烟火
  • 相关阅读:
    [Debug]驱动程序调测方法与技巧
    [内核同步]自旋锁spin_lock、spin_lock_irq 和 spin_lock_irqsave 分析
    ios多线程-GCD基本用法
    用PHP抓取页面并分析
    IOS开发-KVC
    IOS开发-KVO
    JavaScript垃圾回收(三)——内存泄露
    JavaScript垃圾回收(二)——垃圾回收算法
    JavaScript垃圾回收(一)——内存分配
    JavaScript闭包(二)——作用
  • 原文地址:https://www.cnblogs.com/cstdio1/p/12031351.html
Copyright © 2011-2022 走看看