Java 让GAE Shiro和Resteasy一起工作
我正试图让盖西罗和雷斯脱轻松相处。所以我试着做了一个快速端口。然而,我得到了这个错误:Java 让GAE Shiro和Resteasy一起工作,java,google-app-engine,jax-rs,resteasy,shiro,Java,Google App Engine,Jax Rs,Resteasy,Shiro,我正试图让盖西罗和雷斯脱轻松相处。所以我试着做了一个快速端口。然而,我得到了这个错误: [ERROR] java.lang.RuntimeException: java.lang.InstantiationException: com.cilogi.shiro.guice.ServeModule [ERROR] at org.jboss.resteasy.plugins.guice.GuiceResteasyBootstrapServletContextListener.getModul
[ERROR] java.lang.RuntimeException: java.lang.InstantiationException: com.cilogi.shiro.guice.ServeModule
[ERROR] at org.jboss.resteasy.plugins.guice.GuiceResteasyBootstrapServletContextListener.getModules(GuiceResteasyBootstrapServletContextListener.java:83)
[ERROR] at org.jboss.resteasy.plugins.guice.GuiceResteasyBootstrapServletContextListener.contextInitialized(GuiceResteasyBootstrapServletContextListener.java:27)
[ERROR] at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:548)
[ERROR] at org.mortbay.jetty.servlet.Context.startContext(Context.java:136)
[ERROR] at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
[ERROR] at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
[ERROR] at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
[ERROR] at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
[ERROR] at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
[ERROR] at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
[ERROR] at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
[ERROR] at org.mortbay.jetty.Server.doStart(Server.java:224)
[ERROR] at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
[ERROR] at com.google.appengine.tools.development.JettyContainerService.startContainer(JettyContainerService.java:228)
[ERROR] at com.google.appengine.tools.development.AbstractContainerService.startup(AbstractContainerService.java:255)
[ERROR] at com.google.appengine.tools.development.AbstractServer.startup(AbstractServer.java:79)
[ERROR] at com.google.appengine.tools.development.DevAppServerImpl$Servers.startup(DevAppServerImpl.java:451)
[ERROR] at com.google.appengine.tools.development.DevAppServerImpl.start(DevAppServerImpl.java:198)
[ERROR] at com.google.appengine.tools.development.gwt.AppEngineLauncher.start(AppEngineLauncher.java:97)
[ERROR] at com.google.gwt.dev.DevMode.doStartUpServer(DevMode.java:509)
[ERROR] at com.google.gwt.dev.DevModeBase.startUp(DevModeBase.java:1068)
[ERROR] at com.google.gwt.dev.DevModeBase.run(DevModeBase.java:811)
[ERROR] at com.google.gwt.dev.DevMode.main(DevMode.java:311)
[ERROR] Caused by: java.lang.InstantiationException: com.cilogi.shiro.guice.ServeModule
[ERROR] at java.lang.Class.newInstance0(Class.java:359)
[ERROR] at java.lang.Class.newInstance(Class.java:327)
[ERROR] at org.jboss.resteasy.plugins.guice.GuiceResteasyBootstrapServletContextListener.getModules(GuiceResteasyBootstrapServletContextListener.java:70)
[ERROR] ... 22 more
这是我当前的web.xml配置
<context-param>
<param-name>resteasy.guice.modules</param-name>
<!-- <param-value>org.jboss.errai.ui.demo.server.MyServletModule</param-value> -->
<param-value>com.cilogi.shiro.guice.ServeModule</param-value>
</context-param>
<listener>
<listener-class>
org.jboss.resteasy.plugins.guice.GuiceResteasyBootstrapServletContextListener
</listener-class>
</listener>
<context-param>
<param-name>resteasy.servlet.mapping.prefix</param-name>
<param-value>/</param-value>
</context-param>
<servlet>
<servlet-name>Resteasy</servlet-name>
<servlet-class>
org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Resteasy</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<context-param>
<param-name>user-base-url</param-name>
<param-value>/user/admin</param-value>
</context-param>
<context-param>
<param-name>static-base-url</param-name>
<param-value></param-value>
</context-param>
<listener>
<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>
<listener>
<listener-class>com.cilogi.shiro.guice.ServeContextListener</listener-class>
</listener>
<mime-mapping>
<extension>manifest</extension>
<mime-type>text/cache-manifest</mime-type>
</mime-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
resteasy.guice.modules
com.cilogi.shiro.guice.ServeModule
org.jboss.resteasy.plugins.guice.GuiceResteasyBootstrapServletContextListener
resteasy.servlet.mapping.prefix
/
放松
org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
放松
/*
用户基url
/用户/管理员
静态基本url
org.apache.shiro.web.env.EnvironmentLoaderListener
com.cilogi.shiro.guice.ServeContextListener
显示
文本/缓存清单
index.html
我意识到这个问题已经存在了将近一年,但我最近在Shiro(注意:不是GAE Shiro)和RESTEasy遇到了一个类似的问题,我想我会在这里发布我使用的解决方案,这样可能会使遇到这个特殊问题的任何人受益
问题在于RESTEasy的guicereSteasySbootstrapservletContextListener
试图创建一个需要向其传递参数的模块(在我的例子中,它是一个ShiroWebModule
需要一个ServletContext
参数……在您的例子中,它看起来像com.cilogi.shiro.guice.ServeModule
需要传递一个字符串)。但是,当RESTEasy尝试创建模块时,它会通过调用no args构造函数来创建模块,然后由于没有构造函数而失败
我决定采用的解决方案是扩展GuiceResteasyBootstrapServletContextListener
并重写getModules(ServletContext ctx)
方法,以便如果存在采用ServletContext
的构造函数,则使用它,否则,使用默认的no-args构造函数
例如:
public class MyBootstrapServletContextListener extends GuiceResteasyBootstrapServletContextListener {
@Override
protected List getModules(final ServletContext context) {
final List result = new ArrayList();
final String modulesString = context.getInitParameter("resteasy.guice.modules");
if (modulesString != null) {
final String[] moduleStrings = modulesString.trim().split(",");
for (final String moduleString : moduleStrings) {
try {
log.info("Found module: {}", moduleString);
final Class cls = Thread.currentThread().getContextClassLoader().loadClass(moduleString.trim());
final Module module = createModule(cls, context);
result.add(module);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}
return result;
}
private Module createModule(Class cls, ServletContext context) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Constructor constructor = null;
try {
constructor = cls.getConstructor(ServletContext.class);
} catch (NoSuchMethodException e) {
log.info("Class {} has no constructor that takes just a ServletContext parameter; defaulting to no-args constructor.", cls);
}
return constructor == null ? (Module) cls.newInstance() : (Module) constructor.newInstance(context);
}
}
公共类MyBootstrapServletContextListener扩展了GuiceResteasyBootstrapServletContextListener{
@凌驾
受保护列表getModules(最终ServletContext上下文){
最终列表结果=新建ArrayList();
最后一个字符串moduleString=context.getInitParameter(“resteasy.guice.modules”);
if(moduleString!=null){
最后一个字符串[]moduleStrings=ModuleString.trim().split(“,”);
for(最终字符串moduleString:moduleString){
试一试{
info(“找到的模块:{}”,moduleString);
最终类cls=Thread.currentThread().getContextClassLoader().loadClass(moduleString.trim());
最终模块=createModule(cls,上下文);
结果.添加(模块);
}catch(classnotfounde异常){
抛出新的运行时异常(e);
}捕获(非法访问例外e){
抛出新的运行时异常(e);
}捕获(实例化异常e){
抛出新的运行时异常(e);
}捕获(IllegalArgumentException e){
抛出新的运行时异常(e);
}捕获(调用TargetException e){
抛出新的运行时异常(e);
}
}
}
返回结果;
}
私有模块createModule(类cls,ServletContext上下文)抛出实例化异常、IllegalAccessException、IllegalArgumentException、InvocationTargetException{
构造函数=null;
试一试{
constructor=cls.getConstructor(ServletContext.class);
}捕获(无此方法例外){
info(“类{}没有只接受ServletContext参数的构造函数;默认为无参数构造函数。”,cls);
}
返回构造函数==null?(模块)cls.newInstance():(模块)constructor.newInstance(上下文);
}
}
一旦这一切就绪,我将web.xml
更改为使用MyBootstrapServletContextListener
而不是RESTEasy的guicereSteasySbootstrapservletcontextlistener
,RESTEasy就不再有问题了。您应该能够执行类似的操作,允许RESTEasy将所需字符串传递到com.cilogi.shiro.guice.ServeModule
我再次意识到,您可能不再需要解决方案,但我在研究Shiro的类似问题时偶然发现了这个问题,希望能帮助其他试图在web应用程序中结合RESTEasy和Shiro的人。我制作了一个示例项目,使用RESTEasy作为过滤器(具有异步支持)。它不使用GAE,但使用Guice、Shiro和RestEasy。请查看: