本文将介绍将外部资源文件夹添加到SpringBoot的详细情况,特别是关于如何将外部文件导入eclipse的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将涉及一
本文将介绍将外部资源文件夹添加到Spring Boot的详细情况,特别是关于如何将外部文件导入eclipse的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将涉及一些关于55.springboot引入资源文件、Jawr & Springboot - 资源文件夹未解析、NutzBoot 读取外部资源文件功能的诞生、Spring boot 国际化自动加载资源文件问题的知识。
本文目录一览:- 将外部资源文件夹添加到Spring Boot(如何将外部文件导入eclipse)
- 55.springboot引入资源文件
- Jawr & Springboot - 资源文件夹未解析
- NutzBoot 读取外部资源文件功能的诞生
- Spring boot 国际化自动加载资源文件问题
将外部资源文件夹添加到Spring Boot(如何将外部文件导入eclipse)
我想相对于jar的位置添加一个资源文件夹(除了jar中的打包资源),例如:
/Directory Application.jar /resources test.txt
我尝试了以下方法:
@Overridepublic void addResourceHandlers(final ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**") .addResourceLocations("/resources/", "file:/resources/");}
我也尝试过:
.addResourceLocations("/resources/", "file:resources/");
http://localhost:8080/resources/test.txt
使用任何一种设置进行访问都会导致出现白标错误页面。我该如何解决?
答案1
小编典典您的第二种方法可行:
@Overridepublic void addResourceHandlers(final ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**") .addResourceLocations("/resources/", "file:resources/");}
但 仅 当您从启动Spring Boot时/Directory
,因为file:resources/
它是相对路径。
cd Directoryjava -jar Application.jar
如果可以将所有内容打包到jar中,这很好,但是如果必须引用外部资源,则应该使用绝对路径来避免此类问题。
55.springboot引入资源文件
1.效果
2.应用
参考:
https://www.cnblogs.com/grasp/p/11473826.html
https://blog.csdn.net/happyblueice/article/details/86538843
启动命令spring.profiles.active指定文件中的值 > 文件中spring.profiles.active指定的文件列表中最后一次出现的值 > 文件中spring.profiles.include指定的文件列表中最后一次出现的值
应用:开发 生产 环境切换
配置静态资源
2.注意问题
要引入静态资源文件 就别用 @AllArgsConstructor了 否则影响@Value注解
Jawr & Springboot - 资源文件夹未解析
如何解决Jawr & Springboot - 资源文件夹未解析?
我的问题是 css & js 文件包没有解决。
我正在将我的 WAR 应用程序迁移到 Spring Boot 应用程序。
这是jawr 的servlet 3.0 配置:
@Configuration
public class WebJawrConfiguration {
private final Properties properties;
public WebJawrConfiguration(final WebSelfiscProperties webProperties) {
this.properties = new Properties();
this.properties.putAll(webProperties.getJawr().entrySet().stream().collect(Collectors.toMap(e -> "jawr." + e.getKey(),Entry::getValue)));
}
@Bean
public JawrSpringController jawrBinaryController() {
final JawrSpringController jawrBinaryController = new JawrSpringController();
jawrBinaryController.setConfiguration(properties);
jawrBinaryController.setType(JawrConstant.BINARY_TYPE);
return jawrBinaryController;
}
@Bean
@DependsOn("jawrBinaryController")
public JawrSpringController jawrCssController() {
final JawrSpringController jawrCssController = new JawrSpringController();
jawrCssController.setConfiguration(properties);
jawrCssController.setType(JawrConstant.CSS_TYPE);
// jawrCssController.setMapping("/public/bundles/css");
return jawrCssController;
}
@Bean
@DependsOn("jawrCssController")
public JawrSpringController jawrJsController() {
final JawrSpringController jawrJsController = new JawrSpringController();
jawrJsController.setConfiguration(properties);
jawrJsController.setType(JawrConstant.JS_TYPE);
// jawrJsController.setMapping("/public/bundles/js");
return jawrJsController;
}
@Configuration
@ConditionalOnMissingBean(name = "jawrHandlerMapping")
@DependsOn("jawrJsController")
public class jawrHandlerMappingConfiguration {
private final JawrSpringController jawrJsController;
private final JawrSpringController jawrCssController;
private final JawrSpringController jawrBinaryController;
/**
* Constructeur
*
* @param jawrJsController
* @param jawrCssController
* @param jawrBinaryController
*/
public jawrHandlerMappingConfiguration(final JawrSpringController jawrJsController,final JawrSpringController jawrCssController,final JawrSpringController jawrBinaryController) {
super();
this.jawrJsController = jawrJsController;
this.jawrCssController = jawrCssController;
this.jawrBinaryController = jawrBinaryController;
}
@Bean
public HandlerMapping jawrHandlerMapping() {
final SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping();
handlerMapping.setorder(Ordered.HIGHEST_PRECEDENCE);
final Map<String,Object> urlMap = new HashMap<>();
urlMap.put("**/*.css",jawrCssController);
urlMap.put("**/*.eot",jawrBinaryController);
urlMap.put("**/*.gif",jawrBinaryController);
urlMap.put("**/*.ico",jawrBinaryController);
urlMap.put("**/*.jpg",jawrBinaryController);
urlMap.put("**/*.jpeg",jawrBinaryController);
urlMap.put("**/*.js",jawrJsController);
urlMap.put("**/*.png",jawrBinaryController);
urlMap.put("**/*.ttf",jawrBinaryController);
urlMap.put("**/*.woff",jawrBinaryController);
urlMap.put("**/*.woff2",jawrBinaryController);
urlMap.put("**/*.svg",jawrBinaryController);
handlerMapping.setUrlMap(urlMap);
return handlerMapping;
}
}
}
可能 application.properties 的一部分:
# Common properties
jawr.debug.on=false
jawr.gzip.on=false
jawr.gzip.ie6.on=false
jawr.charset.name=UTF-8
jawr.css.bundle.base.id=/base.css
jawr.css.bundle.base.mappings=/public/css/blue-theme.css,/public/css/main.css
以及它是如何在我的 JSP 中声明的
<jawr:style src="/base.css" />
如果我设置了jawr.debug.on=true 一切正常:
<link rel="stylesheet" type="text/css" media="screen" href="/sel/public/css/blue-theme.css?d=1136145833">
<link rel="stylesheet" type="text/css" media="screen" href="/sel/public/css/main.css?d=762931402">
如果我设置了jawr.debug.on=false 一个哈希前缀链接到版本它。但是id不再解析。
<link rel="stylesheet" type="text/css" media="screen" href="/2096063500/base.css">
一个多星期以来,我一直在努力解决这个问题。没有成功。
有人遇到过这个问题吗? 谢谢。
解决方法
我解决了我的问题。
这是我的新配置:
@Configuration
public class WebJawrConfiguration {
private final Properties properties;
/**
* Constructor
*
* @param webProperties
*/
public WebJawrConfiguration(final WebSelfiscProperties webProperties) {
this.properties = new Properties();
this.properties.putAll(webProperties.getJawr().entrySet().stream().collect(Collectors.toMap(e -> "jawr." + e.getKey(),Entry::getValue)));
}
@Bean
@DependsOn("jawrBinaryController")
public JawrSpringController jawrCssController() {
final JawrSpringController jawrCssController = new JawrSpringController();
final Properties propertiesCss = new Properties();
propertiesCss.putAll(properties.entrySet().stream().filter(e -> !e.getKey().toString().contains("jawr.js"))
.collect(Collectors.toMap(Entry::getKey,Entry::getValue)));
jawrCssController.setConfiguration(propertiesCss);
jawrCssController.setType(JawrConstant.CSS_TYPE);
return jawrCssController;
}
@Bean
@DependsOn("jawrCssController")
public JawrSpringController jawrJsController() {
final JawrSpringController jawrJsController = new JawrSpringController();
final Properties propertiesJs = new Properties();
propertiesJs.putAll(properties.entrySet().stream().filter(e -> !e.getKey().toString().contains("jawr.css"))
.collect(Collectors.toMap(Entry::getKey,Entry::getValue)));
jawrJsController.setConfiguration(propertiesJs);
jawrJsController.setType(JawrConstant.JS_TYPE);
return jawrJsController;
}
@Configuration
@DependsOn("jawrJsController")
public class jawrHandlerMappingConfiguration {
private final JawrSpringController jawrJsController;
private final JawrSpringController jawrCssController;
/**
* Constructor
*
* @param jawrJsController
* @param jawrCssController
*/
public jawrHandlerMappingConfiguration(final JawrSpringController jawrJsController,final JawrSpringController jawrCssController) {
super();
this.jawrJsController = jawrJsController;
this.jawrCssController = jawrCssController;
}
@Bean
@DependsOn("jawrJsController")
public HandlerMapping jawrHandlerMapping() {
final SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping();
handlerMapping.setOrder(Ordered.HIGHEST_PRECEDENCE);
final Map<String,Object> urlMap = new HashMap<>();
urlMap.put("**/*.css",jawrCssController);
urlMap.put("**/*.js",jawrJsController);
handlerMapping.setUrlMap(urlMap);
return handlerMapping;
}
}
}
并使用 *.css、*.js 映射我的 servlet 调度程序
NutzBoot 读取外部资源文件功能的诞生
前因
Nutz 接触时间了,最近使用 NutzBoot 开发了个微服务,在准备部署的时候遇上一个问题,NutzBoot 在发布时,会将配置文件、模板文件都打包进 jar 包,那么在后期做细微调整时将涉及到重新发包,本人强伯症,受不了这个,如果项目只是需要对配置做些修改,或者模板做些修改,完全没必要重新打包发布,故而发生了之后的事情 - 改造
过程
怎样把配置文件打包到 jar 包外面?
修改 pom.xml <build>...</build>
标签内加入配置,过滤 resources
目录
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/*</exclude>
</excludes>
<filtering>true</filtering>
</resource>
</resources>
<build><plugins>...</plugins></build>
标签内加入配置,将配置资源目录编译到 jar 包外
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<encoding>UTF-8</encoding>
<outputDirectory>
${project.build.directory}
</outputDirectory> <!-- 表示把配置文件拷到和jar包同一个路径下 -->
<resources>
<resource>
<directory>src/main/resources/</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
此时执行 mvn clean;mvn compile;mvn package;
已经可以将资源文件打包到 jar 包外部了。
那么问题来了,项目如何读取外部资源
首先我是想办法解决 beetl 模板文件的读取,因为 NutzBoot 项目没有考虑过外部读取的情况,所以必须经过改造,与 @wendal 进行讨论后,采取从 Setup 的 init 方法着手,手动指定模板读取路径,实现如下:
public class MainSetup implements Setup {
@Override
public void init(NutConfig nc) {
for(ViewMaker maker: nc.getViewMakers()) {
if(maker.getClass() == BeetlViewMakerStarter.class) {
// 获取BeetlViewMaker对象
BeetlViewMaker beetlViewMaker = (BeetlViewMaker)maker;
// 生成FileResourceLoader 从文件系统取资源
FileResourceLoader fileResourceLoader = new FileResourceLoader();
fileResourceLoader.setCharset("UTF-8");
// 设置jar包外部模板目录
fileResourceLoader.setRoot(getBasePath() + File.separator + "template");
// 配置beetlViewMaker使用外部目录读取模板
beetlViewMaker.groupTemplate.setResourceLoader(fileResourceLoader);
}
}
}
@Override
public void destroy(NutConfig nc) {
}
// 获取jar包当前目录
static String getBasePath() {
String basePath = MainSetup.class.getProtectionDomain().getCodeSource().getLocation().getPath();
int lastIndex = basePath.lastIndexOf(File.separator);
basePath = basePath.substring(0, lastIndex);
try {
basePath = java.net.URLDecoder.decode(basePath, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return basePath;
}
}
外部模板读取问题解决,就剩下读取外部配置文件,于是跟 @wendal 又进行各种沟通,最后决定修改源码让 NutzBoot 支持读取外部配置文件,顺便实现了指定配置文件目录自动扫描,详细步骤就不写了,如有兴趣可关注 论坛讨论贴 NutzBoot 如何打包发布
经过修改后,现在 NutzBoot 支持外部配置方式,比如将 application.properties
放在 jar 包同级目录。 另外 application.properties
新增支持配置读取其他配置文件, 如:
nutz.boot.configure.properties.dir=config
// 系统将自动扫描jar包同级config目录下所有properties文件进行参数读取
结束语
到此我外部读取参数和模板的需求算是圆满解决,也特别感谢 @wendal 给予的支持,特此记录
Spring boot 国际化自动加载资源文件问题
最近正在把以前的一个Spring项目整改为基于Spring boot配置的项目。中间遇到一个国际化资源加载的问题,正常来说只要在application.properties文件中定义正确的资源文件路径,Spring boot就启动时就会自动加载资源。
spring.messages.basename=i18n/message
但是我的项目修改后获取消息时系统报错,找不到对应语言的资源配置。于是试图找到原因。Google好久都没找到,简直好像就我一个人遇到这鬼问题一样?。只好自己一步一步去调试。
调试中首先发现系统在调用MessageSource的地方注入的不是MessageSourceAutoConfiguration中定义的ResourceBundleMessageSource对象,而是一个DelegatingMessageSource对象,而且这个对象是空的什么都没有。MessageSourceAutoConfiguration中的定义如下:
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
if (StringUtils.hasText(this.basename)) {
messageSource.setBasenames(StringUtils.commaDelimitedListToStringArray(
StringUtils.trimAllWhitespace(this.basename)));
}
if (this.encoding != null) {
messageSource.setDefaultEncoding(this.encoding.name());
}
messageSource.setFallbackToSystemLocale(this.fallbackToSystemLocale);
messageSource.setCacheSeconds(this.cacheSeconds);
messageSource.setAlwaysUseMessageFormat(this.alwaysUseMessageFormat);
return messageSource;
}
调试Spring boot 启动过程找到了 DelegatingMessageSource 对象来源, 在启动过程中如果Spring没有找到messageSource定义,就会自动创建一个 DelegatingMessageSource 对象提供给SpringContext。也就是说 MessageSourceAutoConfiguration 根本没有被加载。打断点在 MessageSourceAutoConfiguration 中也确定了Spring boot启动时根本没有执行 MessageSourceAutoConfiguration 的定义。
/**
* Initialize the MessageSource.
* Use parent''s if none defined in this context.
*/
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// Make MessageSource aware of parent MessageSource.
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// Only set parent context as parent MessageSource if no parent MessageSource
// registered already.
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isDebugEnabled()) {
logger.debug("Using MessageSource [" + this.messageSource + "]");
}
}
else {
// Use empty MessageSource to be able to accept getMessage calls.
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate MessageSource with name ''" + MESSAGE_SOURCE_BEAN_NAME +
"'': using default [" + this.messageSource + "]");
}
}
}
继续调试发现 MessageSourceAutoConfiguration 上有 @Conditional(ResourceBundleCondition.class) 这么个注解,@Conditional 官方介绍 Indicates that a component is only eligible for registration when all specified conditions match. 大概意思就是只有满足所有条件才会被注册。继续去看ResourceBundleCondition.class的实现。
private ConditionOutcome getMatchOutcomeForBasename(ConditionContext context,
String basename) {
ConditionMessage.Builder message = ConditionMessage
.forCondition("ResourceBundle");
for (String name : StringUtils.commaDelimitedListToStringArray(
StringUtils.trimAllWhitespace(basename))) {
for (Resource resource : getResources(context.getClassLoader(), name)) {
if (resource.exists()) {
return ConditionOutcome
.match(message.found("bundle").items(resource));
}
}
}
return ConditionOutcome.noMatch(
message.didNotFind("bundle with basename " + basename).atAll());
}
这个方法是根据basename(上面配置的“i18n/message”)存不存在返回是否满足条件,也就是去找classpath:i18n/message.properties文件,看了下目录确实没有这个文件(只有message_**.properties)。因为之前项目messageSource加载时自己配置的,所以并没有这个问题。但现在Spring boot中没有找到message.properties这个默认文件整个messageSource就不加载了。。?简直思密达。。。??总算是解决这个奇葩问题。 话说真的就只有我遇到这问题么,没搜到没搜到啊。。。。?
最后总结Spring boot自动加载messageSource一定要有一个默认的资源文件。也就是basename.properties。好不科学啊,之前没有找到默认会默认取中文(没考虑过原理?),现在没有默认整个就不加载了。
今天关于将外部资源文件夹添加到Spring Boot和如何将外部文件导入eclipse的分享就到这里,希望大家有所收获,若想了解更多关于55.springboot引入资源文件、Jawr & Springboot - 资源文件夹未解析、NutzBoot 读取外部资源文件功能的诞生、Spring boot 国际化自动加载资源文件问题等相关知识,可以在本站进行查询。
本文标签: