最近要写个公司内部使用的代码生成器,想学习新东西,打算 用 Groovy 和 JFinal。
发现JFinal对body中json处理不如Spring那样方便,无法自动将json转成bean传入action中, 就研究源码,写了一个插件,将相关操作进行封装,工程中只要引入插件就可以了。
有两个前提条件, 如果你也用Groovy开发JFinal,这个插件可以直接使用,否则需要改写成java版本,由于Groovy的语法挺好理解的(我最后这版使用比较多的Groovy的特性,原先java版本写法的注释为了代码的简洁,我都删除了),这个改写并不难,我就不实现了;另一个是我发现Groovy有原生的Json实现,我将原先的fastjson改成了 GroovyJson,如果java要用请自行改成FastJson或者其他json实现。
在我的基础上还可以增加对更多contentType 类型的处理。
插件代码:
/** * 对ContentType的处理插件 * @author MRZC * */ class ContentTypePlugin implements IPlugin{ @Override public boolean start() { // 引入FastJson作为Json转换的实现 Config.constants.jsonFactory = new GroovyJsonFactory() // 引入 ContentType 的拦截器 Config.interceptors.addGlobalActionInterceptor new ContentTypeInterceptor() return true } @Override public boolean stop() { // 没有释放的资源 true } } import com.jfinal.aop.Interceptor as JfianlInterceptor /** * 对application/json的拦截器 * @author MRZC * */ class ContentTypeInterceptor implements JfianlInterceptor { @Override public void intercept(Invocation inv) { def controller = inv.controller def contentType = controller.request.contentType def parameterTypes = inv.method.parameterTypes // 判断contentType 是否包含 application/json,并且action函数是否只有一个参数 if(contentType?.indexOf("application/json") > -1 && parameterTypes.length == 1) { // 将body体中的json转成bean def arg = JsonKit.parse(controller.rawData, parameterTypes[0]) // 替换原先的参数 inv.setArg(0, arg) } inv.invoke() } } /** * Groovy版本IJsonFactory实现 * @author MRZC * */ class GroovyJsonFactory implements IJsonFactory { @Override public Json getJson() { new GroovyJson(); } } /** * Json 转换 Groovy 实现 * @author MRZC * */ class GroovyJson extends Json { @Override public String toJson(Object o) { JsonOutput.toJson o } @Override public <T> T parse(String json, Class<T> t) { def jsonSlurper = new JsonSlurper() def map = jsonSlurper.parseText json if(t == Object || t == GroovyObject) { return map } t.newInstance map } }
使用样例:
class Main extends JFinalConfig{ static void main(args) { UndertowServer.start(Main, 80, true); } @Override public void configConstant(Constants me) { me.devMode = true } @Override public void configRoute(Routes me) { me.add("/", Index); } @Override public void configEngine(Engine me) {} @Override public void configPlugin(Plugins me) { // 引入对ContentType的处理插件 me.add new ContentTypePlugin() } @Override public void configInterceptor(Interceptors me) {} @Override public void configHandler(Handlers me) {} } class Index extends Controller { public index(User u) { // 将请求Json再转成Json输出,用于验证 renderJson(JsonKit.toJson(u)) } public groovy(o) { // 验证默认的Map类型 renderText o.getClass().toString() + " " + o.name } } class User { def name; }