Spring Boot project with static content generates 404 when running jar

转自: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.

share | improve this question
 

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.

share | improve this answer
 
 
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')
}
share | improve this answer
 
 
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

  • alezx
    Junior Member
    •  Apr 2014
    •  2

    #1

    static content with spring boot

    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 !
  • patrad
    Junior Member
    •  Jul 2011
    •  12

    #2
    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.
  • theanswerli
    Junior Member
    •  Apr 2014
    •  1

    #3
    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...
  • alezx
    Junior Member
    •  Apr 2014
    •  2

    #4
    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
  • jlic
    Junior Member
    •  Apr 2010
    •  39

    #5
    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
  • patrad
    Junior Member
    •  Jul 2011
    •  12

    #6
    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`
  • jlic
    Junior Member
    •  Apr 2010
    •  39

    #7
    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
  • patrad
    Junior Member
    •  Jul 2011
    •  12

    #8
    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.
  • jlic
    Junior Member
    •  Apr 2010
    •  39

    #9
    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
  • jlic
    Junior Member
    •  Apr 2010
    •  39

    #10
    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)






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值