1

我有一个由具有以下类的服务创建的 bean:

@Configuration
public class AccessManager {

    @Bean(name="access", destroyMethod="destroy")
    @Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
    @Autowired
    public Access create(HttpServletRequest request) {
        System.out.println(request.getRemoteAddr());
        return new Access();
    }

}

一切都按预期工作,除了在应用程序启动时调用此方法,可能是因为我有一些其他使用该 bean 的单例Accessbean。在启动时没有请求绑定到线程,并且java.lang.IllegalStateException在尝试访问request参数的任何属性时预计会得到一个。

没问题。问题是,是否可以在调用引发异常的属性之前检查HttpServletRequest代理request的底层是否存在?null

4

2 回答 2

2

您可能想看看RequestContextHolder#getRequestAttributes()null如果您当前不在可以使用请求范围的上下文中,那将返回。

@Configuration
public class AccessManager {

    @Bean(name="access", destroyMethod="destroy")
    @Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
    @Autowired
    public Access create(HttpServletRequest request) {
        if (RequestContextHolder.getRequestAttributes() != null) {
            System.out.println(request.getRemoteAddr());
        }
        return new Access();
    }

}
于 2012-08-18T02:25:12.090 回答
1

我认为这里的问题是关注点分离。通常你的服务层不应该对 servlet 类有任何依赖。这在很大程度上是一个控制器/UI 问题。

应该为您的服务类提供完成其工作所需的属性。在这种情况下是一个字符串。此服务方法应从注入 servlet 请求的控制器方法中调用。

类似于以下内容:

@Controller
public class MyController {

  @Autowired
  private AccessManager accessManager;


  @RequestMapping
  public void handleRequest(HttpServletRequest request) {
    accessManager.create(request.getRemoteAddr());
  }
}

然后您的服务将如下所示:

@Service
public class AccessManager {

  public Access create(String remoteAddress) {
    return new Access();
  }
}

总而言之,任何注释为 @Service 的东西都不应访问请求。

于 2012-08-17T19:27:16.343 回答