杰瑞科技汇

java获取application

  • 获取应用的初始化参数 (web.xml 中配置的)
  • 获取资源文件 (如 properties, xml)
  • 在应用范围内存取属性 (setAttribute, getAttribute)
  • 获取 MIME 类型
  • 获取服务器信息等

获取 ServletContext 的方法有很多种,具体取决于你所在的代码环境(在 Servlet 中、在 Filter 中、在 Spring 管理的 Bean 中等)。

java获取application-图1
(图片来源网络,侵删)

下面我将为你详细介绍几种最常见和重要的方法。


在原生 Servlet / Filter 中获取 (最直接)

这是最基础也是最直接的方法,在 Servlet API 中,ServletConfigServletRequest 对象都提供了获取 ServletContext 的方法。

通过 ServletConfig 获取

每个 Servlet 在初始化时都会收到一个 ServletConfig 对象,它包含了该 Servlet 的配置信息,并且可以通过 getServletContext() 方法获取 ServletContext

示例代码:

java获取application-图2
(图片来源网络,侵删)
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
public class MyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        // 1. 通过 this.getServletContext() 获取 (推荐)
        //    this 指代当前的 Servlet 实例,Servlet 实现了 ServletConfig 接口
        ServletContext application = this.getServletContext();
        // 2. 或者通过 request.getServletContext() 获取 (Servlet 3.0+)
        // ServletContext application = request.getServletContext();
        // 使用 application
        String appInitParam = application.getInitParameter("appParam"); // 获取应用初始化参数
        application.setAttribute("myAttribute", "Hello from Servlet!"); // 设置应用属性
        response.getWriter().println("ServletContext obtained via ServletConfig!");
    }
}

通过 HttpServletRequest 获取

从 Servlet 3.0 开始,HttpServletRequest 对象直接提供了 getServletContext() 方法,这使得在任何可以拿到 request 对象的地方都能方便地获取 ServletContext

示例代码 (在 Filter 中):

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter("/*")
public class MyFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
            throws IOException, ServletException {
        // 将 ServletRequest 转换为 HttpServletRequest (通常需要)
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        // 通过 request 对象获取 ServletContext
        ServletContext application = httpRequest.getServletContext();
        // 使用 application...
        System.out.println("Filter got ServletContext: " + application.getContextPath());
        // 继续执行过滤器链
        chain.doFilter(request, response);
    }
    // ... 其他 Filter 方法
}

在 Spring/Spring Boot 中获取 (最常用)

在现代 Spring 应用中,获取 ServletContext 的方式更加灵活和多样化。

通过依赖注入 (Dependency Injection) - 推荐

Spring 容器会管理 ServletContext 的生命周期,你可以直接将它作为一个 Bean 注入到任何 Spring 管理的组件(如 @Controller, @Service, @Component)中。

java获取application-图3
(图片来源网络,侵删)

示例代码 (Spring MVC):

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.ServletContext;
@Controller
public class MyController {
    // 通过构造器注入 (推荐方式)
    private final ServletContext servletContext;
    // Spring 会自动注入 ServletContext 实例
    public MyController(ServletContext servletContext) {
        this.servletContext = servletContext;
    }
    @GetMapping("/get-context")
    @ResponseBody
    public String getServletContext() {
        // 使用注入的 servletContext
        String realPath = servletContext.getRealPath("/WEB-INF/");
        return "ServletContext obtained via DI! RealPath: " + realPath;
    }
    // 或者通过 Setter 注入
    /*
    @Autowired
    public void setServletContext(ServletContext servletContext) {
        this.servletContext = servletContext;
    }
    */
}

通过 WebApplicationContextUtils 获取

如果你在一个非 Spring 托管的类(一个工具类、一个监听器或一个第三方库的回调中)需要获取 ServletContext,可以通过 WebApplicationContextUtils 来获取 Spring 的 WebApplicationContext,然后从中获取 ServletContext

示例代码 (工具类中):

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import javax.servlet.ServletContext;
public class MyUtil {
    public static void doSomething(ServletContext servletContext) {
        // 从 ServletContext 获取 Spring 的根应用上下文
        WebApplicationContext webAppContext = 
            WebApplicationContextUtils.getWebApplicationContext(servletContext);
        if (webAppContext != null) {
            // 现在你可以获取 Spring 容器中的任何 Bean
            MyService myService = webAppContext.getBean(MyService.class);
            myService.performTask();
        }
    }
}

通过 ServletContextAware 接口 - 不推荐,但可行

让你的组件实现 ServletContextAware 接口,Spring 会在初始化时自动调用 setServletContext 方法,这种方式侵入性较强,耦合度较高,通常不推荐使用,除非有特殊需求。

import org.springframework.stereotype.Component;
import org.springframework.web.context.ServletContextAware;
import javax.servlet.ServletContext;
@Component
public class MyComponent implements ServletContextAware {
    private ServletContext servletContext;
    @Override
    public void setServletContext(ServletContext servletContext) {
        this.servletContext = servletContext;
    }
    public void useContext() {
        // ...
    }
}

通过监听器 (Listener) 获取

ServletContextListener 是一个 Servlet API 中的监听器,它会在 Web 应用启动和销毁时被通知,这是获取 ServletContext 的一个绝佳位置,尤其适合用于执行应用启动时的初始化任务。

示例代码:

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class MyContextListener implements ServletContextListener {
    // 在应用启动时调用
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        // 通过 sce.getServletContext() 获取
        ServletContext application = sce.getServletContext();
        System.out.println("Application started! Context path: " + application.getContextPath());
        // 加载初始化数据
        String initDataPath = application.getInitParameter("initDataPath");
        System.out.println("Loading data from: " + initDataPath);
    }
    // 在应用关闭时调用
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        ServletContext application = sce.getServletContext();
        System.out.println("Application shutting down...");
        // 清理资源
    }
}

总结与最佳实践

场景 推荐方法 说明
原生 Servlet this.getServletContext()request.getServletContext() 最直接,Servlet API 内置支持。
原生 Filter request.getServletContext() 简单直接,Servlet 3.0+ 后可用。
Spring 管理的 Bean 依赖注入 (@Autowired 或构造器) 最佳实践,代码解耦,易于测试。
Spring 非托管类 WebApplicationContextUtils.getWebApplicationContext(servletContext) 在无法使用 DI 时,通过 ServletContext 桥接到 Spring 容器。
应用初始化 ServletContextListener 专门用于监听应用生命周期,是执行启动任务的理想位置。

核心要点:

  1. ServletContext application:在 Java Web 开发中,我们常说的 application 作用域,其底层实现就是 ServletContext
  2. 选择合适的方法:根据你代码的运行环境(原生 vs Spring,托管 vs 非托管)选择最合适的获取方式。
  3. 优先使用依赖注入:在 Spring 生态中,始终优先考虑使用依赖注入来获取 ServletContext,这会使你的代码更干净、更易于维护和测试。
分享:
扫描分享到社交APP
上一篇
下一篇