Весенняя загрузка @Controller не работает при развертывании в автономном режиме Tomcat

#spring #spring-boot #spring-mvc

#весна #пружинный ботинок #весна-mvc

Вопрос:

У меня есть приложение Spring Boot ThymeLeaf с @RestController и @Controller, все работает нормально со встроенным tomcat, но когда я развертываю свое приложение с файлом war в Tomcat 8.5 @Класс контроллера не работает @RestController работает нормально, когда я захожу на любую страницу с использованием контроллера @Controller, у меня ошибка 404.

Это мой pom.xml:

 <?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.example.boot</groupId>
        <artifactId>boot-parent</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>api</artifactId>
    <packaging>war</packaging>

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <version>2.1.2.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>

        <dependency>
            <groupId>com.example.boot</groupId>
            <artifactId>web</artifactId>
            <version>${project.version}</version>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.14</version>
            <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>[5.0.2,5.1.47)</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-cas</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-ldap</artifactId>
            <version>${spring-security.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
            <scope>provided</scope>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                    <skip>false</skip>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <showDeprecation>true</showDeprecation>
                    <showWarnings>true</showWarnings>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <configuration>
                    <packagingExcludes>WEB-INF/lib/tomcat-*.jar</packagingExcludes>
                    <warName>skillinventory</warName>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-resources-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-resources</id>
                        <phase>validate</phase>
                        <goals>
                            <goal>copy-resources</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.build.directory}/classes/resources/</outputDirectory>
                            <resources>
                                <resource>
                                    <directory>${project.parent.basedir}/web-si/src/main/web/dist/FrontEnd/</directory>
                                </resource>
                            </resources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

  

Это мой класс приложения Spring Boot:

 @SpringBootApplication
@EnableScheduling
@PropertySource("classpath:application.properties")
public class Application extends SpringBootServletInitializer {

    @Value("${cas.service}")
    private String service;

    @Value("${cas.loginUrl}")
    private String loginUrl;

    @Value("${cas.cas30ServiceTicketValidator}")
    private String cas30ServiceTicketValidator;

    @Value("${cas.createAuthorityList}")
    private String createAuthorityList;

    @Value("${cas.key}")
    private String key;

    @Value("${cas.logoutFilterLink}")
    private String logoutFilterLink;

    @Value("${cas.setFilterProcessesUrl}")
    private String setFilterProcessesUrl;

    @Value("${cas.setCasServerUrlPrefix}")
    private String setCasServerUrlPrefix;

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public ServiceProperties serviceProperties() {
        ServiceProperties serviceProperties = new ServiceProperties();
        serviceProperties.setService(service);
        serviceProperties.setSendRenew(false);
        return serviceProperties;
    }

    @Bean
    @Primary
    public AuthenticationEntryPoint authenticationEntryPoint(ServiceProperties sP) {
        CasAuthenticationEntryPoint entryPoint = new CasAuthenticationEntryPoint();
        entryPoint.setLoginUrl(loginUrl);
        entryPoint.setServiceProperties(sP);
        return entryPoint;
    }

    @Bean
    public TicketValidator ticketValidator() {
        return new Cas30ServiceTicketValidator(cas30ServiceTicketValidator);
    }

    @Bean
    public CasAuthenticationProvider casAuthenticationProvider() {
        CasAuthenticationProvider provider = new CasAuthenticationProvider();
        provider.setAuthenticationUserDetailsService(customUserDetailsService());
        provider.setKey(key);
        return provider;
    }
    @Bean
    public AuthenticationUserDetailsService<CasAssertionAuthenticationToken> customUserDetailsService() {
        return token -> {
            AttributePrincipal principal = token.getAssertion().getPrincipal();
            String name = principal.getName();
            return new User(name, "pwd", AuthorityUtils.createAuthorityList(createAuthorityList));
        };
    }

    @Bean
    public SecurityContextLogoutHandler securityContextLogoutHandler() {
        return new SecurityContextLogoutHandler();
    }

    @Bean
    public LogoutFilter logoutFilter() {
        LogoutFilter logoutFilter = new LogoutFilter(logoutFilterLink, securityContextLogoutHandler());
        logoutFilter.setFilterProcessesUrl(setFilterProcessesUrl);
        return logoutFilter;
    }

    @Bean
    public SingleSignOutFilter singleSignOutFilter() {
        SingleSignOutFilter singleSignOutFilter = new SingleSignOutFilter();
        singleSignOutFilter.setCasServerUrlPrefix(setCasServerUrlPrefix);
        singleSignOutFilter.setIgnoreInitConfiguration(true);
        return singleSignOutFilter;
    }

    @EventListener
    public SingleSignOutHttpSessionListener singleSignOutHttpSessionListener(HttpSessionEvent event) {
        return new SingleSignOutHttpSessionListener();
    }
}
  

Моя конфигурация безопасности:

 @EnableWebSecurity
@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    private AuthenticationProvider authenticationProvider;
    private AuthenticationEntryPoint authenticationEntryPoint;

    @Autowired
    public SpringSecurityConfig(CasAuthenticationProvider
                                        casAuthenticationProvider,
                                AuthenticationEntryPoint authenticationEntryPoint) {
        this.authenticationProvider = casAuthenticationProvider;
        this.authenticationEntryPoint = authenticationEntryPoint;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("/v1/datas/**")
                .permitAll()
                .and()
                .authorizeRequests()
                .regexMatchers("/")
                .authenticated()
                .and()
                .authorizeRequests()
                .regexMatchers("/")
                .permitAll()
                .and()
                .httpBasic()
                .authenticationEntryPoint(authenticationEntryPoint);
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws
            Exception {
        auth.authenticationProvider(authenticationProvider);
    }


    @Override
    protected AuthenticationManager authenticationManager() throws Exception {
        return new ProviderManager(Arrays.asList(authenticationProvider));
    }

    @Bean
    public CasAuthenticationFilter casAuthenticationFilter(ServiceProperties serviceProperties) throws Exception {
        CasAuthenticationFilter filter = new CasAuthenticationFilter();
        filter.setServiceProperties(serviceProperties);
        filter.setAuthenticationManager(authenticationManager());
        return filter;
    }
  

Мой контроллер с @Controller :

 @Controller
public class ManagerDataController {

    @Value("${theme.root}")
    private String themeRoot;

    @RequestMapping(value = "/hr/skilldatas", method = RequestMethod.GET)
    public String goProgessData(Model model) {
        model.addAttribute("themeRoot", themeRoot);
        return "data-process";
    }

  @RequestMapping(value = "/hr/datas", method = RequestMethod.GET)
  public String goDataManager(Model model) {
      model.addAttribute("themeRoot", themeRoot);
      return "datamanager";
  }

}

  

Я не знаю, почему он отлично работает со встроенным tomcat, но автономным tomcat?

Комментарии:

1. Глядя на ваши зависимости и плагины, я бы сказал, что сначала начните с их исправления. Тот факт, что вы объявили версию для spring-boot-starter-data-jpa , заставляет меня задуматься, есть ли у вас смешанные версии. Включение spring-context заставляет меня задуматься, почему, поскольку это включено в уже существующие стартеры. Вам не нужен плагин war (поскольку плагин Spring Boot позаботится об этом и фактически поместит его в другой каталог. ). Наконец, проверьте свои журналы о том, почему вы получаете 404, в журналах должна быть информация, возможно, включите ведение журнала ОТЛАДКИ, чтобы получить больше информации.

2. Спасибо, сэр, но что вы имеете в виду под смешанной версией, я не понимаю этот путь.

Ответ №1:

Оказывается, что, поскольку я объявляю, что область зависимости thymeleaf предоставляется, это не Spring false, после того, как я изменю область, чтобы скомпилировать ее, работающую сейчас.