2.10.1.概述
整合思路
在jfinal中添加DispatcherServlet,DispatcherServlet加载spring的配置文件
2.10.2.整合spring-mvc
创建工程jfinal-4.9-spring-mvc-4.1.6
pom.xml
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jdk.version>1.8</jdk.version>
</properties>
<dependencies>
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>jfinal-undertow</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>jfinal</artifactId>
<version>4.9.01</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<!-- java编译插件 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 默认的注解映射的支持 --> <mvc:annotation-driven /> <!-- 开启controller注解支持 --> <context:component-scan base-package="com.alit.jfinal.springmvc.controller" /> </beans>
启动类AppConfig.java
package com.alit.jfinal.springmvc;
import com.jfinal.config.Constants;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors;
import com.jfinal.config.JFinalConfig;
import com.jfinal.config.Plugins;
import com.jfinal.config.Routes;
import com.jfinal.server.undertow.UndertowServer;
import com.jfinal.template.Engine;
public class AppConfig extends JFinalConfig {
public static void main(String[] args) {
UndertowServer.create(AppConfig.class).configWeb(builder -> {
// 配置 Servlet
String servletName = "dispathcer";
builder.addServlet(servletName, "org.springframework.web.servlet.DispatcherServlet");
builder.addServletMapping(servletName, "*.do");
builder.addServletInitParam(servletName, "contextConfigLocation", "classpath:spring-mvc.xml");
builder.setServletLoadOnStartup(servletName, 0);
}).start();
}
public void configConstant(Constants me) { me.setDevMode(true);}
public void configRoute(Routes me) { }
public void configEngine(Engine me) { }
public void configPlugin(Plugins me) { }
public void configInterceptor(Interceptors me) { }
public void configHandler(Handlers me) { }
}HelloController.java
package com.alit.jfinal.springmvc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("Hello")
public class HelloController {
@RequestMapping()
@ResponseBody
public String index() {
return "Hello,World";
}
}启动之后访问成功
http://localhost/Hello.do

2.10.3.实现完美整合
[背景]
如果设置dispatcher的拦截路径为/ 则会测试失败
builder.addServletMapping(servletName, "/");

原因肯定是jfinal拦截了/
分析源码
UndertowServer.configJFinalFilter() 配置如下

JFinalFiler 的doFiler方法
isHander声明为false,但是经过 handler.hanlder之后就变成了true

通过debug调试进入发现进入到了ActionHandler
在ActionHandler中 getAction返回的所以执行了下图所示的上面的代码,返回了404

[解决思路1]
新增一个Handler,新增的SpringMVCHander默认会在ActionHanlder之前执行,根据url获取action,如果action为null,直接返回,此时isHandler第一个元素是false
[解决思路2]
修改ActionHanlder源码,将isHanlder[0]=true向下移动几行,如果action为null直接返回,不执行render方法
[解决思路3]
修改JFinalFiler,取消handler,直接使用spring mvc
我最终选择的是解决思路1但是ActionMapping从哪里来呢?发现JFinal有1个获取action的方法
JFinal.me().getAction(url, urlPara)
编写SpringMVCHandler
package com.alit.jfinal.springmvc.handler;
package com.alit.jfinal.springmvc.handler;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.jfinal.core.Action;
import com.jfinal.core.JFinal;
import com.jfinal.handler.Handler;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class SpringMVCHandler extends Handler {
public void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
// 1.静态文件返回
if (target.indexOf('.') != -1) {
return;
}
String[] urlPara = { null };
Action action = JFinal.me().getAction(target, urlPara);
if (action == null) {
String requestURI = request.getRequestURI();
log.info("{} action is null ,return", requestURI);
return;
}
// 让actionHanlder执行
next.handle(target, request, response, isHandled);
}
}测试访问
添加到启动类
public void configHandler(Handlers me) {
me.add(new SpringMVCHandler());
}显示日志

处理成功

设置undertow.properties,修改controller文件后按Ctrl+S保存也会自动生效

undertow.properties
undertow.devMode=true
重新启动是0.2s
访问1个不存在的路径

以前一些同学是改掉 jfinal-undertow 项目中的 JFinalFilter 换成 spring 的东东,显然不如这个方案好