为什么使用WebApplicationInitializer时Spring会抛出“ IllegalStateException:未设置ServletContext”

问题描述 投票:2回答:1

我只是学习Java,现在尝试使用MVC + thymeleaf为我的应用程序创建UI。当我尝试运行应用程序时,出现错误,如下所示的stacktrace:

 Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'resourceHandlerMapping' defined in org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerMapping]: Factory method 'resourceHandlerMapping' threw exception; nested exception is java.lang.IllegalStateException: No ServletContext set
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:656)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:636)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:882)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
    at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:89)
    at com.foxminded.university.Main.main(Main.java:26)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerMapping]: Factory method 'resourceHandlerMapping' threw exception; nested exception is java.lang.IllegalStateException: No ServletContext set
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:651)
    ... 14 more
Caused by: java.lang.IllegalStateException: No ServletContext set
    at org.springframework.util.Assert.state(Assert.java:73)
    at org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.resourceHandlerMapping(WebMvcConfigurationSupport.java:534)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
    ... 15 more

我的配置文件:

@Configuration
@ComponentScan("com.foxminded.university")
@PropertySource("classpath:config.properties")
@EnableWebMvc
public class ContextConfig implements WebMvcConfigurer {

    private final ApplicationContext applicationContext;

    @Value("${url}")
    public String url;
    @Value("${user}")
    public String user;
    @Value("${password}")
    public String password;
    @Value("${driverClass}")
    public Class<Driver> driverClass;

    @Autowired
    public ContextConfig(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

    @Bean
    public DataSource dataSource() {
        SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
        dataSource.setDriverClass(driverClass);
        dataSource.setUsername(user);
        dataSource.setUrl(url);
        dataSource.setPassword(password);
        return dataSource;
    }

    @Bean
    public SpringResourceTemplateResolver templateResolver() {
        SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
        templateResolver.setApplicationContext(applicationContext);
        templateResolver.setPrefix("/WEB-INF/views/");
        templateResolver.setSuffix(".html");
        templateResolver.setTemplateMode(TemplateMode.HTML);
        return templateResolver;
    }

    @Bean
    public SpringTemplateEngine templateEngine() {
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(templateResolver());
        templateEngine.setEnableSpringELCompiler(true);
        return templateEngine;
    }

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        ThymeleafViewResolver resolver = new ThymeleafViewResolver();
        resolver.setTemplateEngine(templateEngine());
        registry.viewResolver(resolver);
    }
}

dispatcherServlet:

public class SpringMvcDispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return null;
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {    
        return new Class[] {ContextConfig.class};
    }

    @Override
    protected String[] getServletMappings() {   
        return new String[] {"/"};
    }

}

和pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.foxminded.tasks</groupId>
    <artifactId>University1</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>University1</name>
    <properties>
        <maven.compiler.target>11</maven.compiler.target>
        <maven.compiler.source>11</maven.compiler.source>
        <junit.jupiter.version>5.6.0</junit.jupiter.version>
        <org.springframework.version>5.2.5.RELEASE</org.springframework.version>
        <org.springframework.boot.version>2.2.6.RELEASE</org.springframework.boot.version>
        <h2.version>1.4.200</h2.version>
        <org.postgres.version>42.2.11</org.postgres.version>
        <org.sonarsource.scanner.maven.version>3.2</org.sonarsource.scanner.maven.version>
        <mockito.version>3.3.3</mockito.version>
        <logback.version>1.3.0-alpha5</logback.version>
        <slf4j.version>2.0.0-alpha1</slf4j.version>
        <servlet.version>4.0.1</servlet.version>
        <thymeleaf.version>3.0.11.RELEASE</thymeleaf.version>

    </properties>

    <profiles>
        <profile>
            <id>sonar</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <sonar.host.url>
                    http://localhost:9000
                </sonar.host.url>
            </properties>
        </profile>
    </profiles>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
            <version>${org.springframework.boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${org.springframework.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.2.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
            <version>2.2.7.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring5</artifactId>
            <version>${thymeleaf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>${servlet.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>${h2.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.jupiter.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>${mockito.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-junit-jupiter</artifactId>
            <version>${mockito.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.sonarsource.scanner.maven</groupId>
            <artifactId>sonar-maven-plugin</artifactId>
            <version>${org.sonarsource.scanner.maven.version}</version>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>${org.postgres.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>${logback.version}</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>${logback.version}</version>
        </dependency>
    </dependencies>

</project>

请您解释一下,问题出在哪里,我该怎么办。我试图删除.m2存储库并重建项目,但是什么也没发生。

我从创建dao和服务层后没有改变的主要方法,它在控制台中制作了一些用于获取学生和教师时间表的小菜单:

public class Main {

    private final static Logger logger = LoggerFactory.getLogger(Main.class);

    public static void main(String[] args) {
        logger.info("Start Main");

        @SuppressWarnings("resource")
        final ApplicationContext context = new AnnotationConfigApplicationContext(ContextConfig.class);     
        DatabaseInitializer initializer = context.getBean("databaseInitializer", DatabaseInitializer.class);
        try {
            initializer.createTableInsertData();
        } catch (IOException e1) {
            logger.error("DB was not created");
            System.exit(0);
        }
        TimeTable timeTable = context.getBean("timeTable", TimeTable.class);
        TeacherService teacherService = context.getBean("teacherService", TeacherService.class);
        StudentService studentService = context.getBean("studentService", StudentService.class);    

        final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));     
        final String commandListMessage = "Please select which TimeTable you want take:\n"
                + "\"1\" - TimeTable for student for selected interval;\n"
                + "\"2\" - TimeTable for teacher for selected interval;\n"
                + "\"help\" - for get this list of commands again;\n" + "or \"exit\" to exit.";

        System.out.println(commandListMessage);

        String command = "";

        try {
            command = reader.readLine();        
            logger.debug("command is {}", command);         
            logger.debug("start menu loop");
            while (!(command.equalsIgnoreCase("exit"))) {
                logger.info("switch command");              
                switch (command) {
                case "1":
                    logger.debug("case 1");         
                    System.out.println("Enter student id:");
                    int studentId = Integer.parseInt(reader.readLine());
                    Student student = studentService.findOne(studentId);

                    if (student != null) {
                        System.out.println("Enter date interval as \"MM.DD-MM.DD\":");
                        String[] dateInterval = reader.readLine().split("\\D");     
                        logger.debug("getting TT for student {} and period {}.{}-{}.{}", student, dateInterval[0], dateInterval[1], dateInterval[2], dateInterval[3]);                      
                        String timeTableString = timeTable.getTTForGroup(student,
                                LocalDateTime.of(Year.now().getValue(), Month.of(Integer.parseInt(dateInterval[0])),
                                        Integer.parseInt(dateInterval[1]), 0, 0, 0),
                                LocalDateTime.of(Year.now().getValue(), Month.of(Integer.parseInt(dateInterval[2])),
                                        Integer.parseInt(dateInterval[3]), 23, 59, 59));
                        timeTable.printTimeTable(timeTableString);
                    } else {
                        System.out.println("student whith this id \"" + studentId + "\" is not exist.");                        
                        logger.warn("student with this id {} is not exist", studentId);
                    }

                    break;
                case "2":
                    logger.debug("case 2");                 
                    System.out.println("Enter teacher id:");
                    int teacherId = Integer.parseInt(reader.readLine());
                    Teacher teacher = teacherService.findOne(teacherId);

                    if (teacher != null) {
                        System.out.println("Enter date interval as \"MM.DD-MM.DD\":");
                        String[] dateInterval = reader.readLine().split("\\D");             
                        logger.debug("getting TT for teacher {} and period {}.{}-{}.{}", teacher, dateInterval[0], dateInterval[1], dateInterval[2], dateInterval[3]);                  
                        String timeTableString = timeTable.getTTForTeacher(teacher,
                                LocalDateTime.of(Year.now().getValue(), Month.of(Integer.parseInt(dateInterval[0])),
                                        Integer.parseInt(dateInterval[1]), 0, 0, 0),
                                LocalDateTime.of(Year.now().getValue(), Month.of(Integer.parseInt(dateInterval[2])),
                                        Integer.parseInt(dateInterval[3]), 23, 59, 59));
                        timeTable.printTimeTable(timeTableString);
                    } else {
                        System.out.println("teacher whith this id \"" + teacherId + "\" is not exist.");                        
                        logger.warn("teacher with this id {} is not exist", teacherId);
                    }

                    break;
                case "help":
                    logger.debug("case help");
                    System.out.println(commandListMessage);
                    break;
                default:
                    logger.debug("case default");
                    System.out.println("Please enter the correct command.");
                    break;
                }
                command = reader.readLine();
            }
            reader.close();
        } catch (IOException e) {
            logger.error("Reading failure", e);
        }   
        logger.info("Exit Main");
    }

}
java spring spring-mvc servlets
1个回答
-1
投票

我想您可能没有此类的重写方法AbstractAnnotationConfigDispatcherServletInitializer正确。环顾四周。启用调试日志。您为什么不尝试使用Spring Boot。它会自动为您管理所有依赖项的创建。

© www.soinside.com 2019 - 2024. All rights reserved.