Spring Boot中的DispatcherServlet和web.xml

39

我目前正在尝试将我的项目从Java EE迁移到Spring Boot项目。但是,在使用dispatcher servlet和web.xml时遇到了困难和混淆,而且似乎该项目不再读取web.xml文件了。当前项目在Tomcat 7上运行。

在我的web.xml文件中,有很多servletservlet-mappingfilterfilter mapping,我真的不太明白如何在dispatcher中进行映射。

下面是我的web.xml样例,版本为2.5。

<?xml version="1.0" encoding="UTF-8"?>
<web-app metadata-complete="true" version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <display-name>displayName</display-name>
  <description>description</description>
  <resource-ref>
    ...
  </resource-ref>
  <filter>
    <filter-name>Some Filter Name</filter-name>
    <filter-class>Some Filter Class</filter-class>
    <init-param>
      <param-name>Some Param Name</param-name>
      <param-value>Some Value</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>Some Filter Name</filter-name>
    <url-pattern>Some url-pattern</url-pattern>
  </filter-mapping>
  <context-param>
    <param-name>Some Param Name</param-name>
    <param-value>Some Param Value</param-value>
  </context-param>
  <servlet>
    <servlet-name>Some Servlet Name</servlet-name>
    <servlet-class>Some Servlet Class</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>Some Servlet Name</servlet-name>
    <url-pattern>Some Url Pattern</url-pattern>
  </servlet-mapping>
</web-app>

问题:

  1. 如果是的话,我应该将我的web.xml中的所有内容转换为依赖于Spring Dispatcher吗?如果是的话,我该如何实现?
  2. 对于Spring Boot项目来说,摆脱web.xml是一种可行的方式吗?

请问有人可以指导我吗?谢谢!

4个回答

33
  1. 是的,Spring Boot不再依赖XML配置,并自动配置了等效于Dispatcher Servlet的内容。您可以点击以下链接了解如何注册过滤器:如何在Spring Boot中添加过滤器类?
  2. 如果您使用Maven而不是Gradle,则您的Spring Boot项目中仅应有pom.xml中的XML。Spring Boot的最佳实践是将所有XML配置、web.xml等移至Spring Boot的自动配置加上您的Java配置。

当您在Java配置中执行所有操作并遵循Spring Boot原则时,Spring Boot会表现得非常出色。从我的经验来看,如果您开始合并XML配置和传统的Spring结构,则会破坏自动配置过程,因此尽可能遵守新的Spring Boot最佳实践会更好。


谢谢您澄清这一点!那么,我是否可以说我需要在我的@SpringBootApplication类中注册web.xml中每个标签的所有值? - NatureWonder
6
最好保持@SpringBootApplication类的清晰。例如,在@SpringBootApplication所在的包下创建一个名为“config”的新包,并创建一个带有@Configuration注释的类,例如FiltersConfiguration,然后开始将您的过滤器注册为@Bean注释的方法。这样您的代码会更加清晰易读。根据需要可以创建更多的@Configuration类。 - Tom

10
  1. 您可以保留您的web.xml文件,但需要添加

<listener>
     <listener-class>org.springframework.boot.legacy.context.web.SpringBootContextLoaderListener</listener-class>
</listener> 

web.xml文件中。以及pom.xml的必要依赖。

所有的监听器类和过滤器都转换为Java类。该类应该是@Configuration

如果您有一个拦截器,可以将其移动到配置类中。


7
Spring Boot更偏爱注解而不是基于XML的配置,因此在您的情况下,您可以使用基于注解的自动Bean创建来注册Bean,而不是使用web.xml配置servlet、servlet-mapping、filter和filter mapping。为此,您需要:
  • 将基于xml的映射转换为基于注解的映射
  • 使用@Bean注解创建Bean,这样Spring Boot在组件扫描期间会自动使用它们。

参考链接: https://docs.spring.io/spring-boot/docs/current/reference/html/howto-traditional-deployment.html

  • 要注册过滤器并添加过滤器Bean,您可以创建一个类并用@Configuration或@Component注解进行注释,并创建FilterRegistrationBean的Bean以注册过滤器。您还可以在那里使用@Bean注解创建过滤器本身的Bean。

例如,以下基于xml的过滤器的等效内容:

<filter>
  <filter-name>SomeUrlFilter</filter-name>
   <filter-class>com.company.SomeUrlFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>SomeUrlFilter</filter-name>
    <url-pattern>/url/*</url-pattern>
    <init-param>
       <param-name>paramName</param-name>
       <param-value>paramValue</param-value>
    </init-param>
</filter-mapping>

相应的基于注解的代码如下:

@Bean
public FilterRegistrationBean someUrlFilterRegistration() {

    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(someUrlFilter());
    registration.addUrlPatterns("/url/*");
    registration.addInitParameter("paramName", "paramValue");
    registration.setName("Filter");
    registration.setOrder(1);
    return registration;
} 

@Bean(name = "someUrlFilter")
public Filter someUrlFilter() {
    return new SomeUrlFilter();
}
  • Springboot仍然允许我们使用基于XML的配置,例如如果您想使用web.xml。例如:

Web.xml

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/dispatcher.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

在另一个文件dispatcher.xml中,您可以创建以下bean:

<beans ...>

    <context:component-scan base-package="com.demo"/>

    <bean
      class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

请注意,Spring的web.xml通常存放在src/main/webapp/WEB-INF中。
你可以参考以下链接: https://www.baeldung.com/register-servlet

1

我花了很多时间,现在分享三个记住的要点,以便从命令行使其工作。

  1. 最重要的是:JSP应该只保留在文件夹/src/main/resources/META-INF/resources中。 在这里查看更多信息
  2. 确保在构建jar时,maven考虑到了你的文件夹/src/main/resources,否则请在你的pom.xml中添加这些行

  <resources>
     <resource>
        <directory>src/main/resources</directory>   
      </resource>
    </resources>

  1. In your mvc config file

    @Configuration
    public class MvcConfig extends WebMvcConfigurerAdapter {
        @Bean
        public InternalResourceViewResolver viewResolver(){
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/Representation/");
        resolver.setSuffix(".jsp");
        return resolver;
    }
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接