jfinal-undertow实践笔记

实践常见问题记录

1、两个web项目依赖问题

比如:业务biz-web依赖公共share-web,需要配置告诉undertow去share-web项目查找资源文件
undertow.txt文件中配置:(biz-web和share-web在同一个目录)

# 配置 css、js、图片等等 web 资源路径
# "src/main/webapp" 表示从普通路径中加载资源, "classpath:static" 表示从 classpath 与 jar 包中的 static 路径下加载资源
undertow.resourcePath=../share-web/src/main/webapp, src/main/webapp, classpath:static

上面这种情况,基于share-web项目的共享,share-web中只能放静态资源文件。

注意:enjoy的模板文件jfinal原有是不支持,jfianl enjoy engin默认只从web的目的查找enjoy template模板文件,且engin设置baseTemplatePath也只能一个目录,即不会去多个目录中查找enjoy template模板文件。

    解决方式探讨:1、自定义实现一个ISourceFactory,根据需要返回对应的ISource。 2、全部改为java普通应用开发,所有的资源文件(静态文件和模板文件)保存在源码目录,从classpath中加载所有的文件。


2、集成shiro

2.1 把web.xml 中的shiro配置,放到java config中

public static void main(String[] args) {
// 在jvm加载log4j.properties之前设置变量,项目根目录绝对路径,用于log4j.properties中设置自定义日志文件输出路径
String webRootPath=PathKitExt.getWebRootPath();
System.out.println("***********webRootPath="+webRootPath);
System.setProperty("webRootPath", webRootPath);
boolean devMode = true;
UndertowServer server = UndertowServer.create(AppConfig.class);
server.addHotSwapClassPrefix("org.apache.shiro.");
// 设置为 true 时支持热加载,开发环境必配置项。建议在配置文件中进行配置: undertow.devMode=true
// 配置文件中配置便于生产环境修改该项配置,提升性能 注意:undertow.devMode 与 jfinal 中的 devMode 没有任何关系
server.setPort(80).setDevMode(devMode);
server.configWeb(webBuilder -> {
webBuilder.addListener(EnvironmentLoaderListener.class.getName());
webBuilder.addFilter("ShiroFilter", ShiroFilter.class.getName());
///WEB-INF/anotherFile.ini
webBuilder.addFilterInitParam("ShiroFilter", "configPath", "classpath:shiro.ini");
webBuilder.addFilterUrlMapping("ShiroFilter", "/*", DispatcherType.REQUEST);
webBuilder.addFilterUrlMapping("ShiroFilter", "/*", DispatcherType.FORWARD);
webBuilder.addFilterUrlMapping("ShiroFilter", "/*", DispatcherType.INCLUDE);
webBuilder.addFilterUrlMapping("ShiroFilter", "/*", DispatcherType.ERROR);
// webBuilder.addFilterInitParam("ShiroFilter", "key", "value");
});
System.out.println("WebShareMain启动服务");
server.start();
}

2.2 基于jfinal的Interceptor,实现的shiro注解调用。即shiro的5个注解在Controller的方法生效,只需要继承shiro已经为扩展准备好的AnnotationsAuthorizingMethodInterceptor类即可。

/**
 * 通过shiro的实现AnnotationsAuthorizingMethodInterceptor
 * 需要把jfinal的com.jfinal.aop.Invocation转换为org.apache.shiro.aop.MethodInvocation
 * >>DefaultAnnotationResolver
 */
public class JfinalShiroInterceptor extends AnnotationsAuthorizingMethodInterceptor implements Interceptor {
private static final Logger logger = LoggerFactory.getLogger(JfinalShiroInterceptor.class);
@Override
public void intercept(final Invocation inv) {
// controller的方法上的shiro注解验证
MethodInvocation methodInvocation = new MethodInvocation() {
@Override
public Object proceed() throws Throwable {
// TODO Auto-generated method stub
return inv.getReturnValue();
}
@Override
public Object getThis() {
// TODO Auto-generated method stub
return inv.getTarget();
}
@Override
public Method getMethod() {
// TODO Auto-generated method stub
return inv.getMethod();
}
@Override
public Object[] getArguments() {
// TODO Auto-generated method stub
return inv.getArgs();
}
};
Controller  c = inv.getController();
try {
// 执行权限检查
assertAuthorized(methodInvocation);
// 执行正常逻辑
inv.invoke();
}catch (UnauthenticatedException lae) {
//未登录
//401:RequiresGuest,RequiresAuthentication,RequiresUser,未满足时,抛出未经授权的异常。
//c.renderError(401, new TextRender("<div><h1>401</h1><hr/> shiro+jfinal 未经授权!<div>"));
} catch (AuthorizationException ae) {
//未授权
// RequiresRoles,RequiresPermissions授权异常
// 401 :如果没有权限访问对应的资源,返回HTTP状态码401或者调转到为授权页面
}
}
}

极简方式集成Shiro@toni在两年前已经有博客说明

3.3 基于jsp开发,shiro的标签直接使用就可以了。基于enjoy开发,需要现实一个shiro工具类用于enjoy页面的权限判断。

//TODO::

评论区

JFinal

2019-03-13 18:26

通过配置 undertow.resourcePath 确实可以解决很多问题,感谢你的分享

这里也有一个类似的分享,可以增加更多的认知:
http://www.jfinal.com/share/1285

guocw998

2019-03-19 19:17

@JFinal undertow才接触,不是很熟悉。基础配置容易进坑!发了点时间,集成原生集成shiro。

JFinal

2019-03-19 20:22

@guocw998 有不少人在 jfinal undertow 集成 shiro 时出现类型 cast 异常,你的方案居然可以