SpringMVC將請(qǐng)求和響應(yīng)的數(shù)據(jù)轉(zhuǎn)換為JSON格式的幾種方式
RESTful
概述
REST:Representational State Transfer,表現(xiàn)層資源狀態(tài)轉(zhuǎn)移。
表現(xiàn)層:前端的視圖頁(yè)面和后端的控制層就是表現(xiàn)層
資源
資源是一種看待服務(wù)器的方式,即,將服務(wù)器看作是由很多離散的資源組成。每個(gè)資源是服務(wù)器上一個(gè)可命名的抽象概念。因?yàn)橘Y源是一個(gè)抽象的概念,所以它不僅僅能代表服務(wù)器文件系統(tǒng)中的一個(gè)文件、數(shù)據(jù)庫(kù)中的一張表等等具體的東西,可以將資源設(shè)計(jì)的要多抽象有多抽象,只要想象力允許而且客戶端應(yīng)用開發(fā)者能夠理解。與面向?qū)ο笤O(shè)計(jì)類似,資源是以名詞為核心來(lái)組織的,首先關(guān)注的是名詞。一個(gè)資源可以由一個(gè)或多個(gè)URI來(lái)標(biāo)識(shí)。URI既是資源的名稱,也是資源在Web上的地址。對(duì)某個(gè)資源感興趣的客戶端應(yīng)用,可以通過資源的URI與其進(jìn)行交互。
URI :統(tǒng)一資源標(biāo)識(shí)符(Uniform Resource Identifier,URI)是一個(gè)用于標(biāo)識(shí)某一互聯(lián)網(wǎng)資源名稱的字符串。
統(tǒng)一資源定位符(Uniform Resource Locator,URL),統(tǒng)一資源名稱(Uniform Resource Name,URN)是URI的子集。
資源的表述
資源的表述是一段對(duì)于資源在某個(gè)特定時(shí)刻的狀態(tài)的描述??梢栽诳蛻舳?服務(wù)器端之間轉(zhuǎn)移(交換)。資源的表述可以有多種格式,例如 HTML/XML/JSON/純文本/圖片/視頻/音頻等等。資源的表述格式可以通過協(xié)商機(jī)制來(lái)確定。請(qǐng)求-響應(yīng)方向的表述通常使用不同的格式。
狀態(tài)轉(zhuǎn)移
狀態(tài)轉(zhuǎn)移說的是:在客戶端和服務(wù)器端之間轉(zhuǎn)移(transfer)代表資源狀態(tài)的表述。通過轉(zhuǎn)移和操作資源的表述,來(lái)間接實(shí)現(xiàn)操作資源的目的。
RESTful的實(shí)現(xiàn)
具體說,就是 HTTP 協(xié)議里面,四個(gè)表示操作方式的動(dòng)詞:GET、POST、PUT、DELETE。
它們分別對(duì)應(yīng)四種基本操作:GET 用來(lái)獲取資源,POST 用來(lái)新建資源,PUT 用來(lái)更新資源,DELETE 用來(lái)刪除資源。
REST 風(fēng)格提倡 URL 地址使用統(tǒng)一的風(fēng)格設(shè)計(jì),從前到后各個(gè)單詞使用斜杠分開,不使用問號(hào)鍵值對(duì)方式攜帶請(qǐng)求參數(shù),而是將要發(fā)送給服務(wù)器的數(shù)據(jù)作為 URL 地址的一部分,以保證整體風(fēng)格的一致性。
操作傳統(tǒng)方式REST風(fēng)格查詢操作
操作 | 傳統(tǒng)方式 | REST風(fēng)格 |
---|---|---|
查詢操作 | getUserById?id=1 | user/1–>get請(qǐng)求方式 |
保存操作 | saveUser | user–>post請(qǐng)求方式 |
刪除操作 | deleteUser?id=1 | user/1–>delete請(qǐng)求方式 |
更新操作 | updateUser | user–>put請(qǐng)求方式 |
該案例我寫在 demo3 中(也可創(chuàng)建一個(gè)新的項(xiàng)目),大致需要的文件如下:
創(chuàng)建 user.html 并編寫用來(lái)測(cè)試的表單和超鏈接
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>使用RESTFul模擬操作用戶資源(增刪改查)</title> </head> <body> <h1>使用RESTFul模擬操作用戶資源(增刪改查)</h1> <a th:href="@{/user}" rel="external nofollow" >查詢所有用戶信息</a><br/> <a th:href="@{/user/1}" rel="external nofollow" >根據(jù)用戶ID查詢用戶信息</a><br/> <form method="post" th:action="@{/user}"> 用戶名:<input type="text" name="username"><br/> 密碼:<input type="text" name="password"><br/> <input type="submit" value="添加用戶信息"> </form> <form method="put" th:action="@{/user}"> 用戶名:<input type="text" name="username"><br/> 密碼:<input type="text" name="password"><br/> <input type="submit" value="根據(jù)用戶ID修改用戶信息"> </form> <form method="delete" th:action="@{/user}"> 用戶ID:<input type="text" name="id"><br/> <input type="submit" value="根據(jù)用戶ID刪除對(duì)應(yīng)用戶信息"> </form> </body> </html>
編寫對(duì)應(yīng)的控制器方法
package com.laoyang.mvc.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; /** * @ClassName UserController * @Description: 使用RESTFul模擬操作用戶資源(增刪改查) * @Author Laoyang * @Date 2022/1/13 15:53 */ @Controller public class UserController { /** * 查詢所有用戶信息 * /user ---> GET */ @RequestMapping(value = "/user", method = RequestMethod.GET) public String findAllUser() { System.out.println("查詢所有用戶信息"); return "success"; } /** * 根據(jù)用戶ID查詢用戶信息 * /user/1 ---> GET */ @RequestMapping(value = "/user/{id}", method = RequestMethod.GET) public String findByUserId(@PathVariable("id") Integer id) { System.out.println("id=" + id); System.out.println("根據(jù)用戶ID查詢用戶信息"); return "success"; } /** * 添加用戶信息 * /user ---> POST */ @RequestMapping(value = "/user", method = RequestMethod.POST) public String saveUser(String username, String password) { System.out.println("username=" + username + ";password=" + password); System.out.println("添加用戶信息"); return "success"; } /** * 根據(jù)用戶ID修改用戶信息 * /user ---> PUT */ @RequestMapping(value = "/user", method = RequestMethod.PUT) public String updateUser(String username, String password) { System.out.println("username=" + username + ";password=" + password); System.out.println("根據(jù)用戶ID修改用戶信息"); return "success"; } /** * 根據(jù)用戶ID刪除對(duì)應(yīng)用戶信息 * /user/1 ---> DELETE */ @RequestMapping(value = "/user", method = RequestMethod.DELETE) public String deleteUser(Integer id) { System.out.println("id=" + id); System.out.println("根據(jù)用戶ID刪除對(duì)應(yīng)用戶信息"); return "success"; } }
在 spring-mvc.xml 文件中配置頁(yè)面跳轉(zhuǎn)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 掃描組件 --> <context:component-scan base-package="com.laoyang.mvc" /> <!-- 配置 Thymeleaf 視圖解析器 --> <bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver"> <!-- 優(yōu)先級(jí) --> <property name="order" value="1"/> <!-- 字符編碼 --> <property name="characterEncoding" value="UTF-8"/> <!-- 模板 --> <property name="templateEngine"> <bean class="org.thymeleaf.spring5.SpringTemplateEngine"> <property name="templateResolver"> <bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver"> <!-- 視圖前綴 --> <property name="prefix" value="/WEB-INF/templates/"/> <!-- 視圖后綴 --> <property name="suffix" value=".html"/> <!-- 模板模型 --> <property name="templateMode" value="HTML5"/> <!-- 頁(yè)面編碼格式 --> <property name="characterEncoding" value="UTF-8"/> </bean> </property> </bean> </property> </bean> <!-- path:設(shè)置處理的請(qǐng)求地址,該路徑是和 @RequestMapping 注解中的地址是一樣的 簡(jiǎn)單理解:就是把 controller 中用來(lái)跳轉(zhuǎn)頁(yè)面的控制器方法寫在了配置文件中 view-controller:設(shè)置請(qǐng)求地址所對(duì)應(yīng)的視圖名稱 --> <!-- 訪問方式:http://localhost:8080/springmvc/ --> <mvc:view-controller path="/" view-name="index"/> <!-- 訪問方式:http://localhost:8080/springmvc/doView --> <mvc:view-controller path="/doView" view-name="view" /> <!-- 訪問方式:localhost:8080/springmvc/doUser,這一步是新增的代碼 --> <mvc:view-controller path="/doUser" view-name="user"/> <!-- 開啟 mvc 的注解驅(qū)動(dòng) --> <mvc:annotation-driven /> </beans>
啟動(dòng)Tomcat查看效果(訪問localhost:8080/springmvc/doUser)
- 查詢所有用戶
- 根據(jù)用戶ID查詢對(duì)應(yīng)的用戶信息
- 添加用戶信息
以上三個(gè)都是可以正常訪問的,但是瀏覽器效果都是跳轉(zhuǎn)到 success 頁(yè)面,所以大家看控制臺(tái)打印就可以看那個(gè)方法被執(zhí)行了。
- 根據(jù)用戶ID修改用戶信息
- 根據(jù)用戶ID刪除對(duì)應(yīng)用戶信息
這里截的圖是修改的效果,目前是不滿足我們的需求的,刪除效果和這個(gè)差不多,就不另做演示了
- 問題說明: 因?yàn)樾薷暮蛣h除的表單提交的請(qǐng)求方式是 put 和 delete,而瀏覽器基本上都只支持 get 和 post 請(qǐng)求,所以會(huì)導(dǎo)致無(wú)法通過 put 或 delete 方式進(jìn)行處理,所以遇到這種情況的時(shí)候,瀏覽器默認(rèn)會(huì)以 get 請(qǐng)求方式進(jìn)行處理,所以修改和刪除所映射到的控制器方法是 GET 類型的(查詢所有用戶,可以觀察控制臺(tái)打印的語(yǔ)句)
- 解決方案: 可注冊(cè) HiddenHttpMethodFilter 過濾器處理除 get 和 post 之外的幾種請(qǐng)求方式,通過這個(gè)過濾器就可以解決剛才的問題
這里我先簡(jiǎn)單說明一下,如果想要在了解一些東西可以看后面的 HiddenHttpMethodFilter 解析
在 web.xml 中配置 HiddenhttpMethodFilter
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- 配置HiddenHttpMethodFilter過濾器 --> <filter> <filter-name>hidden</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <!-- 注冊(cè)前端控制器 DispatcherServlet --> <servlet> <servlet-name>springMVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 初始化參數(shù) --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> <!-- 初始化前端控制器,將前端控制器 DispatcherServlet 的初始化時(shí)間提前到服務(wù)器啟動(dòng)時(shí) --> <load-on-startup>1</load-on-startup> </servlet> <!-- 設(shè)置字符編碼格式 注意:設(shè)置編碼格式之前不可以獲取任何請(qǐng)求參數(shù),如果獲取了,就會(huì)導(dǎo)致設(shè)置的字符編碼失效!從而導(dǎo)致拿到的數(shù)據(jù)是亂碼。 > 所以字符編碼的 filter-mapping 標(biāo)簽一定要放在其它 filter-mapping 標(biāo)簽前面?。?! --> <filter> <filter-name>encoding-filter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <!-- 指定要使用的編碼格式 --> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <!-- 強(qiáng)制使用我們?cè)O(shè)置的編碼格式,默認(rèn)是false(不強(qiáng)制) --> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <!-- 字符編碼的處理規(guī)則,必須在其他處理規(guī)則之前 --> <filter-mapping> <filter-name>encoding-filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 前端控制器請(qǐng)求處理規(guī)則 --> <servlet-mapping> <servlet-name>springMVC</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- 請(qǐng)求方式的處理規(guī)則 --> <filter-mapping> <filter-name>hidden</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
注意: 編寫 web.xml 文件的時(shí)候一定要注意,字符編碼的處理規(guī)則一定要放在最上面!因?yàn)樵O(shè)置字符編碼之前不可以獲取到任何一個(gè)參數(shù)!如果你先讓其它的處理規(guī)則先執(zhí)行,那么這些請(qǐng)求規(guī)則就可能會(huì)帶有參數(shù),一旦帶有參數(shù),就會(huì)導(dǎo)致我們所設(shè)置的字符編碼失效(簡(jiǎn)單來(lái)說,就是即使我們?cè)O(shè)置了字符編碼,拿到的數(shù)據(jù)也還是亂碼?。?,所以千萬(wàn)要注意?。?!
Ps:web.xml 文件基本上的配置就是這些,兩個(gè)過濾器,一個(gè) Servlet,只要是使用 SpringMVC,這幾個(gè)配置就不能少!
配置完之后還需要將提交方式修改為 POST,并且傳一個(gè)參數(shù) _method
,這個(gè)參數(shù)的值就是我們最終的提交方式,HiddenHttpMethodFilter 會(huì)根據(jù)這個(gè)參數(shù)進(jìn)行處理
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>使用RESTFul模擬操作用戶資源(增刪改查)</title> </head> <body> <h1>使用RESTFul模擬操作用戶資源(增刪改查)</h1> <form method="post" th:action="@{/user}"> <!-- 因?yàn)檫@個(gè)參數(shù)只是給過濾器進(jìn)行處理的,所以我們使用隱藏域來(lái)傳,這樣就不會(huì)影響到用戶使用了 --> <input type="hidden" name="_method" value="PUT"> 用戶名:<input type="text" name="username"><br/> 密碼:<input type="text" name="password"><br/> <input type="submit" value="根據(jù)用戶ID修改用戶信息"> </form> <form method="post" th:action="@{/user}"> <input type="hidden" name="_method" value="DELETE"> 用戶ID:<input type="text" name="id"><br/> <input type="submit" value="根據(jù)用戶ID刪除對(duì)應(yīng)用戶信息"> </form> </body> </html>
再次測(cè)試
這個(gè)時(shí)候在看控制臺(tái),就是打印我們修改方法和刪除方法中的數(shù)據(jù)了
HiddenHttpMethodFilter 解析
為什么要使用 HiddenHttpMethodFilter
由于瀏覽器只支持發(fā)送 get 和 post 方式的請(qǐng)求,所以我們需要配置這個(gè)過濾器來(lái)讓瀏覽器能夠使用我們指定的方式進(jìn)行處理,那么該如何發(fā)送 put 和 delete 請(qǐng)求呢?
- SpringMVC 提供了 HiddenHttpMethodFilter 幫助我們將 POST 請(qǐng)求轉(zhuǎn)換為 DELETE 或 PUT 請(qǐng)求 HiddenHttpMethodFilter 處理put和delete請(qǐng)求的條件:
- 當(dāng)前請(qǐng)求的請(qǐng)求方式必須為post
- 當(dāng)前請(qǐng)求必須傳輸請(qǐng)求參數(shù)
_method
,并且該參數(shù)的值必須是可兼容的(PUT、DELETE、PATCH,如有改動(dòng)可自行查看源碼)
滿足以上條件,HiddenHttpMethodFilter 過濾器就會(huì)將當(dāng)前請(qǐng)求的請(qǐng)求方式轉(zhuǎn)換為請(qǐng)求參數(shù)
_method
的值,因此請(qǐng)求參數(shù)_method
的值才是最終的請(qǐng)求方式
部分源碼 大家可根據(jù)我在源碼上標(biāo)注的注釋進(jìn)行理解
public class HiddenHttpMethodFilter extends OncePerRequestFilter { /** * request 和 response 是我們攔截的請(qǐng)求和響應(yīng) */ @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { HttpServletRequest requestToUse = request; /* request.getMethod():獲取當(dāng)前所攔截的請(qǐng)求的請(qǐng)求方式 理解:如果當(dāng)前的請(qǐng)求方式為 POST,并且沒有任何錯(cuò)誤信息,則進(jìn)行相關(guān)的操作 */ if ("POST".equals(request.getMethod()) && request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) { // 獲取當(dāng)前請(qǐng)求的請(qǐng)求參數(shù)(默認(rèn)為:_method) String paramValue = request.getParameter(this.methodParam); // 如果該值的長(zhǎng)度不為0,則進(jìn)行相關(guān)的操作 if (StringUtils.hasLength(paramValue)) { // 將請(qǐng)求參數(shù)的值轉(zhuǎn)換為大寫 String method = paramValue.toUpperCase(Locale.ENGLISH); /* 如果轉(zhuǎn)換為大寫之后的請(qǐng)求參數(shù)是ALLOWED_METHODS中的某一個(gè),那么就可以進(jìn)行使用(PUT、DELETE、PATCH) 如果不是ALLOWED_METHODS中的值,則無(wú)法實(shí)現(xiàn)我們想要的效果 > 比如我們提交方式為QWE,因?yàn)锳LLOWED_METHODS中并沒有QWE,所以就無(wú)法以QWE方式發(fā)送請(qǐng)求 */ if (ALLOWED_METHODS.contains(method)) { // 將當(dāng)前請(qǐng)求的請(qǐng)求方式替換成我們需要的那種(比如把POST替換成PUT,然后在以PUT方式發(fā)送請(qǐng)求) requestToUse = new HttpMethodRequestWrapper(request, method); } } } // 給當(dāng)前請(qǐng)求放行 filterChain.doFilter(requestToUse, response); } }
SpringMVC 過濾器說明
- 目前為止,SpringMVC中提供了兩個(gè)過濾器:
CharacterEncodingFilter
和HiddenHttpMethodFilter
- 在 web.xml 中注冊(cè)時(shí),必須先注冊(cè) CharacterEncodingFilter,再注冊(cè)HiddenHttpMethodFilter
原因:
- 在 CharacterEncodingFilter 中是通過
request.setCharacterEncoding(encoding)
方法設(shè)置字符集的; request.setCharacterEncoding(encoding) 方法要求前面不能有任何獲取請(qǐng)求參數(shù)的操作 - 而 HiddenHttpMethodFilter 恰恰有一個(gè)獲取請(qǐng)求參數(shù)的操作:
String paramValue = request.getParameter(this.methodParam);
HttpMessageConverter
- 學(xué)習(xí)前可先創(chuàng)建一個(gè)新的項(xiàng)目工程,用來(lái)測(cè)試對(duì)應(yīng)的案例代碼,我這里的工程名為:
springmvc-demo4
web.xml 和 pom.xml 文件里面的內(nèi)容復(fù)制過來(lái)就行
說明
- HttpMessageConverter:
報(bào)文信息轉(zhuǎn)換器
,將請(qǐng)求報(bào)文轉(zhuǎn)換為 Java 對(duì)象,或?qū)?Java 對(duì)象轉(zhuǎn)換為響應(yīng)報(bào)文。 - HttpMessageConverter 提供了兩個(gè)注解和兩個(gè)類型:
@RequestBody
,@ResponseBody
,RequestEntity
,ResponseEntity
@RequestBoyd
@RequestBody 可以獲取請(qǐng)求體,需要在控制器方法設(shè)置一個(gè)形參,使用 @RequestBody 進(jìn)行標(biāo)識(shí),當(dāng)前請(qǐng)求的請(qǐng)求體就會(huì)為當(dāng)前注解所標(biāo)識(shí)的形參賦值。
案例
編寫web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- 配置編碼過濾器 --> <filter> <filter-name>characterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 配置 PUT 和 DELETE 請(qǐng)求方式的過濾器 --> <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> <!--注冊(cè)SpringMVC前端控制器--> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
編寫spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 開啟組件掃描 --> <context:component-scan base-package="com.laoyang.mvc" /> <!-- 配置 Thymeleaf 視圖解析器 --> <bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver"> <!-- 優(yōu)先級(jí) --> <property name="order" value="1"/> <!-- 字符編碼 --> <property name="characterEncoding" value="UTF-8"/> <!-- 模板 --> <property name="templateEngine"> <bean class="org.thymeleaf.spring5.SpringTemplateEngine"> <property name="templateResolver"> <bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver"> <!-- 視圖前綴 --> <property name="prefix" value="/WEB-INF/templates/" /> <!-- 視圖后綴 --> <property name="suffix" value=".html"/> <!-- 模板模型 --> <property name="templateMode" value="HTML5"/> <!-- 頁(yè)面編碼格式 --> <property name="characterEncoding" value="UTF-8"/> </bean> </property> </bean> </property> </bean> <!-- 配置視圖控制器 --> <mvc:view-controller path="/" view-name="index" /> <!-- 開放對(duì)靜態(tài)資源的訪問 --> <mvc:default-servlet-handler /> <!-- 開啟mvc注解驅(qū)動(dòng) --> <mvc:annotation-driven /> </beans>
編寫 index.html 頁(yè)面
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>首頁(yè)</title> </head> <body> <h1>首頁(yè)</h1> <form method="post" th:action="@{/testRequestBody}"> 用戶名:<input type="text" name="username"><br/> 密碼:<input type="text" name="password"><br/> <input type="submit" value="測(cè)試@RequestBody注解"> </form> </body> </html>
編寫 success.html 頁(yè)面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>主頁(yè)面</title> </head> <body> <h1>主頁(yè)面</h1> </body> </html>
編寫對(duì)應(yīng)的控制器方法
package com.laoyang.mvc.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; /** * @ClassName HttpController * @Description: 測(cè)試 @RequestBody 注解和 RequestEntity 類型 * @Author Laoyang * @Date 2022/1/15 15:52 */ @Controller public class RequestController { /** * 測(cè)試 @RequestBody 注解 */ @RequestMapping(value = "/testRequestBody") public String testRequestBody(@RequestBody String requestBody) { // 因?yàn)槭褂昧?@RequestBody 注解,所以這里的 requestBody 就可以獲取到頁(yè)面兩個(gè)文本框的值 System.out.println("------>" + requestBody); return "success"; } }
啟動(dòng)Tomcat進(jìn)行測(cè)試
- 頁(yè)面效果:成功跳轉(zhuǎn)到了 success.html 頁(yè)面
- 控制臺(tái)效果:成功獲取到了我們?cè)跒g覽器文本框中輸入的值 RequestEntity
RequestEntity
封裝請(qǐng)求報(bào)文的一種類型,需要在控制器方法的形參中設(shè)置該類型的形參,當(dāng)前請(qǐng)求的請(qǐng)求報(bào)文就會(huì)賦值給該形參,可以通過 getHeaders()
獲取請(qǐng)求頭信息,通過 getBody()
獲取請(qǐng)求體信息。
案例
在 index.html 中編寫表單
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>首頁(yè)</title> </head> <body> <h1>首頁(yè)</h1> <form method="post" th:action="@{/testRequestEntity}"> 用戶名:<input type="text" name="username"><br/> 密碼:<input type="text" name="password"><br/> <input type="submit" value="測(cè)試RequestEntity類型"> </form> </body> </html>
編寫對(duì)應(yīng)的控制器方法
package com.laoyang.mvc.controller; import org.springframework.http.RequestEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; /** * @ClassName HttpController * @Description: 測(cè)試 @RequestBody 注解和 RequestEntity 類型 * @Author Laoyang * @Date 2022/1/15 15:52 */ @Controller public class RequestController { /** * 測(cè)試 RequestEntity 類型 */ @RequestMapping(value = "/testRequestEntity") public String testRequestEntity(RequestEntity<String> requestEntity) { // 請(qǐng)求頭獲取的就是瀏覽器(F12)中看到的 System.out.println("請(qǐng)求頭 --->" + requestEntity.getHeaders()); // 請(qǐng)求體獲取的就是瀏覽器發(fā)送請(qǐng)求時(shí)帶的參數(shù) System.out.println("請(qǐng)求體 --->" + requestEntity.getBody()); return "success"; } }
啟動(dòng)Tomcat進(jìn)行測(cè)試
- 請(qǐng)求頭獲取的就是瀏覽器(F12)中看到的,具體大家可看瀏覽器,或控制臺(tái)打印的數(shù)據(jù)
@ResponseBody
@ResponseBody 用于標(biāo)識(shí)一個(gè)控制器方法,可以將該方法的返回值直接作為響應(yīng)報(bào)文的響應(yīng)體響應(yīng)到瀏覽器。
使用ServletAPI的response對(duì)象響應(yīng)瀏覽器數(shù)據(jù)
在 index.html 中編寫超鏈接
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>首頁(yè)</title> </head> <body> <h1>首頁(yè)</h1> <a th:href="@{/testResponse}" rel="external nofollow" >通過ServletAPI的response對(duì)象響應(yīng)瀏覽器數(shù)據(jù)</a><br/> </body> </html>
編寫對(duì)應(yīng)控制器方法
package com.laoyang.mvc.controller; import com.laoyang.mvc.pojo.User; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @ClassName ResponseController * @Description: 測(cè)試 @ResponseBody 注解和 ResponseEntity 類型 * @Author Laoyang * @Date 2022/1/15 17:10 */ @Controller public class ResponseController { /** * 通過ServletAPI的response對(duì)象響應(yīng)瀏覽器數(shù)據(jù) */ @RequestMapping("/testResponse") public void testResponse(HttpServletResponse response) { try { // 設(shè)置編碼格式 response.setContentType("text/html;charset=utf-8"); // 響應(yīng)給瀏覽器的數(shù)據(jù) response.getWriter().print("Hello 原生ServletAPI的response"); } catch (IOException e) { e.printStackTrace(); } } }
啟動(dòng)Tomcat查看效果
通過@ResponseBody注解響應(yīng)瀏覽器數(shù)據(jù)(響應(yīng)String類型的數(shù)據(jù))
在 index.html 中編寫超鏈接
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>首頁(yè)</title> </head> <body> <h1>首頁(yè)</h1> <a th:href="@{/testResponseBody}" rel="external nofollow" >通過@ResponseBody注解響應(yīng)瀏覽器數(shù)據(jù)(String)</a><br/> </body> </html>
編寫對(duì)應(yīng)控制器方法
package com.laoyang.mvc.controller; import com.laoyang.mvc.pojo.User; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @ClassName ResponseController * @Description: 測(cè)試 @ResponseBody 注解和 ResponseEntity 類型 * @Author Laoyang * @Date 2022/1/15 17:10 */ @Controller public class ResponseController { /** * 通過@ResponseBody注解響應(yīng)瀏覽器數(shù)據(jù) - String數(shù)據(jù) */ @RequestMapping("/testResponseBody") @ResponseBody public String testResponseBody() { /* 不加 @ResponseBody 注解就表示跳轉(zhuǎn)到 success 頁(yè)面 加上 @ResponseBody 注解則表示將該返回值響應(yīng)給瀏覽器 */ return "success"; } }
啟動(dòng)Tomcat查看效果
使用 @ResponseBody 注解處理 json 數(shù)據(jù)
在 index.html 中編寫超鏈接
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>首頁(yè)</title> </head> <body> <h1>首頁(yè)</h1 <a th:href="@{/testResponseUser}" rel="external nofollow" >通過@ResponseBody注解響應(yīng)瀏覽器數(shù)據(jù)(User)</a><br/> </body> </html>
編寫一個(gè)實(shí)體類用來(lái)配合測(cè)試
package com.laoyang.mvc.pojo; public class User { private Integer id; private String username; private String password; private Integer age; private String sex; // 創(chuàng)建對(duì)應(yīng)的get/set 方法、有參構(gòu)造器、全參構(gòu)造器 }
編寫對(duì)應(yīng)控制器方法
package com.laoyang.mvc.controller; import com.laoyang.mvc.pojo.User; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @ClassName ResponseController * @Description: 測(cè)試 @ResponseBody 注解和 ResponseEntity 類型 * @Author Laoyang * @Date 2022/1/15 17:10 */ @Controller public class ResponseController { /** * 通過@ResponseBody注解響應(yīng)瀏覽器數(shù)據(jù) - User對(duì)象數(shù)據(jù) */ @RequestMapping("/testResponseUser") @ResponseBody public User testResponseUser() { return new User(1001, "admin", "12345", 18, "男"); } }
啟動(dòng)Tomcat查看效果
報(bào)錯(cuò)原因:瀏覽器只能處理字符串類型的數(shù)據(jù)
解決方案:引入 json 相關(guān)依賴,并進(jìn)行相關(guān)配置
解決方案的實(shí)現(xiàn)步驟
導(dǎo)入jackson
的依賴
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.12.5</version> </dependency>
在 SpringMVC 的核心配置文件(spring-mvc.xml)中開啟 mvc 的注解驅(qū)動(dòng),此時(shí)在HandlerAdaptor 中會(huì)自動(dòng)裝配一個(gè)消息轉(zhuǎn)換器:MappingJackson2HttpMessageConverter
,可以將響應(yīng)到瀏覽器的 Java 對(duì)象轉(zhuǎn)換為 Json 格式的字符串
<mvc:annotation-driven />
在最開始的時(shí)候我們已經(jīng)配好了,這里就可以不配了;如果沒有配置,那么一定要加上
在處理器方法上使用 @ResponseBody 注解進(jìn)行標(biāo)識(shí)
package com.laoyang.mvc.controller; import com.laoyang.mvc.pojo.User; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @ClassName ResponseController * @Description: 測(cè)試 @ResponseBody 注解和 ResponseEntity 類型 * @Author Laoyang * @Date 2022/1/15 17:10 */ @Controller public class ResponseController { /** * 通過@ResponseBody注解響應(yīng)瀏覽器數(shù)據(jù) - User對(duì)象數(shù)據(jù) */ @RequestMapping("/testResponseUser") @ResponseBody public User testResponseUser() { return null; } }
將 Java 對(duì)象直接作為控制器方法的返回值進(jìn)行返回,就會(huì)自動(dòng)轉(zhuǎn)換為 Json 格式的字符串
package com.laoyang.mvc.controller; import com.laoyang.mvc.pojo.User; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @ClassName ResponseController * @Description: 測(cè)試 @ResponseBody 注解和 ResponseEntity 類型 * @Author Laoyang * @Date 2022/1/15 17:10 */ @Controller public class ResponseController { /** * 通過@ResponseBody注解響應(yīng)瀏覽器數(shù)據(jù) - User對(duì)象數(shù)據(jù) */ @RequestMapping("/testResponseUser") @ResponseBody public User testResponseUser() { return new User(1001, "admin", "12345", 18, "男"); } }
啟動(dòng)Tomcat查看效果
使用 @ResponseBody 注解處理 ajax 請(qǐng)求
在 index.html 中編寫超鏈接
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>首頁(yè)</title> </head> <body> <h1>首頁(yè)</h1> <div id="app"> <a th:href="@{testAxios}" rel="external nofollow" @click="testAxios">SpringMVC處理ajax</a> </div> </body> </html>
通過vue和axios處理點(diǎn)擊事件
需要先導(dǎo)入 vue.js
和 axios.min.js
然后使用代碼進(jìn)行引用
<script type="text/javascript" th:src="@{/static/js/vue.js}"></script> <script type="text/javascript" th:src="@{/static/js/axios.min.js}"></script> <script type="text/javascript"> var vue = new Vue({ el:"#app", methods:{ testAxios:function (event) { axios({ method:"post", url:event.target.href, params:{ username:"admin", password:"123456" } }).then(function (response) { alert(response.data); }); event.preventDefault(); } } }); </script>
編寫對(duì)應(yīng)控制器方法
package com.laoyang.mvc.controller; import com.laoyang.mvc.pojo.User; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @ClassName ResponseController * @Description: 測(cè)試 @ResponseBody 注解和 ResponseEntity 類型 * @Author Laoyang * @Date 2022/1/15 17:10 */ @Controller public class ResponseController { /** * 使用 @ResponseBody 注解處理 ajax 請(qǐng)求 */ @RequestMapping("/testAxios") @ResponseBody public String testAxios(String username, String password) { System.out.println(username + "--->" + password); return "Hello Axios"; } }
啟動(dòng)Tomcat查看效果
點(diǎn)擊鏈接后就可以獲取到控制器方法響應(yīng)到瀏覽器的數(shù)據(jù)了,控制臺(tái)中也可以看到 username 和 password 的數(shù)據(jù)了。
@RestController 注解
@RestController
注解是 SpringMVC 提供的一個(gè)復(fù)合注解,標(biāo)識(shí)在控制器的類上,就相當(dāng)于為類添加了 @Controller 注解,并且為其中的每個(gè)方法添加了 @ResponseBody 注解。
@RestController public class ResponseController { } 效果就相當(dāng)于: @Controller public class ResponseController { @ResponseBody public String testAxios(String username, String password) { System.out.println(username + "--->" + password); return "Hello"; } } 簡(jiǎn)單理解:@RestController 就相當(dāng)于是 @Controller 和 @ResponseBody 的效果的結(jié)合 > 使用這一個(gè)注解,就可以實(shí)現(xiàn)這兩個(gè)注解的效果 Ps:因?yàn)樽饔檬且粯拥?,所以這里就不演示了
ResponseEntity
- ResponseEntity 用于控制器方法的返回值類型,該控制器方法的返回值就是響應(yīng)到瀏覽器的響應(yīng)報(bào)文。
- 通過 ResponseEntity 可以實(shí)現(xiàn)文件的上傳和下載
文件下載
在 static 目錄下創(chuàng)建 img 文件夾,然后導(dǎo)入一些文件
創(chuàng)建 file.html,編寫超鏈接
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>文件上傳與下載</title> </head> <body> <h1>文件上傳與下載</h1> <a th:href="@{/download}" rel="external nofollow" >下載文件</a><br/> </body> </html>
編寫對(duì)應(yīng)控制器方法
package com.laoyang.mvc.controller; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.ServletContext; import javax.servlet.http.HttpSession; import java.io.FileInputStream; import java.io.InputStream; /** * @ClassName FileAndDownController * @Description: 文件上傳和下載 * @Author Laoyang * @Date 2022/1/16 16:36 */ @Controller public class FileAndDownController { /** * 文件下載 */ @RequestMapping("/download") public ResponseEntity<byte[]> download(HttpSession session) throws Exception { //獲取ServletContext對(duì)象 ServletContext servletContext = session.getServletContext(); //獲取服務(wù)器中文件的真實(shí)路徑 String realPath = servletContext.getRealPath("/static/img/21.jpg"); //創(chuàng)建輸入流 InputStream is = new FileInputStream(realPath); //創(chuàng)建字節(jié)數(shù)組(is.available():獲取當(dāng)前文件的字節(jié)數(shù)) byte[] bytes = new byte[is.available()]; //將流讀到字節(jié)數(shù)組中 is.read(bytes); //創(chuàng)建HttpHeaders對(duì)象設(shè)置響應(yīng)頭信息 MultiValueMap<String, String> headers = new HttpHeaders(); //設(shè)置要下載方式以及下載文件的名字 headers.add("Content-Disposition", "attachment;filename=Digimon.jpg"); //設(shè)置響應(yīng)狀態(tài)碼 HttpStatus statusCode = HttpStatus.OK; //創(chuàng)建ResponseEntity對(duì)象(參數(shù)分別是:請(qǐng)求體、請(qǐng)求頭、響應(yīng)狀態(tài)碼) ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers, statusCode); //關(guān)閉輸入流 is.close(); return responseEntity; } }
啟動(dòng)Tomcat查看效果
點(diǎn)擊瀏覽器頁(yè)面中的超鏈接,即可下載我們配置好的文件
文件上傳
文件上傳要求 form 表單的請(qǐng)求方式必須為 post,并且添加屬性 enctype="multipart/form-data"
SpringMVC 中將上傳的文件封裝到 MultipartFile 對(duì)象中,通過此對(duì)象可以獲取文件相關(guān)信息。
導(dǎo)入相關(guān)依賴
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency>
在 file.html 中編寫表單進(jìn)行文件上傳
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>文件上傳與下載</title> </head> <body> <h1>文件上傳與下載</h1> <form th:action="@{/upload}" method="post" enctype="multipart/form-data"> <input type="file" name="photo"> <input type="submit" value="上傳文件"> </form> </body> </html>
在spring-mvc.xml 文件中配置文件上傳解析器
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>
編寫對(duì)應(yīng)的控制器方法
package com.laoyang.mvc.controller; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.multipart.MultipartFile; import javax.servlet.ServletContext; import javax.servlet.http.HttpSession; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; /** * @ClassName FileAndDownController * @Description: 文件上傳和下載 * @Author Laoyang * @Date 2022/1/16 16:36 */ @Controller public class FileAndDownController { /** * 文件上傳 */ @RequestMapping("/upload") public String upload(MultipartFile photo, HttpSession session) throws IOException { // 獲取上傳的文件名 String fileName = photo.getOriginalFilename(); System.out.println(fileName); // 獲取當(dāng)前工程的上下文路徑 ServletContext servletContext = session.getServletContext(); // 給定一個(gè) URI,返回文件系統(tǒng)中 URI對(duì)應(yīng)的絕對(duì)路徑 String photoPath = servletContext.getRealPath("photo"); File file = new File(photoPath); // 判斷 photoPath 所對(duì)應(yīng)的路徑是否存在 if (!file.exists()) { // 如果不存在,則創(chuàng)建對(duì)應(yīng)目錄 file.mkdirs(); } // 最終的上傳地址 String finalPath = photoPath + File.separator + fileName; // 將文件上傳到指定的地址下 photo.transferTo(new File(finalPath)); return "success"; } }
這里上傳的最終目錄設(shè)置在
springmvc-demo4\target\springmvc-demo4-1.0-SNAPSHOT
目錄下
啟動(dòng)Tomcat查看效果
上傳成功后可在自己項(xiàng)目的
target\springmvc-demo4-1.0-SNAPSHOT
目錄下查看效果
文件上傳的重名問題
- 如果指定的目錄中有一個(gè)和我們即將要上傳的文件名稱一樣的文件,那么就會(huì)導(dǎo)致新上傳的文件覆蓋原來(lái)的文件,從而導(dǎo)致一些不必要的問題(詳細(xì)可了解 IO 流)。 使用 UUID 解決文件重名問題
package com.laoyang.mvc.controller; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.multipart.MultipartFile; import javax.servlet.ServletContext; import javax.servlet.http.HttpSession; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.UUID; /** * @ClassName FileAndDownController * @Description: 文件上傳和下載 * @Author Laoyang * @Date 2022/1/16 16:36 */ @Controller public class FileAndDownController { /** * 文件上傳 */ @RequestMapping("/upload") public String upload(MultipartFile photo, HttpSession session) throws IOException { // 獲取上傳的文件名 String fileName = photo.getOriginalFilename(); // 截取文件后綴名(lastIndexOf:獲取字符串中最后一個(gè) . 的位置) String suffix = fileName.substring(fileName.lastIndexOf(".")); // 將 UUID 作為文件名,保證唯一性 String uuid = UUID.randomUUID().toString(); // 將 UUID 和后綴名進(jìn)行拼接,得到完整的文件名 String fullName = uuid + suffix; // 獲取當(dāng)前工程的上下文路徑 ServletContext servletContext = session.getServletContext(); // 給定一個(gè) URI,返回文件系統(tǒng)中 URI對(duì)應(yīng)的絕對(duì)路徑 String photoPath = servletContext.getRealPath("photo"); File file = new File(photoPath); // 判斷 photoPath 所對(duì)應(yīng)的路徑是否存在 if (!file.exists()) { // 如果不存在,則創(chuàng)建對(duì)應(yīng)目錄 file.mkdirs(); } // 最終的上傳地址 String finalPath = photoPath + File.separator + fullName; // 將文件上傳到指定的目錄 photo.transferTo(new File(finalPath)); return "success"; } }
一般來(lái)說,UUID是不會(huì)重名的
以上就是SpringMVC將請(qǐng)求和響應(yīng)的數(shù)據(jù)轉(zhuǎn)換為JSON格式的幾種方式的詳細(xì)內(nèi)容,更多關(guān)于SpringMVC數(shù)據(jù)轉(zhuǎn)換為JSON格式的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Mybatis-Plus使用ID_WORKER生成主鍵id重復(fù)的解決方法
本文主要介紹了Mybatis-Plus使用ID_WORKER生成主鍵id重復(fù)的解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07java中對(duì)象和JSON格式的轉(zhuǎn)換方法代碼
JSON格式可以輕松地以面向?qū)ο蟮姆绞睫D(zhuǎn)換為Java對(duì)象,下面這篇文章主要給大家介紹了關(guān)于java中對(duì)象和JSON格式的轉(zhuǎn)換方法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12Java下載文件中文文件名亂碼的解決方案(文件名包含很多%)
Java下載文件時(shí),文件名中文亂碼問題通常是由于編碼不正確導(dǎo)致的,使用`URLEncoder.encode(filepath, "UTF-8")`可以解決在提示下載框中正確顯示漢字文件名的問題,但在選擇直接打開時(shí),文件名會(huì)變成亂碼,解決這個(gè)問題的方法2025-02-02引入mybatis-plus報(bào) Invalid bound statement錯(cuò)誤問題的解決方法
這篇文章主要介紹了引入mybatis-plus報(bào) Invalid bound statement錯(cuò)誤問題的解決方法,需要的朋友可以參考下2020-05-05Spring?Boot應(yīng)用打WAR包后無(wú)法注冊(cè)到Nacos的問題及解決方法
當(dāng)我們將?Spring?Boot?應(yīng)用打包成?WAR?并部署到外部?Tomcat?服務(wù)器時(shí),可能會(huì)遇到服務(wù)無(wú)法注冊(cè)到?Nacos?的情況,其原因主要是應(yīng)用獲取不到正確的服務(wù)器端口,下面給大家介紹Spring?Boot?應(yīng)用打?WAR?包后無(wú)法注冊(cè)到?Nacos的問題及解決方法,感興趣的朋友跟隨小編一起看看吧2024-06-06Spring MVC 中 AJAX請(qǐng)求并返回JSON的示例
本篇文章主要介紹了Spring MVC 中 AJAX請(qǐng)求并返回JSON,具有一定的參考價(jià)值,有興趣的可以了解一下。2017-01-01解決springboot集成swagger碰到的坑(報(bào)404)
這篇文章主要介紹了解決springboot集成swagger碰到的坑(報(bào)404),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06JAVA讀取文件流,設(shè)置瀏覽器下載或直接預(yù)覽操作
這篇文章主要介紹了JAVA讀取文件流,設(shè)置瀏覽器下載或直接預(yù)覽操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧2020-10-10在IDEA中安裝MyBatis Log Plugin插件,執(zhí)行mybatis的sql語(yǔ)句(推薦)
這篇文章主要介紹了在IDEA中安裝MyBatis Log Plugin插件,執(zhí)行mybatis的sql語(yǔ)句,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07