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 的东东,显然不如这个方案好