最近要写个公司内部使用的代码生成器,想学习新东西,打算 用 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;
}