#java #spring #spring-boot #spring-mvc #spring5
#java #spring #spring-boot #spring-mvc #spring5
Вопрос:
У меня есть веб-приложение Spring Boot, изначально созданное для внутреннего сервера Tomcat (работает). Затем я принял это приложение для запуска на сервере веб-логики. Мое приложение компилируется и развертывается на сервере без проблем, но когда оно не обслуживает страницы MVC. Каждый вызов выдает ошибку 404. Из приведенной ниже ошибки похоже, что сервлет spring dispatcher присутствует, но даже locale установлен неправильно. Я не могу понять, что здесь не так или отсутствует, но когда я создаю RestController вместо MVC, он работает, и отображается содержимое. Приложение основано на Sprint Boot 2.3.2
<16 Aug 2020, 14:12:32,792 British Summer Time> <Notice> <Stdout> <BEA-000000> <14:12:32.792 [[ACTIVE] ExecuteThread: '10' for queue: 'weblogic.kernel.Default (self-tuning)'] WARN org.springframework.web.servlet.PageNotFound - No mapping for GET /alf/home> <16 Aug 2020, 14:12:34,922 British Summer Time> <Notice> <Stdout> <BEA-000000> <14:12:34.922 [[ACTIVE] ExecuteThread: '10' for queue: 'weblogic.kernel.Default (self-tuning)'] DEBUG org.springframework.context.support.ReloadableResourceBundleMessageSource - No properties file found for [messages] - neither plain properties nor XML> <16 Aug 2020, 14:12:34,922 British Summer Time> <Notice> <Stdout> <BEA-000000> <14:12:34.922 [[ACTIVE] ExecuteThread: '10' for queue: 'weblogic.kernel.Default (self-tuning)'] DEBUG org.springframework.context.support.ReloadableResourceBundleMessageSource - No properties file found for [messages_en_IE] - neither plain properties nor XML> <16 Aug 2020, 14:12:34,922 British Summer Time> <Notice> <Stdout> <BEA-000000> <14:12:34.922 [[ACTIVE] ExecuteThread: '10' for queue: 'weblogic.kernel.Default (self-tuning)'] DEBUG org.springframework.context.support.ReloadableResourceBundleMessageSource - No properties file found for [messages_en] - neither plain properties nor XML> <16 Aug 2020, 14:12:34,923 British Summer Time> <Notice> <Stdout> <BEA-000000> <14:12:34.923 [[ACTIVE] ExecuteThread: '10' for queue: 'weblogic.kernel.Default (self-tuning)'] DEBUG org.springframework.context.support.ReloadableResourceBundleMessageSource - No properties file found for [messages_en_US] - neither plain properties nor XML> <16 Aug 2020, 14:12:34,969 British Summer Time> <Error> <HTTP> <BEA-101107> <[ServletContext@2002815395[app:alf_war_exploded module:alf-2.0.1 path:null spec-version:4.0]] Problem occurred while serving the error page. javax.servlet.jsp.JspTagException: No message found under code 'page.error.title.text' for locale 'en_US'. at org.springframework.web.servlet.tags.MessageTag.doEndTag(MessageTag.java:294) at jsp_servlet._web_45_inf._pages._error.__page_45_404._jsp__tag0(__page_45_404.java:199) at jsp_servlet._web_45_inf._pages._error.__page_45_404._jspService(page-404.jsp:9) at weblogic.servlet.jsp.JspBase.service(JspBase.java:35) at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:295) Truncated. see log file for complete stacktrace> <16 Aug 2020, 14:12:34,972 British Summer Time> <Notice> <Stdout> <BEA-000000> <14:12:34.972 [[ACTIVE] ExecuteThread: '10' for queue: 'weblogic.kernel.Default (self-tuning)'] DEBUG org.springframework.web.servlet.DispatcherServlet - Completed 404 NOT_FOUND> <16 Aug 2020, 14:12:34,974 British Summer Time> <Notice> <Stdout> <BEA-000000> <[[ACTIVE] ExecuteThread: '10' for queue: 'weblogic.kernel.Default (self-tuning)'] [2020-08-16T14:12:34,973] [10.2.16.95-agr5311] INFO AutoLoginFilter::doFilter - END 2020-08-16 14:12:34:972,agr5311,10.2.16.95,2204,2193,11,/alf/home>
Application class:
@SpringBootApplication
@ComponentScan({"ie.gov.agriculture.alf", "ie.gov.agriculture.sso"})
public class AlfApplication extends SpringBootServletInitializer implements WebApplicationInitializer {
public AlfApplication() {
super();
setRegisterErrorPageFilter(false); // disable ErrorPageFilter causing bullshit error messages
}
@Override
public void onStartup(ServletContext servletContext) {
AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext();
appContext.register(AppConfig.class);
appContext.register(WebMvcConfig.class);
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("SpringDispatcher", new DispatcherServlet(appContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
ContextLoaderListener contextLoaderListener = new ContextLoaderListener(appContext);
servletContext.addListener(contextLoaderListener);
// Filter.
FilterRegistration.Dynamic filterReg = servletContext.addFilter("encodingFilter", CharacterEncodingFilter.class);
filterReg.setInitParameter("encoding", "UTF-8");
filterReg.setInitParameter("forceEncoding", "true");
filterReg.addMappingForUrlPatterns(null, true, "/*");
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(AlfApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(AlfApplication.class, args);
}
}
Класс AppConfig:
@Configuration
@EnableCaching
public class AppConfig {
@Bean
public ReloadableResourceBundleMessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
@Bean
public LocalValidatorFactoryBean messageValidator() {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setValidationMessageSource(this.messageSource());
return validator;
}
@Bean
public ConversionServiceFactoryBean convertionService() {
return new ConversionServiceFactoryBean();
}
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager("alfCache");
}
}
наконец, класс WebMvcConfig:
@Configuration
@ServletComponentScan
public class WebMvcConfig implements WebMvcConfigurer {
@Bean
public ViewResolver getViewResolver() {
UrlBasedViewResolver resolver = new UrlBasedViewResolver();
resolver.setPrefix("/WEB-INF/pages/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
return resolver;
}
@Bean
public CommonsMultipartResolver multipartResolver() {
return new CommonsMultipartResolver();
}
@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
jsonConverter.setObjectMapper(objectMapper);
return jsonConverter;
}
@Bean
public CookieLocaleResolver cookieLocaleResolverExample() {
CookieLocaleResolver localeResolver = new CookieLocaleResolver();
localeResolver.setDefaultLocale(Locale.ENGLISH);
localeResolver.setCookieName("alf-locale-cookie");
localeResolver.setCookieMaxAge(3600);
return localeResolver;
}
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver localeResolver = new SessionLocaleResolver();
localeResolver.setDefaultLocale(Locale.UK);
localeResolver.setDefaultTimeZone(TimeZone.getTimeZone("UTC"));
return localeResolver;
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
Комментарии:
1. какова ваша упаковка в файле maven / gradle?
2. это war-файл, здесь проблем нет
3. Вы не используете Spring Boot, но работаете в обход (или против него). Ваш
AlfApplication
ошибочен, поскольку он в основном работает вокруг Spring Boot. Удалите свойonStartup
метод, чтобы правильно вызвать и запустить Spring Boot во внешнем контейнере. При этом также остальная часть вашей конфигурации показывает, что вы пытаетесь обойти функции автоматической настройки Spring Boot.4. Против Весны ? Когда я удалил то, что вы говорите, контекста нет, диспетчер и, как правило, приложение вообще не развертывается
Ответ №1:
Ответ на эту проблему, как всегда, простой, компонент конфигурации сообщений должен выглядеть следующим образом, и все работает нормально, ключ — «classpath: » в setBasenema
@Bean
public ReloadableResourceBundleMessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:messages");
return messageSource;
}