jfinal每个包中写FastJson.getJson().parse(rawData, xxx.class)
有些重复,而且有时候如果数据格式转换失败的话,直接返回错误页面。导致ajax
请求获取不到json
数据。
个人增加了一个助手类,可以getBean,也可以getRawData。也可以先检测是否为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())); } }
觉得还行的话给我的博客点个赞吧,谢谢您。