【问题标题】:Creating an XsrfProtectedServiceServlet with a @Service stereotype throws a NullPointerException使用 @Service 构造型创建 XsrfProtectedServiceServlet 会引发 NullPointerException
【发布时间】:2017-08-28 20:52:07
【问题描述】:

我正在尝试按照指南中的指南将 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() 的返回值为空:

@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 服务实现,我需要做额外的配置吗?

【问题讨论】:

  • 也将@Service 添加到 MyService
  • 嘿@SundararajGovindasamy,谢谢你的建议。我试过了,但在启动时仍然遇到同样的错误。

标签: java spring gwt csrf


【解决方案1】:

查看抛出空指针的类的代码,这似乎是有问题的方法:

@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 配置和上下文只需要在它为 null 时访问 cookie 名称,因此您可以通过在构造函数中指定 cookie 名称来绕过它,即:

public XsrfProtectedServiceServlet(String sessionCookieName) {
    this.sessionCookieName = sessionCookieName;
}

因此,在 MyServiceImpl 中,您将添加:

public MyServiceImpl() {
   super("NAME_OF_THE_COOKIE_YOU_ARE_SPECIFYING_IN_WEB_XML_PROBABLY_JSESSIONID");
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-25
    • 1970-01-01
    • 1970-01-01
    • 2012-04-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多