当前位置:网站首页>2.0springmvc uses restful

2.0springmvc uses restful

2022-06-25 04:35:00 gh-xiaohe

author : gh-xiaohe
gh-xiaohe The blog of
If you think the blogger's article is good , I hope you'll make it three times in a row ( Focus on , give the thumbs-up , Comment on ), Give me more support !!!

RESTful

1、RESTful brief introduction

REST:Representational State Transfer, Presentation layer resource state transition .

a> resources

     resources It is a kind of look Wait for the server The way , namely , Think of the server as composed of many discrete resources . Each resource is a nameable abstraction on the server . Because resource is an abstract concept , So it can not only represent a file in the server file system 、 A table in the database and so on , We can design resources as abstract as possible , As long as imagination allows and client application developers can understand . Similar to object-oriented design , Resources are organized around terms , The first concern is the noun . A resource can be made up of one or more URI To mark .URI Is the name of the resource , It's also resources Web Address on . Client applications interested in a resource , The URI Interact with it .

b> Expression of resources

     The expression of resources is a paragraph about resources In a certain Specific moment Of state Of describe . Can be on the client side - Transfer between servers ( In exchange for ). Resources can be expressed in a variety of formats , for example HTML/XML/JSON/ Pure text / picture / video / Audio and so on. . The presentation format of resources can be determined by negotiation mechanism . request - The response direction is usually expressed in different formats .

c> State shift

     State transition is about : stay client and Server side Between Transfer (transfer) Representation of resource status . By transferring and manipulating the expression of resources , To achieve the purpose of operating resources indirectly .

2、RESTful The implementation of the

     specifically , Namely HTTP In the agreement , Four represent the operation mode It's a simple verb :GETPOSTPUTDELETE.

     They correspond to four basic operations :GET Used to obtain resources ,POST Used to create a new resource ,PUT Used to update resources ,DELETE Used to delete resources .

    REST Style advocates URL Address using Unified style design , Use the words from front to back Slashes separate , Do not use question mark key values Carry on the way Request parameters , Instead, the data to be sent to the server is used as URL Part of the address , To ensure the consistency of the overall style .

operation The traditional way REST style
Query operation getUserById?id=1user/1–>get Request mode
Save operation saveUseruser–>post Request mode
Delete operation deleteUser?id=1user/1–>delete Request mode
update operation updateUseruser–>put Request mode

3、HiddenHttpMethodFilter filter

     Because the browser only supports sending get and post Method request , So how to send put and delete What about the request ?

    SpringMVC Provides HiddenHttpMethodFilter Help us take POST Request conversion to DELETE or PUT request

HiddenHttpMethodFilter Handle put and delete The condition of the request :

  • Request mode of current request It has to be for post

  • The current request must be transmitted Request parameters _method

     Meet the above conditions ,HiddenHttpMethodFilter The filter will convert the request mode of the current request into request parameters _method Value , So request parameters ==_method== The value of is the final request method

stay web.xml Register in HiddenHttpMethodFilter

<!-- Configure how requests are processed put and delete Of HiddenHttpMethodFilter-->
<filter>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-yCdaHbkm-1655820991011)(RESTful.assets/image-20220620214025581.png)]

Source code

/*  filter   There must be three ways  ① initialization ( important ) ② filtering  ③ Three methods of destruction   Mode one :  How to perform filtering doFilter Who has executed it   The subclass is not looking for the parent class   Mode two :  The search parameter is  filterChain  It must be the method of performing filtering  filterChain  For release  */ 
public class HiddenHttpMethodFilter extends OncePerRequestFilter {
    
    private static final List<String> ALLOWED_METHODS;
    public static final String DEFAULT_METHOD_PARAM = "_method";
    private String methodParam = "_method";

    public HiddenHttpMethodFilter() {
    
    }

    public void setMethodParam(String methodParam) {
    
        Assert.hasText(methodParam, "'methodParam' must not be empty");
        this.methodParam = methodParam;
    }

    // The search parameter is  filterChain  It must be the method of performing filtering  filterChain  For release  ( How to perform filtering )
    //HttpServletRequest request, HttpServletResponse response  Filtering is the interception of requests   and   Respond to 
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    

        HttpServletRequest requestToUse = request; //  The assignment is  HttpServletRequest  object 

        //  Get request parameters   Is it equal to  POST  Constant for the  true
        if ("POST".equals(request.getMethod()) && request.getAttribute("javax.servlet.error.exception") == null) {
    
            //  Get request parameters  this.methodParam private String methodParam = "_method"; ( The value of a constant )
            String paramValue = request.getParameter(this.methodParam);
            if (StringUtils.hasLength(paramValue)) {
     //  Is there a length   Is it empty 
                String method = paramValue.toUpperCase(Locale.ENGLISH); //  take _method  Converts the value of to uppercase 
                if (ALLOWED_METHODS.contains(method)) {
     // Can only write  PUT DELETE PATCH  Here's the explanation 
                    // requestToUse  Assign him a value   Turned into  PUT DELETE PATCH
                    requestToUse = new HiddenHttpMethodFilter.HttpMethodRequestWrapper(request, method);
                }
            }
        }
        //  At the time of release   The newly created request object   As a   Filter intercepted objects   Released 
        filterChain.doFilter((ServletRequest)requestToUse, response);//  The results obtained in the future are  PUT DELETE PATCH
    }

    static {
    
        //List  combination  //  Put the last three values in list In combination  HttpMethod enumeration 
        ALLOWED_METHODS = Collections.unmodifiableList(Arrays.asList(HttpMethod.PUT.name(), HttpMethod.DELETE.name(), HttpMethod.PATCH.name()));
    }

    private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {
    
        private final String method;  // ② PUT DELETE PATCH

        public HttpMethodRequestWrapper(HttpServletRequest request, String method) {
    
            super(request);
            this.method = method; // ① PUT DELETE PATCH
        }

        public String getMethod() {
    
            return this.method; // ③ PUT DELETE PATCH
        }
    }
}

notes :

     When there are multiple filters , The order of filter execution is determined , The more advanced the configuration , Just execute
    
     So far, ,SpringMVC Two filters are provided in CharacterEncodingFilter and HiddenHttpMethodFilter

stay web.xml Registration in China , Must first register CharacterEncodingFilter, To register again HiddenHttpMethodFilter

reason :

  • stay CharacterEncodingFilter Pass through request.setCharacterEncoding(encoding) Method to set the value of the character set

  • request.setCharacterEncoding(encoding) Method requires that there must be no previous operation to get the request parameters

  • and HiddenHttpMethodFilter There is just one operation to get the request mode :

  • String paramValue = request.getParameter(this.methodParam);
    

RESTful Case study

1、 preparation

And traditional CRUD equally , Realize the addition, deletion, modification and query of employee information .

  • Set up the environment

  • Prepare entity classes

    public class Employee {
          
    
       private Integer id;
       private String lastName;
    
       private String email;
       //1 male, 0 female
       private Integer gender;
       
       public Integer getId() {
          
          return id;
       }
    
       public void setId(Integer id) {
          
          this.id = id;
       }
    
       public String getLastName() {
          
          return lastName;
       }
    
       public void setLastName(String lastName) {
          
          this.lastName = lastName;
       }
    
       public String getEmail() {
          
          return email;
       }
    
       public void setEmail(String email) {
          
          this.email = email;
       }
    
       public Integer getGender() {
          
          return gender;
       }
    
       public void setGender(Integer gender) {
          
          this.gender = gender;
       }
    
       public Employee(Integer id, String lastName, String email, Integer gender) {
          
          super();
          this.id = id;
          this.lastName = lastName;
          this.email = email;
          this.gender = gender;
       }
    
       public Employee() {
          
       }
    }
    
  • Get ready dao Analog data

    import java.util.Collection;
    import java.util.HashMap;
    import java.util.Map;
    
    import com.atguigu.mvc.bean.Employee;
    import org.springframework.stereotype.Repository;
    
    
    @Repository // Persistent layer by layer component database 
    public class EmployeeDao {
          
    
        private static Map<Integer, Employee> employees = null;
    
        static{
          
            employees = new HashMap<Integer, Employee>();
    
            employees.put(1001, new Employee(1001, "E-AA", "[email protected]", 1));
            employees.put(1002, new Employee(1002, "E-BB", "[email protected]", 1));
            employees.put(1003, new Employee(1003, "E-CC", "[email protected]", 0));
            employees.put(1004, new Employee(1004, "E-DD", "[email protected]", 0));
            employees.put(1005, new Employee(1005, "E-EE", "[email protected]", 1));
        }
    
        private static Integer initId = 1006;
    
        //  add to   and   modify   function 
        public void save(Employee employee){
          
            if(employee.getId() == null){
          
                employee.setId(initId++); //  Assign first   Increasing 
            }
            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);
        }
    }
    

2、 Feature list

function URL Address Request mode
Visit the home page √/GET
Query all data √/employeeGET
Delete √/employee/2DELETE
Jump to the add data page √/toAddGET
Perform save √/employeePOST
Jump to the update data page √/employee/2GET
Perform the update √/employeePUT

3、 Specific function : Visit the home page

a> To configure view-controller

<mvc:view-controller path="/" view-name="index"/>

b> Create a page

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8" >
    <title>Title</title>
</head>
<body>
<h1> home page </h1>
<a th:href="@{/employee}"> Access employee information </a>
</body>
</html>

4、 Specific function : Query all employee data

a> Controller method

@RequestMapping(value = "/employee", method = RequestMethod.GET)
public String getEmployeeList(Model model){
    
    Collection<Employee> employeeList = employeeDao.getAll();
    model.addAttribute("employeeList", employeeList);
    return "employee_list";
}

b> establish employee_list.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Employee Info</title>
    <script type="text/javascript" th:src="@{/static/js/vue.js}"></script>
</head>
<body>
	<!-- Margin  = 1 ,  Cancel margins ,  Cancel spacing   In the middle -->
    <table border="1" cellpadding="0" cellspacing="0" style="text-align: center;" id="dataTable">
        <tr>
            <th colspan="5">Employee Info</th>
        </tr>
        <tr>
            <th>id</th>
            <th>lastName</th>
            <th>email</th>
            <th>gender</th>
            <th>options(<a th:href="@{/toAdd}">add</a>)</th>
        </tr>
        <tr th:each="employee : ${employeeList}">
            <td th:text="${employee.id}"></td>
            <td th:text="${employee.lastName}"></td>
            <td th:text="${employee.email}"></td>
            <td th:text="${employee.gender}"></td>
            <td>
                <!-- Wrong way of writing : {  It will be resolved to  %7B }  It will be resolved to  %7D-->
                <!--<a th:href="@{/employee/${employee.id}}">delete</a>-->
                <!-- Mode one :-->
                    <a @click="deleteEmployee" th:href="@{
     '/employee/'+${employee.id}}">delete</a>
                <!-- Mode two :-->
                    <a th:href="@{
     '/employee/'+${employee.id}}">update</a>
            </td>
        </tr>
    </table>
</body>
</html>

5、 Specific function : Delete a key

a> Create processing delete Request Form

<!--  effect : Control the submission of forms through hyperlinks , take post Request conversion to delete request  -->
<form id="delete_form" method="post">
    <!-- HiddenHttpMethodFilter requirement : Must transmit _method Request parameters , And the value is the final request method  -->
    <input type="hidden" name="_method" value="delete"/>
</form>

b> Delete hyperlink binding click event

  • introduce vue.js
<script type="text/javascript" th:src="@{/static/js/vue.js}"></script>
  • Create hyperlinks
                <!-- Wrong way of writing : {  It will be resolved to  %7B }  It will be resolved to  %7D-->
                <!--<a th:href="@{/employee/${employee.id}}">delete</a>-->
                <!-- Mode one :-->
                    <a @click="deleteEmployee" th:href="@{
     '/employee/'+${employee.id}}">delete</a>
                <!-- Mode two :-->
                    <a th:href="@{
     '/employee/'+${employee.id}}">update</a>
  • adopt vue Handle click events
    <script type="text/javascript"> var vue = new Vue({
       el:"#dataTable", methods:{
       deleteEmployee:function (event) {
       // according to id Get form elements  var deleteForm = document.getElementById("deleteForm"); // The of the hyperlink that will trigger the click event href Property is assigned to the of the form action deleteForm.action = event.target.href; // Submit Form  deleteForm.submit(); // Cancel the default behavior of hyperlinks  event.preventDefault(); } } }); </script>

c> Controller method

@RequestMapping(value = "/employee/{id}", method = RequestMethod.DELETE)
public String deleteEmployee(@PathVariable("id") Integer id){
    
    employeeDao.delete(id);
    return "redirect:/employee";
}

6、 Specific function : Jump to the add data page

a> To configure view-controller

<mvc:view-controller path="/toAdd" view-name="employee_add"></mvc:view-controller>

b> establish employee_add.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Add Employee</title>
</head>
<body>

<form th:action="@{/employee}" method="post">
    lastName:<input type="text" name="lastName"><br>
    email:<input type="text" name="email"><br>
    gender:<input type="radio" name="gender" value="1">male
    <input type="radio" name="gender" value="0">female<br>
    <input type="submit" value="add"><br>
</form>

</body>
</html>

* 7、 Specific function : Perform save

a> Controller method

@RequestMapping(value = "/employee", method = RequestMethod.POST)
public String addEmployee(Employee employee){
    
    employeeDao.save(employee);
    return "redirect:/employee";
}

8、 Specific function : Jump to the update data page

a> Modify hyperlinks

<a th:href="@{
     '/employee/'+${employee.id}}">update</a>

b> Controller method

@RequestMapping(value = "/employee/{id}", method = RequestMethod.GET)
public String getEmployeeById(@PathVariable("id") Integer id, Model model){
    
    Employee employee = employeeDao.get(id);
    model.addAttribute("employee", employee);
    return "employee_update";
}

c> establish employee_update.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Update Employee</title>
</head>
<body>

<form th:action="@{/employee}" method="post">
    <input type="hidden" name="_method" value="put">
    <input type="hidden" name="id" th:value="${employee.id}"> <!-- The echo data ${}-->
    lastName:<input type="text" name="lastName" th:value="${employee.lastName}"><br>
    email:<input type="text" name="email" th:value="${employee.email}"><br>
    <!-- th:field="${employee.gender}" Can be used to echo radio boxes or check boxes   If the radio box value and employee.gender The value is consistent. , Then add checked="checked" attribute  -->
    gender:<input type="radio" name="gender" value="1" th:field="${employee.gender}">male
    <input type="radio" name="gender" value="0" th:field="${employee.gender}">female<br>
    <input type="submit" value="update"><br>
</form>

</body>
</html>

9、 Specific function : Perform the update

a> Controller method

@RequestMapping(value = "/employee", method = RequestMethod.PUT)
public String updateEmployee(Employee employee){
    
    employeeDao.save(employee);
    return "redirect:/employee";
}
原网站

版权声明
本文为[gh-xiaohe]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/176/202206250257224293.html