jfinal每个包中写FastJson.getJson().parse(rawData, xxx.class)
有些重复,而且有时候如果数据格式转换失败的话,直接返回错误页面。导致ajax
请求获取不到json
数据。
个人增加了一个助手类
package com.my.rep.common.assist;
import com.alibaba.fastjson.JSONException;
import com.jfinal.core.Controller;
import com.jfinal.core.Injector;
import com.jfinal.json.FastJson;
import com.my.rep.common.myException.ModelFormatException;
import javax.servlet.http.HttpServletRequest;
/**
* @date 2019/11/20 - 19:45
*/
public class ControllerAssist extends Controller {
private static final String EMPTY_STRING = "";
private static final String EMPTY_OBJECT = "{}";
private static final String JSON_HEADER = "application/json";
private static final String CONTENT_TYPE = "Content-Type";
/**
* 转换rataData为指定类型对象
* @param cla 需要转换成的类
* @param rawData rawData,json类型的请求数据
* @param throwError 是否抛出异常
* @return 转换后的对象
*/
public Object getObject(Class<?> cla, String rawData, Boolean throwError) {
try {
Object result = FastJson.getJson().parse(rawData, cla);
System.out.println(result);
if (EMPTY_OBJECT.equals(result.toString())) {
if (throwError) {
throw new ModelFormatException();
} else {
return null;
}
}
return result;
} catch (JSONException err) {
if (throwError) {
throw new ModelFormatException();
} else {
return null;
}
}
}
public Object getObject(Class<?> cla, String rawData) {
return getObject(cla, rawData, true);
}
/**
* 转换application/x-www-form-urlencoded或者multipart/form-data的数据为bean对象
* @param cla 需要转换为的bean类
* @param request 本次请求
* @return 转换后的结果
*/
public Object getBean(Class<?> cla, HttpServletRequest request) {
return getBean(cla, request, true);
}
public Object getBean(Class<?> cla, HttpServletRequest request, boolean throwError) {
final Object result = Injector.injectBean(cla, "", request, false);
if (EMPTY_OBJECT.equals(result.toString())) {
if (throwError) {
throw new ModelFormatException();
} else {
return null;
}
} else {
return result;
}
}
}
其中的错误是自己定义的。如下
其中,所有错误类型继承MyException
,方便后续的同一控制,MyException继承RuntimeException
。
新建一个类用来控制所有的错误信息
public class MyExceptionTip {
public static final String UPLOAD = "上传格式有误";
public static final String MODEL_FORMAT = "数据格式有误";
public static final String NO_DATA = "没有找到任何有关信息";
}
拿其中一个错误举例子:
public class ModelFormatException extends MyException {
public ModelFormatException() {
this(MyExceptionTip.MODEL_FORMAT);
}
public ModelFormatException(String message) {
super(message);
}
// ...省略构造方法
}
重点来了
创建一个处理异常的拦截器
public class ModelFormatInterceptor implements Interceptor {
@Inject
private MyErrorHandle errorHandle;
@Override
public void intercept(Invocation inv) {
try {
inv.invoke();
} catch (MyException e) {
errorHandle.render(inv, e);
}
}
}
上面的异常处理中,重点可以把MyException
写为RuntimeException
,这样就可以对所有的错误都返回其信息了。(不过没有继承MyExcption
的例如NullPointerException
返回的错误信息就是默认的getMessage()了,见下面的个人的MyErrorHandle
实现就可知晓了)。
// 方便复用
public class MyErrorHandle {
@Inject
private MyConnectKit connectKit;
public void render(Invocation inv, RuntimeException e) {
final HttpServletRequest request = inv.getController().getRequest();
// 如果是ajax请求,返回错误信息,否则抛出错误即可,因为抛出错误后jfinal框架会返回错误页面的。
if (isAjax(request)) {
inv.getController().renderJson(MyRet.fail(e.getMessage()));
} else {
throw e;
}
}
public void render(Invocation inv, String errorMessage) {
this.render(inv, new RuntimeException(errorMessage));
}
public boolean isAjax(HttpServletRequest request) {
return "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
}
}
上述的MyRet
只是简单封装了一下Ret
。
public class MyRet extends Ret {
public static final String DATA = "data";
public static final String MESSAGE = "message";
public MyRet() {
}
public static Ret ok(Object object) {
return ok().set(DATA, object);
}
public static Ret fail (String message) {
return fail().set(MESSAGE, message);
}
}
最后配置Config
中的全局拦截器就好了
@Override
public void configInterceptor(Interceptors me) {
me.addGlobalActionInterceptor(new ModelFormatInterceptor());
}
个人简单应用举例子:
public class UserController extends Controller {
@Inject
private UserService service;
@Inject
private ControllerAssist controllerAssist;
private User getUser() {
return (User) controllerAssist.getObject(User.class, getRawData());
// 根据需要可以随时切换为
// return (User) controllerAssist.getBean(User.class, this.getRequest());
// 也可以改为那个二者检测版本的方法
}
/**
* 获得当前用户代言店铺列表
* @render List<Shop>
*/
public void getRepShopList() {
renderJson(service.getRepShopList(getUser()));
}
/**
* 得到用户信息
* @render Model: User
*/
public void getInfo() {
renderJson(service.getInfo(getUser()));
}
}