#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, после того, как я изменю область, чтобы скомпилировать ее, работающую сейчас.