Java封装返回数据类型

共 6014字,需浏览 13分钟

 ·

2021-12-11 10:32

介绍

在做Java请求返回json数据的时候,我们常做的就是封装数据类型,每个方法的返回类型都是自己定义封装的数据类型,我如果在方法上直接定义void类型,是否就不能返回json数据了呢,我做了下面的测试。

自定义封装类


package org.jeemp.common;

import org.jeemp.enums.IErrorCode;
import org.jeemp.enums.ResultCode;

/**
* 通用返回对象
*/

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;
}

/**
* 成功返回结果
*
* @param data 获取的数据
*/

public static CommonResult success(T data) {
return new CommonResult(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data);
}

/**
* 成功返回结果
*
* @param data 获取的数据
* @param message 提示信息
*/

public static CommonResult success(T data, String message) {
return new CommonResult(ResultCode.SUCCESS.getCode(), message, data);
}

/**
* 失败返回结果
* @param errorCode 错误码
*/

public static CommonResult failed(IErrorCode errorCode) {
return new CommonResult(errorCode.getCode(), errorCode.getMessage(), null);
}

/**
* 失败返回结果
* @param message 提示信息
*/

public static CommonResult failed(String message) {
return new CommonResult(ResultCode.FAILED.getCode(), message, null);
}

/**
* 失败返回结果
*/

public static CommonResult failed() {
return failed(ResultCode.FAILED);
}

/**
* 参数验证失败返回结果
*/

public static CommonResult validateFailed() {
return failed(ResultCode.VALIDATE_FAILED);
}

/**
* 参数验证失败返回结果
* @param message 提示信息
*/

public static CommonResult validateFailed(String message) {
return new CommonResult(ResultCode.VALIDATE_FAILED.getCode(), message, null);
}

/**
* 未登录返回结果
*/

public static CommonResult unauthorized(T data) {
return new CommonResult(ResultCode.UNAUTHORIZED.getCode(), ResultCode.UNAUTHORIZED.getMessage(), data);
}

/**
* 未授权返回结果
*/

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;
}
}

方法中直接调用:

@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);,怎么将代码中的数据对象传出去?

这边想到的是做一个拦截器,将数据对象转json后传出去:

/**
* @author JackRen
* @date 2021-12-08 16:19
* @description:
*/

@Component
public class JeempInterceptor implements HandlerInterceptor {

@Autowired
private InitUrlService initUrlService;

/**
* controller方法结束之后调用如果有controller方法有异常则不会调用
* @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:打印日志,后续加入
}
}

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");
//根据获取的请求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);
}

}


总结

void声明说了那么多,其实就是将返回的数据对象通过HttpServletResponse返回,如果想要做到通用,最简单的办法就是自己定义一些规则,比如在定义bean的时候自己定义名称,方法的请求url必须以bean的名称开头,在拦截的时候可以根据这样的规则找到bean,进而可以拿到这个类上要传递的数据。

我这边没有定义规则,我想的是根据url反向查找类名,接口名,注解值,然后根据拿到的类名再去查找bean,但是会有一些问题,比如不同的开发人员在定义bean的时候,有的不去定义,系统默认处理,但是有的同事却自己定义,这样的话根据类型就找不到这个bean,所以会出现问题。

最好的解决办法就是自己定义规则,所有的请求按照自己的规则来,然后自己按照规则进行处理,这样就可以在方法返回类型中直接定义void。


浏览 55
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报