我的问题是我无法在我的bean中获取servletcontext。 我创建了自定义bean“FileRepository”,我需要在那里获取ServletContext。 这是代码
package com.pc.webstore.utils;
import java.io.File;
import java.nio.file.Files;
import javax.servlet.ServletContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.ServletContextAware;
public class FileRepository implements ServletContextAware {
private ServletContext servletContext;
public String saveFile(File file){
File tempdir = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
...
}
@Override
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
}
在ApplicationContext.xml中注册
<bean id="fileStorage" class="com.pc.webstore.utils.FileRepository"/>
当saveFile(文件文件)启动时,我重新发现Nullpointerexception,因为servletContext == null。
那么为什么不注入servletcontext? 我在web.xml中注册了ContextLoaderListener
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
我发现有一些范围。可能是问题在那里。请简要介绍一下applicationontext范围或给出链接请求。 感谢帮助。我花了很多时间来解决这个问题。
经过一些调试后,我了解到servletcontextaware的setServletContexr方法实际上是在应用程序启动时调用的,但是当我尝试使用FileRepository从我的控制器存储文件时,它已经是具有null servletContext字段的anather对象。
在我想要的时候,有没有办法在自定义bean中自动跟踪servlet上下文,比如在控制器中?
最后我通过ServletContextAware获取servletContext。我改变了创建fileRepository bean的方式。从这个
public String create(@Valid Item item, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest, FileRepository fileRepository) {
到这个
@Autowired
private FileRepository fileRepository;
@RequestMapping(method = RequestMethod.POST, produces = "text/html")
public String create(@Valid Item item, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest) {
答案 0 :(得分:4)
ContextLoaderListener加载一个ApplicationContext,它成为应用程序的全局父上下文。那里没有ServletContext。 ServletContext仅存在于(请原谅术语的重载)SERVLET的CONTEXT中,例如DispatcherServlet。每个DispatcherServlet(通常只有一个)都会注册一个子上下文,该上下文指向ContextLoaderListener注册的全局父上下文。 ApplicationContexts就像类加载器一样。当IOC容器“查找”bean时,每个ApplicationContext都可以向上查看其父级以尝试查找它,但它不能向下看。孩子们也可以从父上下文中覆盖bean定义。
现在......看起来你的问题是你的bean是在没有找到ServletContext的全局父上下文中定义的。 (它不能让孩子看起来“向下”找到它。)
您需要做的是将fileStorage bean定义“down”移动到DispatcherServlet的ApplicationContext中。
在web.xml中定义DispatcherServlet时,通常会指定在何处可以找到定义其子上下文的文件。像这样:
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/web-context/*.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
将该bean定义向下移动到contextConfigLocation指定的位置,一切都应该按预期工作。