为什么';在Spring work中,您不只是自动连接GWT servlet中的字段吗?
在GWT servlet中将字段简单地标记为为什么';在Spring work中,您不只是自动连接GWT servlet中的字段吗?,spring,gwt,aspectj,autowired,configurable,Spring,Gwt,Aspectj,Autowired,Configurable,在GWT servlet中将字段简单地标记为@Autowired,并不能按预期工作。代码将被编译,web应用程序将启动—这意味着Spring能够成功地自动连接字段,但当servlet实际被客户端代码命中时,它将生成一个NullPointerException—就像被命中的servlet的另一个未初始化副本一样 我在web上找到了几种方法来实现这一点,一种是使用一个执行Spring逻辑的基本servlet类,但这样做意味着每个GWT servlet都必须扩展这个基本类。另一种方法是使用Aspect
@Autowired
,并不能按预期工作。代码将被编译,web应用程序将启动—这意味着Spring能够成功地自动连接字段,但当servlet实际被客户端代码命中时,它将生成一个NullPointerException
—就像被命中的servlet的另一个未初始化副本一样
我在web上找到了几种方法来实现这一点,一种是使用一个执行Spring逻辑的基本servlet类,但这样做意味着每个GWT servlet都必须扩展这个基本类。另一种方法是使用AspectJ和@Configurable
Spring注释。这里只涉及很少的配置,它只是神奇地工作
我的问题是,为什么不只是自动布线的领域只是工作的预期?GWT所做的什么导致了此故障
代码将被编译,web应用程序将启动-这是什么
意味着Spring能够成功地自动连接字段
不一定。web容器可以在没有Spring帮助的情况下实例化servlet。您可能会体验到:
但是当servlet实际被客户端代码击中时,它将
产生一个NullPointerException-就像有一个不同的、未初始化的
正在命中的servlet的副本
尝试重写Servlet的init():
当从客户机调用RPC服务时,查看被调用URL和servlet映射的“服务器端”将找到类,创建实例并为请求提供服务。这意味着,如果您有
@Autowired
注释,或者您在spring上下文中已经有了RPC类的实例,这并不重要。新实例将被创建,它不会“知道”Spring
我通过实现一个类来解决这个问题,该类扩展了RemoteServiceServlet
,并实现了Controller
(来自SpringMVC)和ServletContextAware
。
通过这种方式,您可以使用Spring MVC方法通过URL映射每个RPC服务,例如:
<bean id="publicUrlMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/myFirstRpc">firstRpcServiceBeanRef</prop>
<prop key="/mySecondRpc">secondRpcServiceRef</prop>
</props>
</property>
</bean>
firstRpcServiceBeanRef
第二个RPCServiceRef
您还可以避免对web.xml
中的每个rpcservlet进行声明,映射是干净的,并且具有Spring注入。
在org.springframework.web.servlet.DispatcherServlet
中,您只为org.springframework.web.servlet.DispatcherServlet
声明一个映射,该映射将服务于所有RPC调用
web上有两个示例,解释了GWT RPC和Spring MVC控制器的集成
希望这会有所帮助。事实证明,至少在使用Spring时,有一种更简单的方法可以做到这一点,即您可以使用@Autowired,并且它不涉及大量配置或基类。需要注意的是,您还必须使用AspectJ。以下是GWT servlet所需的内容:
@Configurable
public class MyGwtServiceImpl extends RemoteServiceServlet implements MyGwtService
{
@Autowired
private MyService service;
// ...
}
在Spring配置中,确保您还具有:
<!-- enable autowiring and configuration of non-spring managed classes, requires AspectJ -->
<context:spring-configured/>
最后一个音符。如果您也在GWT应用程序(以及GWT servlet)中使用Spring security,则需要确保定义正确的模式,以确保正确完成AspectJ编织(即,您同时获得@Secured注释处理和@Autowired处理),您将需要:
<!-- turn on spring security for method annotations with @Secured(...) -->
<!-- the aspectj mode is required because we autowire spring services into GWT servlets and this
is also done via aspectj. a server 500 error will occur if this is changed or removed. -->
<security:global-method-security secured-annotations="enabled" mode="aspectj"/>
Ack!我很抱歉。我没有明确说明我们使用的不是SpringMVC,而是SpringWeb。考虑到我在网络上找到的信息,即一个控制器来控制所有的模式对我来说真的是错误的,因为我们会吸入整个框架组件,只使用一小部分。对我来说,Spring MVC的真正力量是能够创建任意数量的控制器,将类似功能的控制器组合在一起,将控制器方法与URI绑定在一起,并在逐个方法的基础上添加安全性—这一切都是自动发生的,只需很少的编码即可完成。我认为您将dispacher servlet与一个控制器混合在一起来管理它们。这个servlet映射给出了控制器使用的URL的一般定义,如/rpc/*。这就是想法。如果您已经包括了类似于Spring安全性的框架,那么您仍然有可能在方法级别上实现安全性。虽然您在回答的第一部分中在技术上是正确的,但是Spring默认情况下会根据需要处理自动连接的带注释的字段/方法,因此会验证它是否构建了一个可以匹配带注释项的bean。此外,在您回答的第二部分中,我在web上看到了这个解决方案,但需要注意的是:1)我需要创建一个父servlet类来扩展所有GWT servlet类,这是我一直希望避免的,2)此模式会干扰异常处理,并阻止在抛出异常时正确处理异常。请参见作者的评论:,以及他的解决方案——使用AspectJ。您不需要创建基类,每个servlet都可以为自己重写init():)True。然后,到处都会有冗余代码,它们只是尖叫着“基类…”-我想这就是你的观点。
<!-- turn on spring security for method annotations with @Secured(...) -->
<!-- the aspectj mode is required because we autowire spring services into GWT servlets and this
is also done via aspectj. a server 500 error will occur if this is changed or removed. -->
<security:global-method-security secured-annotations="enabled" mode="aspectj"/>