Spring-bootプロジェクトで静的コンテンツを提供することができません。
src/main/resources
の下にstatic
という名前のフォルダーを配置しました。その中にimages
という名前のフォルダーがあります。アプリをパッケージして実行すると、そのフォルダーに置いた画像が見つかりません。
静的ファイルをpublic
、resources
、およびMETA-INF/resources
に配置しようとしましたが、何も機能しません。
-tvf app.jarをjarすると、ファイルが正しいフォルダーのjar内にあることがわかります。たとえば、/static/images/head.png
ですが、http://localhost:8080/images/head.png
を呼び出すと、404
だけが取得されます
Spring-Bootがこれを見つけられない理由はありますか? (1.1.4 BTWを使用しています)
1年以上経っても死者を増やすことはしないでください。ただし、これまでのすべての回答でいくつかの重要な点を見逃しています。
@EnableWebMvc
はorg.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration
を無効にします。完全な制御が必要な場合はそれで問題ありませんが、それ以外の場合は問題です。すでに提供されているものに加えて、静的リソース用に別の場所を追加するためのコードを書く必要はありません。 v1.3.0.RELEASEのorg.springframework.boot.autoconfigure.web.ResourceProperties
を見ると、application.properties
で設定できるフィールドstaticLocations
が見えます。これは、ソースからの抜粋です。
/**
* Locations of static resources. Defaults to classpath:[/META-INF/resources/,
* /resources/, /static/, /public/] plus context:/ (the root of the servlet context).
*/
private String[] staticLocations = RESOURCE_LOCATIONS;
前述のように、リクエストURLはこれらの場所に対して相対解決されます。したがって、リクエストURLがsrc/main/resources/static/index.html
の場合は/index.html
が提供されます。パスの解決を担当するクラスは、Spring 4.1以降ではorg.springframework.web.servlet.resource.PathResourceResolver
です。
接尾辞パターンマッチングはデフォルトで有効になっています。つまり、リクエストURL /index.html
に対して、Springは/index.html
に対応するハンドラを探します。意図が静的コンテンツを提供することである場合、これは問題です。これを無効にするには、WebMvcConfigurerAdapter
を拡張し(ただし@EnableWebMvc
は使用しないでください)、次に示すようにconfigurePathMatch
をオーバーライドします。
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
super.configurePathMatch(configurer);
configurer.setUseSuffixPatternMatch(false);
}
私見、あなたのコードでより少ないバグを持つ唯一の方法は可能な限りコードを書くことではありません。すでに提供されているものを使用してください。たとえそれがいくらかの調査を必要とするとしても、その見返りは価値があります。
Spring-bootが述べているのとは違って、私のspring-boot jarがコンテンツを提供するようにするために:私はこのconfigクラスを通して私のsrc/main/resources/staticコンテンツを特別に登録しなければなりません:
@Configuration
public class StaticResourceConfiguration extends WebMvcConfigurerAdapter {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
"classpath:/META-INF/resources/", "classpath:/resources/",
"classpath:/static/", "classpath:/public/" };
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS);
}
}
私は同じような問題を抱えていました、そして、単純な解決策は私の設定クラスがWebMvcAutoConfiguration
を拡張することであることがわかった:
@Configuration
@EnableWebMvc
@ComponentScan
public class ServerConfiguration extends WebMvcAutoConfiguration{
}
静的コンテンツを提供するために他のコードは必要ありませんでしたが、src/main/webapp
の下にpublic
というディレクトリを置き、リソースディレクトリとしてsrc/main/webapp
を指すようにmavenを構成しました。これは、public
がtarget/classes
にコピーされるため、実行時にspring-boot/Tomcatが見つけることができるクラスパス上にあることを意味します。
「/」にマップされているか、パスがマップされていないコントローラを探します。
私はこのような問題を抱えていました、405のエラーを得て、そして数日間私の頭を激しく打ちました。問題は、私が@RestController
アノテーションを付けることを忘れていた@RequestMapping
アノテーションを付けられたコントローラーであることがわかりました。このマッピングパスはデフォルトで "/"に設定されており、静的コンテンツリソースマッピングはブロックされていると思います。
構成は次のようにすることができます。
@Configuration
@EnableWebMvc
public class WebMvcConfig extends WebMvcAutoConfigurationAdapter {
// specific project configuration
}
ここで重要なのは、WebMvcConfig
mayaddResourceHandlers
メソッドをオーバーライドすることです。したがって、明示的にsuper.addResourceHandlers(registry)
を呼び出す必要があります(デフォルトのリソースの場所に問題がなければ、メソッドをオーバーライドする必要はありません)。
ここでコメントする必要があるもう1つのことは、それらのデフォルトリソースロケーション(/static
、/public
、/resources
、および/META-INF/resources
)は、/**
にマップされたリソースハンドラがまだない場合にのみ登録されるということです。
これ以降、たとえばsrc/main/resources/static/images
という名前でimage.jpg
という名前のイメージがある場合は、次のURLを使用してアクセスできます。http://localhost:8080/images/image.jpg
(サーバーはポート8080で起動され、アプリケーションはルートコンテキストにデプロイされています)。
Spring Bootのリファレンスドキュメント をチェックしましたか?
デフォルトでは、Spring Bootはクラスパス内の
/static
(または/public
または/resources
または/META-INF/resources
)という名前のフォルダーまたはServletContextのルートから静的コンテンツを提供します。
プロジェクトとガイドを比較することもできます Spring MVCを使用したWebコンテンツの提供 、または spring-boot-sample-web-ui プロジェクトのソースコードをチェックすることもできます。
私はこの正確な問題を抱えていました、それから私は私のapplication.propertiesで定義したことに気づきました:
spring.resources.static-locations=file:/var/www/static
これは私が試した他のすべてを無効にしていました。私の場合は、両方を保持したいので、プロパティを保持して追加しました。
spring.resources.static-locations=file:/var/www/static,classpath:static
これはsrc/main/resources/staticからlocalhost:{port} /file.htmlとしてファイルを提供します。
別の目的を果たすためにオンラインから簡単にコピーされる可能性のあるこの小さなプロパティについては、誰も言及していなかったため、上記のどれも私には役に立ちませんでした。
それが役に立てば幸い!この問題を抱える人々のためのこの長い回答の投稿にうまく適合するだろうと考えました。
私は前の答えがそのトピックに非常によく取り組んでいると思います。ただし、アプリケーションでSpring Securityが有効になっている場合は、たとえば"/ static/fonts"のように、他の静的リソースディレクトリへの要求を許可するようにSpringに明確に指示する必要があるかもしれません。 =。
私の場合、デフォルトで "/ static/css"、 "/ static/js"、 "/ static/images"が許可されていましたが、/ static/fonts/**はSpring Securityの実装によってブロックされていました。
以下は私がこれをどのように修正したかの例です。
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
.....
@Override
protected void configure(final HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/", "/fonts/**").permitAll().
//other security configuration rules
}
.....
}
@EnableWebMvc
は静的リソースハンドラを作成するコードであるWebMvcAutoConfiguration
がロードされないようにすると人々は言っています。 WebMvcAutoConfiguration
がロードされないようにする条件が他にもあります。これを確認する最も明確な方法は、ソースを見ることです。
私の場合は、自動設定を妨げる条件であるWebMvcConfigurationSupport
から拡張されたクラスを持つライブラリを含めていました。
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
WebMvcConfigurationSupport
から拡張しないことが重要です。代わりにWebMvcConfigurerAdapter
から拡張してください。
この解決策は私のために働く:
まず、次のようにwebapp/WEB-INFの下にresourcesフォルダを置きます。
-- src
-- main
-- webapp
-- WEB-INF
-- resources
-- css
-- image
-- js
-- ...
第二に、春の設定ファイルで
@Configuration
@EnableWebMvc
public class MvcConfig extends WebMvcConfigurerAdapter{
@Bean
public ViewResolver getViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".html");
return resolver;
}
@Override
public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resource/**").addResourceLocations("WEB-INF/resources/");
}
}
そうすれば、 http:// localhost:8080/resource/image/yourimage.jpg のように、リソースのコンテンツにアクセスできます。
IDE内から(つまりEclipseまたはIntelliJ Ideaから始めて)アプリケーションを起動し、Mavenを使用しているときに問題が表面化する場合、解決策の鍵は Spring-にあります。 bootはじめに ドキュメント:
Mavenを使用している場合は、次のコマンドを実行してください。
mvn package && Java -jar target/gs-spring-boot-0.1.0.jar
その重要な部分は、package
という目標を追加して、アプリケーションを実際に起動する前に実行することです。 (アイデア:Run
メニュー、Edit Configrations...
、Add
、そしてそこからRun Maven Goal
を選択し、フィールドにpackage
の目標を指定します)
考慮すべきことが2つあります(Spring Boot v1.5.2.RELEASE) - 1)すべてのControllerクラスで@EnableWebMvcアノテーションがないか確認し、存在する場合は削除します2)アノテーションが使用されているControllerクラスをチェックします - @RestControllerまたは@Controller 。 1つのクラスにRest APIとMVCの動作を混在させないでください。 MVCには@Controllerを使い、REST APIには@RestControllerを使います。
2つ以上のことをすることで私の問題は解決しました。今私の春のブートは何の問題もなく静的なリソースをロードしています。 @Controller => load index.html =>静的ファイルをロードします。
@Controller
public class WelcomeController {
// inject via application.properties
@Value("${welcome.message:Hello}")
private String message = "Hello World";
@RequestMapping("/")
public String home(Map<String, Object> model) {
model.put("message", this.message);
return "index";
}
}
index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>index</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet/less" th:href="@{/webapp/assets/theme.siberia.less}"/>
<!-- The app's logic -->
<script type="text/javascript" data-main="/webapp/app" th:src="@{/webapp/libs/require.js}"></script>
<script type="text/javascript">
require.config({
paths: { text:"/webapp/libs/text" }
});
</script>
<!-- Development only -->
<script type="text/javascript" th:src="@{/webapp/libs/less.min.js}"></script>
</head>
<body>
</body>
</html>
私はリソースが404を見つけられなかったと言って私は春のブート2.1.3で同じ問題に直面していました。私はapplicatiion.propertiesから以下を削除しました。
#spring.resources.add-mappings=true
#spring.resources.static-locations=classpath:static
#spring.mvc.static-path-pattern=/**,
@ enableWebMVC を削除し、オーバーライドしているWebMvcConfigurerを削除しました
// @ EnableWebMvc
また、設定に @ EnableAutoConfiguration があることを確認してください。
そして、すべての静的リソースを src/main/resources/static に入れると、ついには魔法のように動作しました。
私は1.3.5を使用しており、Jerseyの実装を介して多数のRESTサービスをホストしています。私はいくつかのHTML + jsファイルを追加することを決心するまでそれはうまくいきました。このフォーラムで与えられた答えのどれも私を助けませんでした。しかし、私のpom.xmlに以下の依存関係を追加すると、src/main/resources/staticの内容はすべてブラウザ経由で表示されていました。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<dependency>
Spring-web/spring-webmvcはspring boot auto configを有効にする重要な推移的依存関係のようです。
私のSpring-Boot Angularアプリ(統合)がlocalhost:8080でUIを表示するために静的フォルダの内容を提供していないのと同じ状況にあります。フロントエンドはangular4で開発されているので、ng build
を使用して、出力パスdir src/main/resources/staticにファイルを生成しますが、内容は表示されません。私はindex.htmlを提供するために特別にコントローラを作りましたが、角度付きのものとlocalhostを理解するために何かが起動していないようです:8080は私のコントローラメソッド "index.html"から返された文字列をウェブページに表示するだけです。以下はindex.htmlです(私はログインコンポーネントが私が作成したものであり、UI用の私の主要なコンポーネントであるが、それでもapp-rootであろうとこれであろうと動作しません)。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Hello Test App</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-login></app-login>
<script type="text/javascript" src="runtime.js"></script><script type="text/javascript" src="polyfills.js"></script><script type="text/javascript" src="styles.js"></script><script type="text/javascript" src="vendor.js"></script><script type="text/javascript" src="main.js"></script></body>
</html>
コントローラコード:
@RequestMapping("/")
public String userInterface() {
return "index.html";
}
それが問題であるかどうかわからないが、これはIntellijIdeaで開発されたgradleベースのプロジェクトであり、春のブートバージョンは-org.springframework.boot:spring-boot-starter-web:2.0.2.RELEASE
です。
@Vizcaino - 簡単なトリックがあるとおっしゃったように - Intellijideaは同様にソースディレクトリ/フォルダを作成するための同様のオプションを提供しますか?右クリックメニュー - >新規作成 - >ディレクトリから作成しました。しかし、それが私の問題の原因であろうかどうか疑問に思う、それが同じことかどうかわからない?
グローバルコントローラを他のコントローラで上書きしたかどうかをチェックする価値があることもあります。簡単な例の間違い(kotlin):
@RestController("/foo")
class TrainingController {
@PostMapping
fun bazz(@RequestBody newBody: CommandDto): CommandDto = return commandDto
}
上記の場合、静的リソースを要求したときに取得します。
{
title: "Method Not Allowed",
status: 405,
detail: "Request method 'GET' not supported",
path: "/index.html"
}
その理由は、@PostMapping
を/foo
にマッピングしたいが、@RequestMapping
レベルでの@RestController
アノテーションを忘れていたことかもしれません。この場合、すべてのリクエストはPOST
にマップされ、この場合は静的コンテンツを受け取ることはできません。
FYI:私は完璧に機能するSpring Bootのアプリをめちゃくちゃにして静的フォルダのコンテンツを提供できないようにすることもできます。
@RestController
public class BadController {
@RequestMapping(method= RequestMethod.POST)
public String someMethod(@RequestParam(value="date", required=false)String dateString, Model model){
return "foo";
}
}
この例では、プロジェクトに不適切なコントローラを追加した後、ブラウザが静的フォルダにあるファイルを要求すると、エラー応答は 'になります。405 Method Not Allowed '。
注意コントローラパスの例では、パスがマッピングされていません。
GradleとEclipseを使用して同じ問題を抱えていて、それを把握するために何時間も費やしました。
コーディングは必要ありません。トリックは、メニューオプション[新規作成] - > [ソースフォルダ]([新規] - > [フォルダ])を使用して、src/main/resourcesの下に静的フォルダを作成する必要があることです。なぜこれが機能するのかわからないが、新しい - >ソースフォルダをしてから静的フォルダにした(それからソースフォルダダイアログでチェックしなければならないエラーが表示される)私が新しく追加したstaticフォルダにindex.htmlを追加しましたが、これで動作します。