开发者社区 问答 正文

spring boot theme无法启用?报错

希望在spring boot 1.2.4 中加入ResourceBundleThemeSource管理主题资源, 成功启动后访问freemarker视图, 读取主题资源报错, 日志中看到, spring仅查找了messageSource而未查找themeSource, 有人碰到过此问题吗?

我尝试过在WebMvcConfigurerAdapter中通过@Bean直接将ResourceBundleThemeSource拿如管理, 无论是加入了ResourceBundleThemeSource还是LocaleMessageSource启动都会报错.

随后仿造WebMvcAutoConfiguration那个类, 修改代码将ResourceBundleThemeSource纳入spring管理, 启动成功, 且看到autoconfig正确报告, 且找到我配置的资源, 但读取时, 日志中看出, 仅查找了MessageSource, 未查找ThemeSource

日志好像是这样的(全凭记忆)

could not found resource name defaultThemeName for zh_CN // 这里未查找theme资源而只查找了message资源


求大神解答!!

展开
收起
爱吃鱼的程序员 2020-06-14 14:48:46 541 分享 版权
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB

    经过摸索,终于发现病灶....改太急....

    @BeanpublicThemeSourcemessageSource(){ResourceBundleThemeSourcemessageSource=newResourceBundleThemeSource();if(StringUtils.hasText(this.basename)){messageSource.setBasenamePrefix(trimAllWhitespace(this.basename));}returnmessageSource;}



    改为

    @BeanpublicThemeSourcethemeSource(){ResourceBundleThemeSourcethemeSource=newResourceBundleThemeSource();if(StringUtils.hasText(this.basename)){themeSource.setBasenamePrefix(trimAllWhitespace(this.basename));}returnthemeSource;}



    就好了

    明天将日志和配置贴上来得把你配置发出来,看起来像是什么配置有问题

    日志

    2015-07-0809:29:07.611DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Exposingrequestattribute'base'withvalue[http://localhost:8080]tomodel
    2015-07-0809:29:07.612DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'message'oftype[java.lang.String]torequestinviewwithname'common/test.html'
    2015-07-0809:29:07.612DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'request'oftype[org.springframework.web.servlet.support.RequestContext]torequestinviewwithname'common/test.html'
    2015-07-0809:29:07.612DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.web.context.request.async.WebAsyncManager.WEB_ASYNC_MANAGER'oftype[org.springframework.web.context.request.async.WebAsyncManager]torequestinviewwithname'common/test.html'
    2015-07-0809:29:07.612DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.web.servlet.DispatcherServlet.CONTEXT'oftype[org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext]torequestinviewwithname'common/test.html'
    2015-07-0809:29:07.612DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.web.servlet.resource.ResourceUrlProvider'oftype[org.springframework.web.servlet.resource.ResourceUrlProvider]torequestinviewwithname'common/test.html'
    2015-07-0809:29:07.612DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'characterEncodingFilter.FILTERED'oftype[java.lang.Boolean]torequestinviewwithname'common/test.html'
    2015-07-0809:29:07.612DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.web.servlet.DispatcherServlet.THEME_SOURCE'oftype[org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext]torequestinviewwithname'common/test.html'
    2015-07-0809:29:07.612DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.web.servlet.DispatcherServlet.LOCALE_RESOLVER'oftype[org.springframework.web.servlet.i18n.CookieLocaleResolver]torequestinviewwithname'common/test.html'
    2015-07-0809:29:07.613DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALE'oftype[java.util.Locale]torequestinviewwithname'common/test.html'
    2015-07-0809:29:07.613DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.web.servlet.HandlerMapping.bestMatchingPattern'oftype[java.lang.String]torequestinviewwithname'common/test.html'
    2015-07-0809:29:07.613DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.web.servlet.DispatcherServlet.OUTPUT_FLASH_MAP'oftype[org.springframework.web.servlet.FlashMap]torequestinviewwithname'common/test.html'
    2015-07-0809:29:07.613DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.web.servlet.HandlerMapping.pathWithinHandlerMapping'oftype[java.lang.String]torequestinviewwithname'common/test.html'
    2015-07-0809:29:07.613DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.web.servlet.DispatcherServlet.FLASH_MAP_MANAGER'oftype[org.springframework.web.servlet.support.SessionFlashMapManager]torequestinviewwithname'common/test.html'
    2015-07-0809:29:07.613DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.web.servlet.HandlerMapping.uriTemplateVariables'oftype[java.util.LinkedHashMap]torequestinviewwithname'common/test.html'
    2015-07-0809:29:07.613DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.web.servlet.DispatcherServlet.THEME_RESOLVER'oftype[org.springframework.web.servlet.theme.CookieThemeResolver]torequestinviewwithname'common/test.html'
    2015-07-0809:29:07.613DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.core.convert.ConversionService'oftype[org.springframework.format.support.DefaultFormattingConversionService]torequestinviewwithname'common/test.html'
    2015-07-0809:29:07.613DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'base'oftype[java.lang.String]torequestinviewwithname'common/test.html'
    2015-07-0809:29:07.613DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'springMacroRequestContext'oftype[org.springframework.web.servlet.support.RequestContext]torequestinviewwithname'common/test.html'
    2015-07-0809:29:07.615DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :RenderingFreeMarkertemplate[common/test.html]inFreeMarkerView'common/test.html'
    2015-07-0809:29:07.667 WARN13264---[nio-8080-exec-1]o.s.c.s.ResourceBundleMessageSource   :ResourceBundle[defaultThemeName]notfoundforMessageSource:Can'tfindbundleforbasenamedefaultThemeName,localeen_US


    这两行很可疑,为什么主题资源是这个类 org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext

    2015-07-0809:29:07.612DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.web.servlet.DispatcherServlet.THEME_SOURCE'oftype[org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext]torequestinviewwithname'common/test.html'


    配置如下

    spring.messages.basename=config/i18nspring.messages.encoding="UTF-8"spring.messages.cacheSeconds=-1spring.theme.basename=config/theme-




    packagecom.vip.ygd.common;importjavax.servlet.ServletException;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.web.servlet.config.annotation.InterceptorRegistry;importorg.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;importorg.springframework.web.servlet.handler.HandlerInterceptorAdapter;importorg.springframework.web.servlet.i18n.CookieLocaleResolver;importorg.springframework.web.servlet.i18n.LocaleChangeInterceptor;importorg.springframework.web.servlet.theme.CookieThemeResolver;importorg.springframework.web.servlet.theme.ThemeChangeInterceptor;@ConfigurationpublicclassMvcConfigextendsWebMvcConfigurationSupport{@BeanpublicHandlerInterceptorAdapterrequestDefValueInterceptor(){returnnewHandlerInterceptorAdapter(){@OverridepublicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsServletException{request.setAttribute("base",request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath());request.setAttribute("user",request.getSession().getAttribute("user"));returntrue;}@OverridepublicvoidafterCompletion(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,Exceptionex)throwsException{if(ex!=null){//sendmailandlogthis}super.afterCompletion(request,response,handler,ex);}};}@BeanpublicLocaleChangeInterceptorlocaleChangeInterceptor(){returnnewLocaleChangeInterceptor();}@BeanpublicThemeChangeInterceptorthemeChangeInterceptor(){returnnewThemeChangeInterceptor();}@OverrideprotectedvoidaddInterceptors(InterceptorRegistryregistry){registry.addInterceptor(requestDefValueInterceptor());registry.addInterceptor(themeChangeInterceptor());registry.addInterceptor(localeChangeInterceptor());}@Bean(name="themeResolver")publicCookieThemeResolverthemeResolver(){CookieThemeResolverresolver=newCookieThemeResolver();resolver.setCookieMaxAge(31536000);resolver.setCookieName("clienttheme");resolver.setDefaultThemeName("defaultThemeName");returnresolver;}@Bean(name="localeResolver")publicCookieLocaleResolverlocaleResolver(){CookieLocaleResolverresolver=newCookieLocaleResolver();resolver.setCookieName("locale");resolver.setCookieMaxAge(31536000);returnresolver;}//@Bean(name="themeSource")//publicResourceBundleThemeSourcethemeSource(){//ResourceBundleThemeSourcethemeSource=newResourceBundleThemeSource();//themeSource.setBasenamePrefix("classpath:config/theme-");//returnthemeSource;//}//@Bean(name="messageSource")//publicReloadableResourceBundleMessageSourcemessageSource(){//ReloadableResourceBundleMessageSourcebundle=newReloadableResourceBundleMessageSource();//bundle.setBasename("classpath:config/i18n");//bundle.setDefaultEncoding("UTF-8");//bundle.setCacheSeconds(0);//returnbundle;//}}



    packagecom.vip.ygd.common;importstaticorg.springframework.util.StringUtils.commaDelimitedListToStringArray;importstaticorg.springframework.util.StringUtils.trimAllWhitespace;importjava.io.IOException;importjava.util.Iterator;importjava.util.Set;importorg.springframework.boot.autoconfigure.EnableAutoConfiguration;importorg.springframework.boot.autoconfigure.condition.ConditionOutcome;importorg.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;importorg.springframework.boot.autoconfigure.condition.SpringBootCondition;importorg.springframework.boot.context.properties.ConfigurationProperties;importorg.springframework.boot.context.properties.EnableConfigurationProperties;importorg.springframework.context.MessageSource;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.ConditionContext;importorg.springframework.context.annotation.Conditional;importorg.springframework.context.annotation.Configuration;importorg.springframework.core.Ordered;importorg.springframework.core.annotation.Order;importorg.springframework.core.io.Resource;importorg.springframework.core.io.support.PathMatchingResourcePatternResolver;importorg.springframework.core.type.AnnotatedTypeMetadata;importorg.springframework.ui.context.ThemeSource;importorg.springframework.ui.context.support.ResourceBundleThemeSource;importorg.springframework.util.ConcurrentReferenceHashMap;importorg.springframework.util.StringUtils;importcom.vip.ygd.common.ThemeAutoConfig.ResourceThemeBundleCondition;/***{@linkEnableAutoConfigurationAuto-configuration}for{@linkMessageSource}.**@authorDaveSyer*@authorPhillipWebb*/@Configuration@ConditionalOnMissingBean(ThemeSource.class)@Order(Ordered.HIGHEST_PRECEDENCE)@Conditional(ResourceThemeBundleCondition.class)@EnableConfigurationProperties@ConfigurationProperties(prefix="spring.theme")publicclassThemeAutoConfig{privatestaticfinalResource[]NO_RESOURCES={};/***Comma-separatedlistofbasenames,eachfollowingtheResourceBundleconvention.*Essentiallyafully-qualifiedclasspathlocation.Ifitdoesn'tcontainapackage*qualifier(suchas"org.mypackage"),itwillberesolvedfromtheclasspathroot.*/privateStringbasename="messages";/***Messagebundlesencoding.*/privateStringencoding="utf-8";/***Loadedresourcebundlefilescacheexpiration,inseconds.Whensetto-1,bundles*arecachedforever.*/privateintcacheSeconds=-1;@BeanpublicThemeSourcemessageSource(){ResourceBundleThemeSourcemessageSource=newResourceBundleThemeSource();if(StringUtils.hasText(this.basename)){messageSource.setBasenamePrefix(trimAllWhitespace(this.basename));}returnmessageSource;}publicStringgetBasename(){returnthis.basename;}publicvoidsetBasename(Stringbasename){this.basename=basename;}publicStringgetEncoding(){returnthis.encoding;}publicvoidsetEncoding(Stringencoding){this.encoding=encoding;}publicintgetCacheSeconds(){returnthis.cacheSeconds;}publicvoidsetCacheSeconds(intcacheSeconds){this.cacheSeconds=cacheSeconds;}protectedstaticclassResourceThemeBundleConditionextendsSpringBootCondition{privatestaticConcurrentReferenceHashMap<String,ConditionOutcome>cache=newConcurrentReferenceHashMap<String,ConditionOutcome>();@OverridepublicConditionOutcomegetMatchOutcome(ConditionContextcontext,AnnotatedTypeMetadatametadata){Stringbasename=context.getEnvironment().getProperty("spring.theme.basename","messages");ConditionOutcomeoutcome=cache.get(basename);if(outcome==null){outcome=getMatchOutcomeForBasename(context,basename);cache.put(basename,outcome);}returnoutcome;}privateConditionOutcomegetMatchOutcomeForBasename(ConditionContextcontext,Stringbasename){for(Stringname:commaDelimitedListToStringArray(trimAllWhitespace(basename))){for(Resourceresource:getResources(context.getClassLoader(),name)){if(resource.exists()){returnConditionOutcome.match("Bundlefoundfor"+"spring.theme.basename:"+name);}}}returnConditionOutcome.noMatch("Nobundlefoundfor"+"spring.theme.basename:"+basename);}privateResource[]getResources(ClassLoaderclassLoader,Stringname){try{returnnewSkipPatternPathMatchingResourcePatternResolver(classLoader).getResources("classpath*:"+name+"*.properties");}catch(Exceptionex){returnNO_RESOURCES;}}}/***{@linkPathMatchingResourcePatternResolver}thatskipswellknownJARsthatdon't*containmessages.properties.*/privatestaticclassSkipPatternPathMatchingResourcePatternResolverextendsPathMatchingResourcePatternResolver{privatestaticfinalClassLoaderROOT_CLASSLOADER;static{ClassLoaderclassLoader=null;try{classLoader=ClassLoader.getSystemClassLoader();while(classLoader.getParent()!=null){classLoader=classLoader.getParent();}}catch(Throwableex){}ROOT_CLASSLOADER=classLoader;}privatestaticfinalString[]SKIPPED={"aspectjweaver-","hibernate-core-","hsqldb-","jackson-annotations-","jackson-core-","jackson-databind-","javassist-","snakeyaml-","spring-aop-","spring-beans-","spring-boot-","spring-boot-actuator-","spring-boot-autoconfigure-","spring-core-","spring-context-","spring-data-commons-","spring-expression-","spring-jdbc-","spring-orm-","spring-tx-","spring-web-","spring-webmvc-","tomcat-embed-","joda-time-","hibernate-entitymanager-","hibernate-validator-","logback-classic-","logback-core-","thymeleaf-"};publicSkipPatternPathMatchingResourcePatternResolver(ClassLoaderclassLoader){super(classLoader);}@OverrideprotectedvoidaddAllClassLoaderJarRoots(ClassLoaderclassLoader,Set<Resource>result){if(classLoader!=ROOT_CLASSLOADER){super.addAllClassLoaderJarRoots(classLoader,result);}}@OverrideprotectedSet<Resource>doFindAllClassPathResources(Stringpath)throwsIOException{Set<Resource>resources=super.doFindAllClassPathResources(path);for(Iterator<Resource>iterator=resources.iterator();iterator.hasNext();){Resourceresource=iterator.next();for(Stringskipped:SKIPPED){if(resource.getFilename().startsWith(skipped)){iterator.remove();break;}}}returnresources;}}}



    引用来自“逝水fox”的评论

    得把你配置发出来,看起来像是什么配置有问题这个theme有啥用
    2020-06-14 14:49:05
    赞同 展开评论
问答分类:
问答标签:
问答地址: