当前位置:网站首页>2.0springmvc uses restful
2.0springmvc uses restful
2022-06-25 04:35:00 【gh-xiaohe】
List of articles
- RESTful
- RESTful Case study
- 1、 preparation
- 2、 Feature list
- 3、 Specific function : Visit the home page
- 4、 Specific function : Query all employee data
- 5、 Specific function : Delete a key
- 6、 Specific function : Jump to the add data page
- * 7、 Specific function : Perform save
- 8、 Specific function : Jump to the update data page
- 9、 Specific function : Perform the update
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 :GET、POST、PUT、DELETE.
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=1 | user/1–>get Request mode |
Save operation | saveUser | user–>post Request mode |
Delete operation | deleteUser?id=1 | user/1–>delete Request mode |
update operation | updateUser | user–>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>
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 HiddenHttpMethodFilterstay 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 √ | /employee | GET |
Delete √ | /employee/2 | DELETE |
Jump to the add data page √ | /toAdd | GET |
Perform save √ | /employee | POST |
Jump to the update data page √ | /employee/2 | GET |
Perform the update √ | /employee | PUT |
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";
}
边栏推荐
- Intel 13th generation core showed its true colors for the first time: 68mb cache improved significantly
- CTF_ Web: Learn flask template injection (SSTI) from 0
- Gbase 8s index b+ tree
- CTF_ Web: Advanced questions of attack and defense world expert zone WP (19-21)
- 2021.6.14 notes
- GBASE 8s 索引B+树
- kenlm
- CTF_ Variable coverage in web:php
- 深度学习——几种学习类型
- Introduction to intstream API
猜你喜欢
简单的恶意样本行文分析-入门篇
CTF_ Web: basic 12 questions WP of attack and defense world novice zone
Anaconda installation +tensorflow installation +keras installation +numpy installation (including image and version information compatibility issues)
English Grammar - pronunciation rules
Gbase 8s index b+ tree
小白学习MySQL - 统计的'投机取巧'
Leetcode points to the leetcode road of offering II 091 house painting [dynamic planning] heroding
【无标题】
Shutter fittedbox component
Summary of various problems encountered by cocos2d-x
随机推荐
Laravel document sorting 11. System architecture
《牛客刷verilog》Part I Verilog快速入门
jsz中的join()
CTF_ Web: how to recognize and evaluate a regular expression
Gbase 8s index R tree
GBASE 8s的数据导入和导出
cnpm : 无法加载文件 C:\Users\Administrator\AppData\Roaming\npm\cnpm.ps1,因为在此系统上禁止运行脚本。
2021.6.14 notes
Codeforces Round #802 (Div. 2) C D
Cascading deletion of gbase 8s
Data view for gbase 8s
Win10 environment phpstudy2016 startup failure record
GBASE 8s的隔离级别介绍
Can Navicat directly operate the Android database SQLite
彻底理解数据库事务
CTF_ Web: Learn flask template injection (SSTI) from 0
Gbase 8s index b+ tree
【esp32学习之路6——flash加密】
SQL injection details
简单的恶意样本行文分析-入门篇