简单且强大的ReturnInterceptor拦截器

在项目开发中经常会写如下代码:

public void doPublish() {
 // 从param中获取name 和 age
 if(StrKit.isBlank("name")) {
	renderJson(Ret.by("msg", "名称不能为空"));
	return;
 }
 if(StrKit.isBlank("age")) {
       renderJson(Ret.by("msg", "年龄不能为空"));
       return;		
 }		
 Ret ret = xxService.publish(name,age);//你的业务方法调用返回结果....
 renderJson(ret);
}

增加ReturnInterceptor拦截器后:

public Ret doPublish() {
 // 从param中获取name 和 age
 if(StrKit.isBlank("name")) {
  return Ret.by("msg", "名称不能为空");
 }
 if(StrKit.isBlank("age")) {
  return Ret.by("msg", "年龄不能为空");
 }
 return xxService.publish(name,age);
}

ReturnInterceptor拦截器代码:

public class ReturnInterceptor implements FixedInterceptor {

	@Override
	public void intercept(Invocation inv) {
		              inv.invoke();
		  Controller ctrl = inv.getController();
		  if (ctrl != null) {
			    Object result = inv.getReturnValue();
			    // 只有存在返回值时才进行render处理,否则使用默认方式,例如可能是renderHtml
			   if (result != null) {
				     ctrl.renderJson(result);
			  }
		 }
	}
}


不知道大家有没做这样小玩意的封装  ^-^ ?


评论区

JFinal

2020-06-02 22:04

这种用法节省了代码,非常赞

有个小建议, Object ret = inv.getReturnValue() 还可以做得更智能一些,例如:
if (ret intanceof String) {
render((String)ret);
} else {
renderJson(ret);
}


这样改进的话, controller 中就可以这么来玩了:
public Ret doPublish() {
// 从param中获取name 和 age
if(StrKit.isBlank("name")) {
return Ret.by("msg", "名称不能为空");
}
if(StrKit.isBlank("age")) {
return Ret.by("msg", "年龄不能为空");
}

if (notLogin()) {
return "login.html";
}

return "index.html";
}

杜福忠

2020-06-02 22:10

有啊~ 开发接口的时候就差不多这样封装的, 把结果封装成JSON,还有接收参数也打包为JSON对象。还有把StrKit.isBlank也封装了一下,直接把JSON传入kit后取值,值不存在的时候直接返回错误码,并告诉缺失哪个参数等等小封装,2333 我也贴一下链接吧~ https://gitee.com/yun_final/JFinal-API

leomj

2020-06-03 08:23

@JFinal get 到了

leomj

2020-06-03 08:24

@杜福忠 JFinal-API挺好,决定借鉴用用。

caoxusheng

2020-06-03 09:16

判断指定的类型 更简单吧
if (inv.getReturnValue() instanceof ResponseResult) {
ResponseResult rr = inv.getReturnValue();
c.renderJson(rr);
}

逍遥一生

2020-06-03 13:52

我也是使用同样的方式,把return的值在拦截器中处理返回,同时把一些异常也统一处理了。
Controller controller = inv.getController();
try {
inv.invoke();
Object returnValue = inv.getReturnValue();

// 支持jfinal原生的返回void的请求
if (returnValue == null) {
return;
}

if (returnValue instanceof ResponseBean) {
controller.renderJson(returnValue);
} else {
controller.renderJson(ResponseBean.success(returnValue));
}
} catch (NoLoginException e) {
controller.renderJson(ResponseBean.error(ResponseErrorEnums.NOLOGIN));
} catch (ParamsValideException e) {
controller.renderJson(ResponseBean.error(e.getErrorMsg()));
} catch (ServiceException e) {
controller.renderJson(ResponseBean.error(e.getCode(), e.getMsg()));
} catch (Exception e) {
String errorMsg = "服务器出现异常";
if (!StrKit.isBlank(e.getMessage())) {
logger.error(e.getMessage());
errorMsg = e.getMessage();
}
e.printStackTrace();
controller.renderJson(ResponseBean.error(errorMsg));
} finally {
RequestContextUtil.remove();
}

JFinal

2020-06-03 14:06

@逍遥一生 或许添加一个对于 render 的判断为好,因为在 action 中可能使用了 render 方法,加这个判断:

if (inv.getController().getRender() != null) {
return ;
}

getRender() 方法如果返回的不是 null,证明在 controller 中调用过 render 系列的方法,或者 redirect 方法

逍遥一生

2020-06-03 14:33

@JFinal 嗯 这个确实要加上

JFinal

2020-06-03 15:26

@逍遥一生 除了加这个,最好还加上这个判断:
if (inv.getReturnValue() != null) {
...
}

当返回值为 null 的时候,证明 action 方法返回为 void,例如:
public void index() {
}

BTMTimor

2020-06-03 18:56

public class ApiInterceptor implements Interceptor {
public static final String RENDER_JSON = "json";
private ActionCache action = new ActionCache();

@Override
public void intercept(Invocation invocation) {
// 这里只处理通过返回值返回客户端的数据
ApiController annotation = invocation.getController().getClass().getAnnotation(ApiController.class);
invocation.invoke();
if(null != annotation){
process(invocation , annotation);
}
}

public void process(Invocation invocation, ApiController annotation){
if(action.notReturnVoid(invocation)){
Object returnValue = invocation.getReturnValue();
String renderType = annotation.value().toLowerCase();
if (RENDER_JSON.equals(renderType)){
invocation.getController().renderJson(returnValue);
}
}
}

static class ActionCache{
HashMap mapping = new HashMap<>();

public boolean notReturnVoid(Invocation invocation){
return !isReturnVoid(invocation);
}

public boolean isReturnVoid(Invocation invocation) {
String target = invocation.getActionKey();
if (mapping.containsKey(target)) {
return mapping.get(target);
}else {
boolean isReturnVoid = invocation.getMethod().getReturnType().equals(Void.TYPE);
mapping.put(target, isReturnVoid);
return isReturnVoid;
}
}
}

}

BTMTimor

2020-06-03 18:58

很久很久以前的代码了,可以参考改进一下

JFinal

2020-06-03 19:49

@BTMTimor 看来好多人都这么用过

逍遥一生

2020-06-04 11:38

@JFinal 这个判断过了 如果是null直接return;

热门分享

扫码入社