如何从 Spring WebApplicationContext 中获取 DispatcherServlet?
Posted
技术标签:
【中文标题】如何从 Spring WebApplicationContext 中获取 DispatcherServlet?【英文标题】:How to get the DispatcherServlet from spring WebApplicationContext? 【发布时间】:2021-09-23 08:23:35 【问题描述】:如何从弹簧WebApplicationContext
对象中获取DispatcherServlet
实例?
我想对前端控制器 servlet 执行直接请求(避免使用网络接口)并检查来自 spring 应用程序的响应,例如WebApplicationContext
实例。
注意,我们无法使用 MockMvc 来检查 JSP 渲染的 html,因为:“如果您使用 JSP,您可以验证请求被转发到的 JSP 页面,但没有渲染任何 HTML em>"(根据MockMvc vs End-to-End Tests)
所以也许如果我们得到DispatcherServlet
实例,我们可以通过它的doDispatch
方法执行请求并检查响应中的内容。
【问题讨论】:
您可以通过@Autowired DispatcherServlet dispatcherServlet;
获取实例,但我不确定这是否有助于您解决问题。您能详细说明一下您想要实现的目标吗?
【参考方案1】:
当你看 DispatcherServlet.java,有一个以 WebApplicationContext 作为参数的构造函数,但是来自 FrameworkServlet.java 的超级构造函数只保存字段本身,没有任何回调 - 所以给定的 Web 应用程序上下文将不知道调度程序 servlet。
所以我认为您不能通过 WebApplicationContext 解析调度程序 servlet。当然,您可以尝试注入/自动装配 DispatcherServlet - 也许这在测试中也是可能的,但我不确定。
我认为检查 JSP 输出的最简单方法是使用真实服务器测试这些部分,如 Testing with a running server 所述。这应该会在您的测试中为您提供完整的输出和 Web 应用程序行为,而无需任何解决方法。
【讨论】:
【参考方案2】:Dispatcher Servlet:它充当基于 Spring 的 Web 应用程序的前端控制器。它提供了一种请求处理机制,其中实际工作由可配置的委托组件执行。它继承自HttpServlet
、HttpServletBean
和FrameworkServlet
。它还实现了ApplicationContextAware
,因此它能够设置ApplicationContext。
WebApplicationContext :它是普通 ApplicationContext 的扩展。它是 Web 感知的 ApplicationContext,即它具有 Servlet 上下文信息。当DispatcherServlet
被加载时,它会查找WebApplicationContext
的bean配置文件并对其进行初始化。
因此,您可以从 DispatcherServlet 设置和获取任何 ApplicationContext 的实例,但反之则不行。
dispatcherServlet.getWebApplicationContext();
虽然,您可以获得DispatcherServlet
的实例,但我怀疑它是否能满足您的目的,因为它的范围是protected
。
@Autowired
DispatcherServlet dispatcherServlet;
DispatcherServlet
内的代码
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception
可以创建自己的 DispatcherServlet 并执行操作。您可以覆盖 Spring Boot 应用程序创建的默认值。 示例:
public class SampleDispatcherServlet extends DispatcherServlet
private final Log logger = LogFactory.getLog(getClass());
@Override
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception
// You can use other implementations of HttpServletRequest and
// HttpServletResponse as per your requirement
// e.g. FormContentRequestWrapper , ResourceUrlEncodingResponseWrapper many more
if (!(request instanceof ContentCachingRequestWrapper))
request = new ContentCachingRequestWrapper(request);
if (!(response instanceof ContentCachingResponseWrapper))
response = new ContentCachingResponseWrapper(response);
HandlerExecutionChain handler = getHandler(request);
try
// Any task to be done
super.doDispatch(request, response);
finally
// Some task to be done
HandlerExecutionChain
- 处理程序映射器用于将当前请求匹配到适当的控制器。拦截器是在一些调度动作之前和之后调用的对象
然后我们要注册DispatcherServlet
:
@Bean
public ServletRegistrationBean dispatcherRegistration()
return new ServletRegistrationBean(dispatcherServlet());
//The bean name for a DispatcherServlet that will be mapped to the root URL "/"
@Bean(name = DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
public DispatcherServlet dispatcherServlet()
return new SampleDispatcherServlet();
【讨论】:
以上是关于如何从 Spring WebApplicationContext 中获取 DispatcherServlet?的主要内容,如果未能解决你的问题,请参考以下文章
如何修复 react 和 spring web 应用程序中的 cors 错误?