转自:http://stackoverflow.com/questions/21358403/spring-boot-project-with-static-content-generates-404-when-running-jar/

Spring
Boot project with static content generates 404 when running jar

The recent blog post (https://spring.io/blog/2013/12/19/serving-static-web-content-with-spring-boot)
by Spring regarding the use of static web content in Spring Boot projects indicates that several resource directories may be used:

  • /META-INF/resources/
  • /resources/
  • /static/
  • /public/

This is thanks to the WebMvcAutoConfiguration class which automatically adds these directories to the classpath. This all seems fine and appears to work when using the spring-boot-maven-plugin spring-boot:run goal,
all of your static content is working (eg: /index.html).

When you package your Spring Boot project and allow the spring-boot-maven-plugin to
create the enhanced JAR then attempt to run your project using java
-jar my-spring-boot-project.jar
 you find that your static content now returns a 404 error.

asked Jan 26
at 1:14
 

2 Answers

It turns out that whilst Spring Boot is being clever at adding the various resource directories to the classpath, Maven is not and it's up to you to deal with that part. By default, only src/main/resources will
be included in your JAR. If you create a folder called /static in
the root of your project (as implied by the blog post) then it will work fine whilst using the spring-boot:run Maven
goal but not once you create a JAR.

The easiest solution is to create your /static folder
inside /src/main/resources and
then Maven will include it in the JAR. Alternative you can add additional resource locations to your Maven project:

    <resources>
<resource>
<directory>/src/main/resources</directory>
</resource>
<resource>
<directory>/static</directory>
<targetPath>/static</targetPath>
</resource>
</resources>

I hope this is useful to someone, it's kind of obvious when you step back and look at how Maven works but it might stump a few people using Spring Boot as it's designed to be pretty much configuration free.

answered Jan
26 at 1:14
 
 
Just for the record: I think you misread the blog because it doesn't mention maven at all, and isn't
using a jar archive. If you do exactly as Roy did in the blog it would work. –  Dave
Syer
 Jan
26 at 9:27
 
do you have an example project somewhere so i can see...i still can't get it to work –  Chris
DaMour
 May
1 at 16:43

I am banging my head against the wall trying to figure out how to do this with gradle. Any tips?

EDIT: I got it to work by adding this to my build.gradle:

// Copy resources into the jar as static content, where Spring expects it.
jar.into('static') {
from('src/main/webapp')
}
answered Mar
18 at 5:42
kgreenek

37219
 
 
Gradle uses "src/main/resources" by default as well. What's wrong with using that? –  Dave
Syer
 Mar
18 at 7:07
1  
That is true, putting it in the resources directly will get your files copied into the jar. However,
in order for Spring to recognize and serve your files as static content, you need to package it under a directory called "static", "public", "resources", or "/META-INF/resources/" in the jar file. If you simply put your files in the resources directory, they
all get copied to the root directory in the jar and Spring serves 404's when you try to access them.–  kgreenek Mar
19 at 2:56
 
1  
Right, so the simplest (least configuration, maximum functionality) solution is to put your static
resources in "src/main/resourecs/static". That's all I meant. –  Dave
Syer
 Mar
19 at 6:32

---------- 我是华丽丽的分隔线 ----------

转自:http://forum.spring.io/forum/spring-projects/boot/747399-static-content-with-spring-boot

  • Junior Member
    • Join Date: Apr
      2014
    • Posts: 2

    static content with spring boot

    Apr 9th, 2014, 10:48 AM
    Hi ,



    we are developing a web app with spring boot. It is packaged as jar, because we want to run it standalone using the integrated tomcat.

    We have currently two problems:



    1) I have the index.html and all the js files in src/main/webapp, and this is perfectly working when I run my main.java from eclipse. But when I run mvn clean install the webapp directory and its content is not going in the jar. (so I can't distribute it)



    2) Even if I manage to add this resources to the jar, (adding the webapp resource to the maven sources in the pom) I end up having a huge jar because we have lots of static content (images etc) !



    So my question in what is the best way to serve static content in a spring boot standalone application ? Where should I put my javascript files ? and my images ?



    any suggestion is welcome, thanks !
    Tags: None

  • Junior Member
    • Join Date: Jul
      2011
    • Posts: 12
    Apr 10th, 2014, 12:59 PM
    For "1", did you you change the the packaging to a "war"? There is some documentation on how to do the conversion in the boot guide.



    http://docs.spring.io/spring-boot/do...yable-war-file



    For "2" we package all JS and images with the app. Large resources like videos, etc are hosted elsewhere.

    • Unapproved
  • Junior Member
    • Join Date: Apr
      2014
    • Posts: 1
    Apr 11th, 2014, 04:55 AM
    the first question: you can create a folder in the src/main/resource named "static",then you could move all files into this folder, then run mvn install,it would be OK...

  • Junior Member
    • Join Date: Apr
      2014
    • Posts: 2
    Apr 11th, 2014, 07:24 AM
    Hi guys, thanks for the suggestions



    At the end I left all the js in src/main/webapp and in the maven assembly added a fileSet rule to copy the content of webapp to a "static" folder :

    Code:
    <fileSet>
    <directory>src/main/webapp</directory>
    <outputDirectory>static</outputDirectory>
    <includes>
    <include>**/*</include>
    </includes>
    </fileSet>

    so the jar remains slim but I get everything copied inside the dist folder 



    ale


  • Junior Member
    • Join Date: Apr
      2010
    • Posts: 39
    Apr 16th, 2014, 01:04 PM
    hi, I am also having similar problem. The doc (http://docs.spring.io/spring-boot/do...static-content)
    indicated that /public,/static,/resources or /META-INF/resources will all be served. But I am still getting 404 from the browser.



    I tried created a "public" folder and tried putting it immediately under the project root dir, under /src/main/resources/ but neither of them work.



    I am running it directly in Intellij, which executes the Application class.



    Anyone know where I should put the public folder exactly?



    Thanks,

    Joseph

  • Junior Member
    • Join Date: Jul
      2011
    • Posts: 12
    Apr 17th, 2014, 12:57 PM
    What url are you accessing in the browser?



    If I have the file `src/main/resources/static/foo` I can access it at `http://localhost/appcontext/foo`

  • Junior Member
    • Join Date: Apr
      2010
    • Posts: 39
    Apr 18th, 2014, 12:14 PM
    hi Patrad,



    Here is my project structure:

    Code:
    .
    .
    +- gradle
    | +-- wrapper
    +- src
    | +- main
    | | +- java
    | | | +-- com
    | | | +-- precious
    | | | +- config
    | | | +- greeting
    | | | +-- security
    | | +-- resources
    | | +-- static
    | | +- app
    | | +- css
    | | +- fonts
    | | +-- js
    | | +-- bower_components
    | | +- angularjs
    | | | +- css
    ..................

    src/main/resources/static/index.html is the file I am trying to access. And "http://localhost:8080/index.html" is the url I uses.



    I can hit the restful controller without any problem. However I can't hit the static content from the browser.



    The thing that looks strange to me is even for static content, it always goes thru "dispatchServlet", is that normal? I was under the impression that static content should be served directly thru tomcat. I haven't tried moving dispatchServlet to a non-root
    context url as the doc seems discourage that (http://docs.spring.io/spring-boot/do...patcherservlet).



    Joseph


  • Junior Member
    • Join Date: Jul
      2011
    • Posts: 12
    Apr 18th, 2014, 12:46 PM
    That looks right to me. (Your app is deployed at the root context right?)

    I think the dispatcherServlet is suppose to map /** to to ResourceHttpRequestHandler.

    You may have a mapping that overrides that behavior.



    At start up you should see a bunch of log lines where Spring MVC tells you what URL mappings it is using.

    Code:
    INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/error],methods=[],params=[],headers=[],consumes=[],produces=[text/html],custom=[]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.actuate.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest)
    INFO : org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]

    If you do see the /** mapping, then try setting a break point in ResourceHttpRequestHandler and debug what it is doing.


  • Junior Member
    • Join Date: Apr
      2010
    • Posts: 39
    Apr 18th, 2014, 01:56 PM
    thanks Patrad,



    I read something in http://stackoverflow.com/questions/2...ic-web-content that
    might help. I will give it a try late tonight and see if it solves my problem.



    Thanks,

    Joseph

  • Junior Member
    • Join Date: Apr
      2010
    • Posts: 39
    Apr 20th, 2014, 05:51 AM
    An update on what I eventually found and made it work!!. Thanks to Robert Hunt (see attached link)



    Short answer is, the doc is correct that all those resource, static, public paths were added to the ResourceHttpRequestHandler, however they were added as a classpath resource, so they need to be in a class path. However the pom.xml didn't have that. Thus the
    404 not found error.



    adding the following in the <build> section in the pom.xml solves my problem:

    <resources>

    <resource>

    <directory>src/main/public</directory>

    <targetPath>public</targetPath>

    </resource>

    </resources>





    However questions remains why the embeded tomcat docBase is set to a random folder??? (a bit more detail in the link provided below)

Spring Boot project with static content generates 404 when running jar的更多相关文章

  1. Spring boot web程序static资源放在jar外部

    spring boot程序的static目录默认在resources/static目录, 打包为jar的时候,会把static目录打包进去,这样会存在一些问题: static文件过多,造成jar包体积 ...

  2. 不常见偏门的Bug,Spring Boot IDEA 静态资源 图片访问404,初学者之殇

    用过Idea朋友都知道,它有一个非常让人喜欢的功能就是:打算在某个a目录下创建一个hello.class文件,那么你仅需要右键点击New-Java Class- 然后输入名字:a.hello 即可. ...

  3. 初学 Spring boot 报错 Whitelabel Error Page 404

    按照教程,写了个最简单的 HelloWorld,尼玛报错 -->Whitelabel Error Page 404. 网上99%都是项目结构不对,说什么 Application放在父级 pack ...

  4. 创建Spring boot project报错:Project build error: Non-resolvable parent POM for xxx:0.0.1-SNAPSHOT: Could not transfer artifact org.springframework.boot:spring-boot-starter-parent

    刚开始创建Spring boot项目时,pom.xml文件时报如下图错误: 在网上百度的说让更新下Maven的update project,我试了没用,最后将version版本改了就行了,我原来版本是 ...

  5. [Spring Boot ] Creating the Spring Boot Project : Demo: Creating a REST Controller

    In Spring boot, define a REST API endpoint is pretty easy. package com.globomatisc.bike.controllers; ...

  6. Spring Boot 打war包后自定义404页面不生效解决方法

    最近做一个项目,自定义了404页面,本地测试可以到自定义页面,但是打包放到tomcat里面就不行.搞了一天终于看到一个比较正确的方法.下面附上连接,非常感谢各位博主们 1.https://blog.c ...

  7. spring boot项目使用swagger-codegen生成服务间调用的jar包

    swagger-codegen的github:https://github.com/swagger-api/swagger-codegen 需要的环境:jdk > 1.7   maven > ...

  8. Spring Boot文档

    本文来自于springboot官方文档 地址:https://docs.spring.io/spring-boot/docs/current/reference/html/ Spring Boot参考 ...

  9. Spring Boot ConfigurationProperties validate

    使用@Query可以在自定义的查询方法上使用@Query来指定该方法要执行的查询语句,比如:@Query("select o from UserModel o where o.uuid=?1 ...

随机推荐

  1. 不错的题目-n个数连接得到的最大值

    这道题目还是很不错的 <[字符串排序]n个数连接得到最小或最大的多位整数> 题目 描述:设有n个正整数,将它们依次连成在一排,组成一个多位数,现在要求可能组成的多位数中最大的多位数是什么? ...

  2. Meteor 前端 RESTful API 通过后端 API 下载文件

    Meteor 下载文件 问题场景 后端 HTTP server提供一个下载接口,可是须要前端 Meteor 可以给浏览器用户开一个URL来下载这个文件. 举例:在线的Meteor Logo文件就好比后 ...

  3. Node.js具体解析

    介绍 JavaScript 高涨的人气带来了非常多变化.以至于现在使用其进行网络开发的形式也变得截然不同了.就如同在浏览器中一样,现在我们也能够在server上执行 JavaScript ,从前端跨越 ...

  4. 【cocos2d-x 3.7 飞机大战】 决战南海I (八) 背景移动

    採用双层背景.这样效果更好 .h class BackgroundMove : public Layer { public: BackgroundMove(); ~BackgroundMove(); ...

  5. u-boot学习(五):u-boot启动内核

    u-boot的目的是启动内核.内核位于Flash中,那么u-boot就要将内核转移到内存中.然后执行命令执行之.这些操作是由bootcmd命令完毕的. bootcmd=nand read.jffs2 ...

  6. 分布式设计《初尝memcached》

          之前听说过高性能的分布式缓存开源工具,但一直没有真正接触过,如今接触的产品中实用到过分布式缓存.所以决定一探到底.memcached是一个优秀的开源的分布式缓存工具.也是眼下比較火热的分布 ...

  7. 【Codeforces 105D】 Bag of mice

    [题目链接] http://codeforces.com/contest/148/problem/D [算法] 概率DP f[w][b]表示还剩w只白老鼠,b只黑老鼠,公主胜利的概率,那么 : 1. ...

  8. EOJ 3031 二进制倒置

    题目描述 给定一个整数 n(0≤n≤10100).将 n 的 334 位二进制表示形式(不包括开头可能的值为 0 的位,n=0 表示为 1 位 0)前后倒置,输出倒置后的二进制数对应的整数. 例如:n ...

  9. C++数字图像处理(1)-伽马变换

    https://blog.csdn.net/huqiang_823/article/details/80767019 1.算法原理    伽马变换(幂律变换)是常用的灰度变换,是一种简单的图像增强算法 ...

  10. hiho一下 第174周

    题目1 : Dice Possibility 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 What is possibility of rolling N dice ...