Java封裝返回?cái)?shù)據(jù)類型
介紹
在做Java請(qǐng)求返回json數(shù)據(jù)的時(shí)候,我們常做的就是封裝數(shù)據(jù)類型,每個(gè)方法的返回類型都是自己定義封裝的數(shù)據(jù)類型,我如果在方法上直接定義void類型,是否就不能返回json數(shù)據(jù)了呢,我做了下面的測(cè)試。
自定義封裝類
package org.jeemp.common;
import org.jeemp.enums.IErrorCode;
import org.jeemp.enums.ResultCode;
/**
* 通用返回對(duì)象
*/
public class CommonResult<T> {
private long code;
private String message;
private T data;
protected CommonResult() {
}
protected CommonResult(long code, String message, T data) {
this.code = code;
this.message = message;
this.data = data;
}
/**
* 成功返回結(jié)果
*
* @param data 獲取的數(shù)據(jù)
*/
public static CommonResult success(T data) {
return new CommonResult(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data);
}
/**
* 成功返回結(jié)果
*
* @param data 獲取的數(shù)據(jù)
* @param message 提示信息
*/
public static CommonResult success(T data, String message) {
return new CommonResult(ResultCode.SUCCESS.getCode(), message, data);
}
/**
* 失敗返回結(jié)果
* @param errorCode 錯(cuò)誤碼
*/
public static CommonResult failed(IErrorCode errorCode) {
return new CommonResult(errorCode.getCode(), errorCode.getMessage(), null);
}
/**
* 失敗返回結(jié)果
* @param message 提示信息
*/
public static CommonResult failed(String message) {
return new CommonResult(ResultCode.FAILED.getCode(), message, null);
}
/**
* 失敗返回結(jié)果
*/
public static CommonResult failed() {
return failed(ResultCode.FAILED);
}
/**
* 參數(shù)驗(yàn)證失敗返回結(jié)果
*/
public static CommonResult validateFailed() {
return failed(ResultCode.VALIDATE_FAILED);
}
/**
* 參數(shù)驗(yàn)證失敗返回結(jié)果
* @param message 提示信息
*/
public static CommonResult validateFailed(String message) {
return new CommonResult(ResultCode.VALIDATE_FAILED.getCode(), message, null);
}
/**
* 未登錄返回結(jié)果
*/
public static CommonResult unauthorized(T data) {
return new CommonResult(ResultCode.UNAUTHORIZED.getCode(), ResultCode.UNAUTHORIZED.getMessage(), data);
}
/**
* 未授權(quán)返回結(jié)果
*/
public static CommonResult forbidden(T data) {
return new CommonResult(ResultCode.FORBIDDEN.getCode(), ResultCode.FORBIDDEN.getMessage(), data);
}
public long getCode() {
return code;
}
public void setCode(long code) {
this.code = code;
}
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;
}
}
方法中直接調(diào)用:
@GetMapping("/testJson")
public CommonResult testJson() {
Map map = initUrlService.obtainMapUrls();
return CommonResult.success(map);
} 
方法返回類型直接聲明void
@GetMapping("/obtainUserInfo")
public void obtainUserInfo() {
Map map = new HashMap<>();
map.put("name","jack");
map.put("age",16);
setRespAttr("dataMaps",map);
} 最主要的就是setRespAttr("dataMaps",map);,怎么將代碼中的數(shù)據(jù)對(duì)象傳出去?
這邊想到的是做一個(gè)攔截器,將數(shù)據(jù)對(duì)象轉(zhuǎn)json后傳出去:
/**
* @author JackRen
* @date 2021-12-08 16:19
* @description:
*/
@Component
public class JeempInterceptor implements HandlerInterceptor {
@Autowired
private InitUrlService initUrlService;
/**
* controller方法結(jié)束之后調(diào)用如果有controller方法有異常則不會(huì)調(diào)用
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
parseControllerModel(request,response);
}
private void parseControllerModel(HttpServletRequest req, HttpServletResponse resp) throws Exception {
String className=obtainClassName(req,resp);
try {
BaseController baseController = (BaseController) ApplicationUtil.getBean(className);
if (baseController==null) {
return;
}
writeJson(req,resp,baseController.getRespMap());
}catch (Exception e){
// TODO:打印日志,后續(xù)加入
}
}
private String obtainClassName(HttpServletRequest req, HttpServletResponse resp) throws Exception {
final String contextPath = req.getContextPath();
final String requestURI = req.getRequestURI();
String path = requestURI.substring(contextPath.length());
path = URLDecoder.decode(path, "UTF-8");
//根據(jù)獲取的請(qǐng)求url獲取className
Map map = initUrlService.obtainMapUrls();
if (map==null) {
return "";
}
return StrUtil.removePreAndLowerFirst(String.valueOf(map.get(path)), Constant.PREFIX_URL);
}
private void writeJson(HttpServletRequest req, HttpServletResponse resp, Map model) throws Exception {
writeRespHeaders(req, resp);
resp.setHeader("Content-Type", "text/plain; charset=UTF-8");
Writer out = resp.getWriter();
out.write(toJson(model));
}
private void writeRespHeaders(HttpServletRequest req, HttpServletResponse resp) {
// http://blog.55minutes.com/2011/10/how-to-defeat-the-browser-back-button-cache/
resp.setHeader("Cache-Control", "no-cache, max-age=0, must-revalidate, no-store");
resp.setHeader("Pragma", "no-cache"); // HTTP 1.0 backward compatibility
resp.setDateHeader("Expires", 0); // Causes the proxy cache to see the page as "stale"
}
public String toJson(Object obj) {
if (obj == null) {
return null;
}
return JSON.toJSONString(obj, SerializerFeature.DisableCircularReferenceDetect);
}
} 
總結(jié)
void聲明說了那么多,其實(shí)就是將返回的數(shù)據(jù)對(duì)象通過HttpServletResponse返回,如果想要做到通用,最簡單的辦法就是自己定義一些規(guī)則,比如在定義bean的時(shí)候自己定義名稱,方法的請(qǐng)求url必須以bean的名稱開頭,在攔截的時(shí)候可以根據(jù)這樣的規(guī)則找到bean,進(jìn)而可以拿到這個(gè)類上要傳遞的數(shù)據(jù)。
我這邊沒有定義規(guī)則,我想的是根據(jù)url反向查找類名,接口名,注解值,然后根據(jù)拿到的類名再去查找bean,但是會(huì)有一些問題,比如不同的開發(fā)人員在定義bean的時(shí)候,有的不去定義,系統(tǒng)默認(rèn)處理,但是有的同事卻自己定義,這樣的話根據(jù)類型就找不到這個(gè)bean,所以會(huì)出現(xiàn)問題。
最好的解決辦法就是自己定義規(guī)則,所有的請(qǐng)求按照自己的規(guī)則來,然后自己按照規(guī)則進(jìn)行處理,這樣就可以在方法返回類型中直接定義void。
