使用 @Service 构造型创建 XsrfProtectedServiceServlet 会抛出 NullPointerException
Creating an XsrfProtectedServiceServlet with a @Service stereotype throws a NullPointerException
我正在尝试按照指南中的指南将 CSRF 保护添加到我们的 GWT RPC 层
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()
的 return 值为空:
@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 服务实现,我是否需要做额外的配置?
查看 class 抛出空指针的代码,这似乎是有问题的方法:
@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 不是 "wired in",但是,在您的情况下有一个简单的解决方案。由于 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");
}
我正在尝试按照指南中的指南将 CSRF 保护添加到我们的 GWT RPC 层 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()
的 return 值为空:
@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 服务实现,我是否需要做额外的配置?
查看 class 抛出空指针的代码,这似乎是有问题的方法:
@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 不是 "wired in",但是,在您的情况下有一个简单的解决方案。由于 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");
}