SpringBoot中常用數(shù)據(jù)處理方式詳解
統(tǒng)一結(jié)果響應(yīng)
為了與前端進(jìn)行數(shù)據(jù)交互時(shí),能有一個(gè)統(tǒng)一的數(shù)據(jù)結(jié)構(gòu),一般我們都需要一個(gè)統(tǒng)一響應(yīng)結(jié)果類
以下直接上代碼,粘貼可用
package com.kjyfx.response;
import java.io.Serializable;
/**
* 微信公眾號(hào):云說(shuō)Java、Java棧記
* @Created by 墨云
* @Description 統(tǒng)一響應(yīng)數(shù)據(jù)
* @Date 2020/8/29 12:33
*/
public class BaseResponse<T> implements Serializable {
private static final long serialVersionUID = 3997124446365032582L;
/**
* 返回消息
*/
private String message;
/**
* 返回對(duì)象
*/
private T data;
/**
* 是否成功
*/
private Boolean state;
/**
* 自定義錯(cuò)誤碼
*/
private Integer code;
/**
* 錯(cuò)誤,系統(tǒng)異常
*
* @return result
*/
public static BaseResponse renderError() {
BaseResponse response = new BaseResponse();
response.setState(Boolean.FALSE);
response.setCode(500);
return response;
}
/**
* 錯(cuò)誤數(shù)據(jù)(帶消息)
*
* @param msg 需要返回的消息
* @return result
*/
public static BaseResponse renderError(String msg) {
BaseResponse response = BaseResponse.renderError();
response.setMessage(msg);
return response;
}
/**
* 錯(cuò)誤數(shù)據(jù)(帶消息)
*
* @param msg 需要返回的消息
* @return result
*/
public static BaseResponse renderError(String msg, Integer code) {
BaseResponse response = BaseResponse.renderError();
response.setMessage(msg);
response.setCode(code);
return response;
}
/**
* 成功數(shù)據(jù)
*
* @return result
*/
public static BaseResponse renderSuccess() {
BaseResponse response = new BaseResponse();
response.setState(Boolean.TRUE);
response.setCode(200);
return response;
}
/**
* 成功數(shù)據(jù)(帶信息)
*
* @param msg 需要返回的信息
* @return result
*/
public static BaseResponse renderSuccess(String msg) {
BaseResponse response = BaseResponse.renderSuccess();
response.setMessage(msg);
return response;
}
/**
* 成功數(shù)據(jù)(帶數(shù)據(jù))
*
* @param obj 需要返回的對(duì)象
* @return result
*/
public static BaseResponse renderSuccess(Object obj) {
BaseResponse response = BaseResponse.renderSuccess();
response.setData(obj);
return response;
}
/**
* 成功數(shù)據(jù)(帶數(shù)據(jù),帶信息)
*
* @param msg 需要返回的信息
* @param obj 需要返回的對(duì)象
* @return result
*/
public static BaseResponse renderSuccess(String msg, Object obj) {
BaseResponse response = BaseResponse.renderSuccess();
response.setMessage(msg);
response.setData(obj);
return response;
}
/**
* 失敗數(shù)據(jù)
*
* @return result
*/
public static BaseResponse renderFail() {
BaseResponse response = new BaseResponse();
response.setState(Boolean.FALSE);
response.setCode(500);
return response;
}
/**
* 失敗數(shù)據(jù)(帶消息)
*
* @param msg 需要返回的消息
* @return result
*/
public static BaseResponse renderFail(String msg) {
BaseResponse response = BaseResponse.renderFail();
response.setMessage(msg);
return response;
}
/**
* 失敗數(shù)據(jù)(帶消息)
*
* @param msg 需要返回的消息
* @param code 自定義錯(cuò)誤碼
* @return result
*/
public static BaseResponse renderFail(String msg, Integer code) {
BaseResponse response = BaseResponse.renderFail();
response.setMessage(msg);
response.setCode(code);
return response;
}
/**
* 失敗數(shù)據(jù)(帶數(shù)據(jù),帶信息)
*
* @param msg 需要返回的信息
* @param obj 需要返回的對(duì)象
* @return result
*/
public static BaseResponse renderFail(String msg, Object obj) {
BaseResponse response = BaseResponse.renderFail();
response.setMessage(msg);
response.setData(obj);
return response;
}
/**
* 失敗數(shù)據(jù)(帶數(shù)據(jù),帶信息)
*
* @param msg 需要返回的信息
* @param obj 需要返回的對(duì)象
* @param code 自定義錯(cuò)誤碼
* @return result
*/
public static BaseResponse renderFail(String msg, Object obj, Integer code) {
BaseResponse response = BaseResponse.renderFail();
response.setMessage(msg);
response.setData(obj);
response.setCode(code);
return response;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public Boolean getState() {
return state;
}
public void setState(Boolean state) {
this.state = state;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
}
接下來(lái)我們就可以用統(tǒng)一結(jié)果響應(yīng)類進(jìn)行數(shù)據(jù)交互
@RequestMapping("/getUser")
public BaseResponse getUser(){
SysUser sysUser = new SysUser()
.setId(1000L)
.setAccount("moyun")
.setUserName("墨云");
return BaseResponse.renderSuccess("成功!",sysUser);
}
訪問(wèn)接口:http://localhost:9000/base/sysUser/getUser,得到如下數(shù)據(jù),統(tǒng)一的數(shù)據(jù)結(jié)構(gòu),也方便前端請(qǐng)求接口之后的統(tǒng)一響應(yīng)攔截處理
從code狀態(tài)碼跟state查看數(shù)據(jù)信息就很清晰
{
"message": "成功!",
"data": {
"id": 1000,
"account": "moyun",
"password": null,
"userName": "墨云",
"tel": null,
"status": null,
"createUser": null,
"createType": null,
"createTime": null,
"updateTime": null
},
"state": true,
"code": 200
}
一般在實(shí)際項(xiàng)目中,見(jiàn)得最多的就是BaseResponse和JsonResult這兩個(gè)統(tǒng)一響應(yīng)結(jié)果類,命名看個(gè)人習(xí)慣,內(nèi)部結(jié)構(gòu)都大同小異
成功結(jié)果,常用以下四個(gè)靜態(tài)方法
BaseResponse.renderSuccess(); BaseResponse.renderSuccess(String msg); BaseResponse.renderSuccess(Object obj); BaseResponse.renderSuccess(String msg, Object obj);
業(yè)務(wù)級(jí)錯(cuò)誤結(jié)果,常用以下五個(gè)靜態(tài)方法
BaseResponse.renderFail(); BaseResponse.renderFail(String msg); BaseResponse.renderFail(String msg, Integer code); BaseResponse.renderFail(String msg, Object obj); BaseResponse.renderFail(String msg, Object obj, Integer code);
系統(tǒng)級(jí)錯(cuò)誤結(jié)果,可用以下三個(gè)靜態(tài)方法(不常用,只是與業(yè)務(wù)級(jí)錯(cuò)誤進(jìn)行區(qū)分)
BaseResponse.renderError(); BaseResponse renderError(String msg); BaseResponse renderError(String msg, Integer code);
全局異常處理
全局異常處理類主要用于,當(dāng)服務(wù)器出現(xiàn)異常時(shí),將捕獲到的異常信息以json數(shù)據(jù)返給前端。
先自定義一個(gè)異常類,繼承RuntimeException
package com.kjyfx.exception;
/**
* 微信公眾號(hào):云說(shuō)Java、Java棧記
* @author moyun
* @date 2020/12/01
*/
public class MsgException extends RuntimeException{
public MsgException() {
}
public MsgException(String message) {
super(message);
}
public MsgException(String message, Throwable cause) {
super(message, cause);
}
public MsgException(Throwable cause) {
super(cause);
}
protected MsgException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
再定義一個(gè)全局異常處理器,可以自行添加其他異常處理
package com.kjyfx.exception;
import com.kjyfx.response.BaseResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.SQLException;
/**
* 微信公眾號(hào):云說(shuō)Java、Java棧記
* @author moyun
* @date 2020/12/01
*/
@RestControllerAdvice
public class GlobalExceptionHandler {
private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler(value = MsgException.class)
public BaseResponse msgExceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception e) {
logger.error(e.getMessage());
e.printStackTrace();
return BaseResponse.renderFail(e.getMessage());
}
@ExceptionHandler(value = NullPointerException.class)
public BaseResponse nullExceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception e) {
logger.error(e.getMessage());
e.printStackTrace();
return BaseResponse.renderFail("出現(xiàn)了空指針!");
}
@ExceptionHandler(value = org.springframework.web.servlet.NoHandlerFoundException.class)
public BaseResponse noHandlerFoundExceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception e) {
logger.error(e.getMessage());
return BaseResponse.renderFail("404,未找到請(qǐng)求地址");
}
@ExceptionHandler(value = IllegalArgumentException.class)
public BaseResponse illegalArgumentExceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception e) {
logger.error(e.getMessage());
e.printStackTrace();
return BaseResponse.renderFail(e.getMessage());
}
@ExceptionHandler(value = SQLException.class)
public BaseResponse sQLExceptionExceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception e) {
logger.error(e.getMessage());
return BaseResponse.renderFail("數(shù)據(jù)庫(kù)查詢異常");
}
}
當(dāng)我們?cè)L問(wèn)以下接口時(shí),sysUser對(duì)象恒為空,此時(shí)就會(huì)拋出一個(gè)MsgException
@RequestMapping("/getUser")
public SysUser getUser(){
SysUser sysUser = null;
if(null == sysUser){
throw new MsgException("服務(wù)器報(bào)了一個(gè)錯(cuò)");
}
return new SysUser();
}
此時(shí)我們?cè)L問(wèn)接口:http://localhost:9000/base/sysUser/getUser
就會(huì)得到以下數(shù)據(jù),便是全局異常處理器為我們處理的
{
"message": "服務(wù)器報(bào)了一個(gè)錯(cuò)",
"data": null,
"state": false,
"code": 500
}
全局異常處理器最主要的兩個(gè)注解,
@RestControllerAdvice:作用于類上,相當(dāng)于Controller的切面,對(duì)異常統(tǒng)一處理,定制,之后再以json格式返給前端
@ExceptionHandler:統(tǒng)一處理某一類異常,作用于方法上,捕捉到相應(yīng)異常后,會(huì)執(zhí)行其修飾的方法
例如:執(zhí)行到第四行的時(shí)候肯定會(huì)報(bào)空指針異常
@RequestMapping("/getUser")
public SysUser getUser(){
SysUser sysUser = null;
sysUser.setId(1000L);
return new SysUser();
}
訪問(wèn)接口后,將會(huì)得到全局異常處理器返回的數(shù)據(jù)
{
"message": "出現(xiàn)了空指針!",
"data": null,
"state": false,
"code": 500
}
JSON數(shù)據(jù)處理
對(duì)于以上得到的json數(shù)據(jù),如果對(duì)象屬性沒(méi)有賦值,則會(huì)顯示為null值,對(duì)前端來(lái)說(shuō)這是很不友好的,一不小心整個(gè)頁(yè)面就會(huì)癱瘓,接下來(lái)我們用SpringBoot自帶的Jackson對(duì)數(shù)據(jù)進(jìn)行轉(zhuǎn)換,將null處理為""空串
創(chuàng)建JacksonConfig配置類:
package com.kjyfx.config;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import java.io.IOException;
/**
* @Description TODO
* 微信公眾號(hào):云說(shuō)Java、Java棧記
* @Date 2020/12/10 22:20
* @Created by moyun
*/
@Configuration
public class JacksonConfig {
@Bean
@Primary
@ConditionalOnMissingBean(ObjectMapper.class)
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
SerializerProvider serializerProvider = objectMapper.getSerializerProvider();
serializerProvider.setNullValueSerializer(new JsonSerializer<Object>() {
@Override
public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
jsonGenerator.writeString("");
}
});
return objectMapper;
}
}
@Primary:
當(dāng)Spring容器掃描到某個(gè)接口的多個(gè) bean 時(shí),如果某個(gè)bean上加了@Primary 注解 ,則這個(gè)bean會(huì)被優(yōu)先選用
@ConditionalOnMissingBean:
它是修飾bean的一個(gè)注解,主要實(shí)現(xiàn)的是,當(dāng)你的bean被注冊(cè)之后,如果而注冊(cè)相同類型的bean,就不會(huì)成功,
它會(huì)保證你的bean只有一個(gè),即你的實(shí)例只有一個(gè)
之后我們重啟項(xiàng)目,再訪問(wèn)接口,會(huì)得到以下數(shù)據(jù),null成功被轉(zhuǎn)成了""空串
{
"message": "成功!",
"data": {
"id": 1000,
"account": "moyun",
"password": "",
"userName": "墨云",
"tel": "",
"status": "",
"createUser": "",
"createType": "",
"createTime": "",
"updateTime": ""
},
"state": true,
"code": 200
}
到此這篇關(guān)于SpringBoot中常用數(shù)據(jù)處理方式詳解的文章就介紹到這了,更多相關(guān)SpringBoot數(shù)據(jù)處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java實(shí)現(xiàn)限定時(shí)間CountDownLatch并行場(chǎng)景
本文將結(jié)合實(shí)例代碼,介紹Java實(shí)現(xiàn)限定時(shí)間CountDownLatch并行場(chǎng)景,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-07-07
Apache?log4j2-RCE?漏洞復(fù)現(xiàn)及修復(fù)建議(CVE-2021-44228)
Apache?Log4j2是一款Java日志框架,大量應(yīng)用于業(yè)務(wù)系統(tǒng)開(kāi)發(fā)。2021年11月24日,阿里云安全團(tuán)隊(duì)向Apache官方報(bào)告了Apache?Log4j2遠(yuǎn)程代碼執(zhí)行漏洞(CVE-2021-44228),本文給大家介紹Apache?log4j2-RCE?漏洞復(fù)現(xiàn)(CVE-2021-44228)的相關(guān)知識(shí),感興趣的朋友一起看看吧2021-12-12
java編譯后的文件出現(xiàn)xx$1.class的原因及解決方式
這篇文章主要介紹了java編譯后的文件出現(xiàn)xx$1.class的原因及解決方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12
解決mybatis批量更新(update foreach)失敗的問(wèn)題
這篇文章主要介紹了解決mybatis批量更新(update foreach)失敗的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11
SpringBoot結(jié)合mockito測(cè)試實(shí)戰(zhàn)
與集成測(cè)試將系統(tǒng)作為一個(gè)整體測(cè)試不同,單元測(cè)試更應(yīng)該專注于某個(gè)類。所以當(dāng)被測(cè)試類與外部類有依賴的時(shí)候,尤其是與數(shù)據(jù)庫(kù)相關(guān)的這種費(fèi)時(shí)且有狀態(tài)的類,很難做單元測(cè)試。但好在可以通過(guò)“Mockito”這種仿真框架來(lái)模擬這些比較費(fèi)時(shí)的類,從而專注于測(cè)試某個(gè)類內(nèi)部的邏輯2022-11-11
springboot項(xiàng)目關(guān)閉swagger如何防止漏洞掃描
這篇文章主要介紹了springboot項(xiàng)目關(guān)閉swagger如何防止漏洞掃描,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-05-05
詳解MyBatis-Puls中saveBatch批量添加慢的問(wèn)題
本文主要介紹了詳解MyBatis-Puls中saveBatch批量添加慢的問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01
java實(shí)現(xiàn)簡(jiǎn)單的驗(yàn)證碼功能
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡(jiǎn)單的驗(yàn)證碼功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04
Mybatis如何實(shí)現(xiàn)關(guān)聯(lián)屬性懶加載
這篇文章主要介紹了Mybatis如何實(shí)現(xiàn)關(guān)聯(lián)屬性懶加載的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07

