我正在尝试根据指南中的指南为我们的GWT RPC层添加CSRF保护 GWT文档。
我在创建扩展XsrfProtectedServiceServlet
的RPC服务实现bean时遇到问题,因为它似乎是上下文
配置仅在创建bean之后创建。尝试运行时,我得到以下NullPointerException
申请:
ERROR [ContextLoader] : Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myServiceImpl' defined in file
[/path/to/project/exploded/WEB-INF/classes/za/co/example/server/MyServiceImpl.class]:
Invocation of init method failed; nested exception is java.lang.NullPointerException
.
.
.
Caused by: java.lang.NullPointerException
at com.google.gwt.user.server.rpc.XsrfProtectedServiceServlet.init(XsrfProtectedServiceServlet.java:84)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(AbstractAutowireCapableBeanFactory.java:1713)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1650)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1579)
以下是RPC服务的服务器端实现:
import com.google.gwt.user.server.rpc.XsrfProtectedServiceServlet;
@Service
public class MyServiceImpl extends XsrfProtectedServiceServlet implements MyService {
// interface overriding methods
}
这是客户端界面:
import com.google.gwt.user.client.rpc.XsrfProtectedService;
public interface MyService extends XsrfProtectedService {
// interface methods
}
注意:我省略MyServiceAsync
,因为在RPC调用中不必进行代码更改以实现反CSRF令牌。
当XsrfProtectedServiceServlet
尝试通过getServletConfig()
访问servlet配置时,抛出空指针,如下所示,即getServletConfig()
的返回值为null:
@Override
public void init() throws ServletException {
super.init();
// do not overwrite if value is supplied in constructor
if (sessionCookieName == null) {
// servlet configuration precedes context configuration
sessionCookieName = getServletConfig().getInitParameter(
XsrfTokenServiceServlet.COOKIE_NAME_PARAM);
if (sessionCookieName == null) {
sessionCookieName = getServletContext().getInitParameter(
XsrfTokenServiceServlet.COOKIE_NAME_PARAM);
}
if (sessionCookieName == null) {
throw new IllegalStateException(
XsrfTokenServiceServlet.COOKIE_NAME_NOT_SET_ERROR_MSG);
}
}
}
为了让Spring使用@Service
构造型正确地注入我的RPC服务实现,我是否需要执行其他配置?
答案 0 :(得分:0)
查看抛出nullpointer的类的代码,这似乎是有问题的方法:
@Override
public void init() throws ServletException {
super.init();
// do not overwrite if value is supplied in constructor
if (sessionCookieName == null) {
// servlet configuration precedes context configuration
sessionCookieName = getServletConfig().getInitParameter(
XsrfTokenServiceServlet.COOKIE_NAME_PARAM);
if (sessionCookieName == null) {
sessionCookieName = getServletContext().getInitParameter(
XsrfTokenServiceServlet.COOKIE_NAME_PARAM);
}
if (sessionCookieName == null) {
throw new IllegalStateException(
XsrfTokenServiceServlet.COOKIE_NAME_NOT_SET_ERROR_MSG);
}
}
}
抛出异常的行是:
sessionCookieName = getServletConfig().getInitParameter(
XsrfTokenServiceServlet.COOKIE_NAME_PARAM);
因此getServletConfig()
方法必须在加载应用程序上下文时返回null。在servlet配置存在之前,您可以确保bean没有“连接”,但是,在您的情况下,有一个简单的解决方案。由于servlet配置和上下文只需要访问cookie名称(如果它为null),您可以通过在构造函数中指定cookie名称来绕过它,即:
public XsrfProtectedServiceServlet(String sessionCookieName) {
this.sessionCookieName = sessionCookieName;
}
所以在你的MyServiceImpl案例中你要添加:
public MyServiceImpl() {
super("NAME_OF_THE_COOKIE_YOU_ARE_SPECIFYING_IN_WEB_XML_PROBABLY_JSESSIONID");
}