转自我原先在Jfinal官网写的文章
序
偷懒,关于如何实现 Message
与 Bean 多对多映射,有思路但是还没有理清逻辑,所以先转载一下自己的文章,养成写作的习惯,不能再鸽了,以下内容是之间复制过来,没有做任何调整,毕竟我现在有点头昏脑胀。
原文
最近要写个公司内部使用的代码生成器,想学习新东西,打算 用 Groovy 和 JFinal。
发现 JFinal 对 body 中 Json 处理不如 Spring 那样方便,无法自动将 Json 转成 Bean 传入 action 中, 就研究源码,写了一个插件,将相关操作进行封装,工程中只要引入插件就可以了。
有两个前提条件, 如果你也用 Groovy 开发 JFinal ,这个插件可以直接使用,否则需要改写成 Java 版本,由于 Groovy 的语法挺好理解的(我最后这版使用比较多的 Groovy 的特性,原先 Java 版本写法的注释为了代码的简洁,我都删除了),这个改写并不难,我就不实现了;另一个是我发现 Groovy 有原生的 Json 实现,我将原先的 fastjson 改成了 GroovyJson ,如果 java 要用请自行改成 FastJson 或者其他 json 实现(在我写这篇文章的时候,FastJson 还是个不错的,但是最近出现太多的问题了,建议使用 Jackson 2)。
在我的基础上还可以增加对更多 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;
}