WebMvcConfigurerAdapter


 

spring Boot 默認的處理方式就已經足夠了,默認情況下Spring Boot 使用WebMvcAutoConfiguration中配置的各種屬性。

建議使用Spring Boot 默認處理方式,需要自己配置的地方可以通過配置文件修改。

但是如果你想完全控制Spring MVC,你可以在@Configuration注解的配置類上增加@EnableWebMvc,增加該注解以后WebMvcAutoConfiguration中配置就不會生效,你需要自己來配置需要的每一項。這種情況下的配置方法建議參考WebMvcAutoConfiguration類。

http://blog.csdn.net/isea533/article/details/50412212


靜態資源訪問

在我們開發Web應用的時候,需要引用大量的js、css、圖片等靜態資源。

默認配置

Spring Boot默認提供靜態資源目錄位置需置於classpath下,目錄名需符合如下規則:

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

舉例:我們可以在src/main/resources/(classpath下)目錄下創建static,在該位置放置一個圖片文件D.jsp(src/main/resources/static/D.jpg)。啟動程序后,嘗試訪問http://localhost:8080/D.jpg。如能顯示圖片,配置成功。

http://blog.didispace.com/springbootweb/



27.1.5 Static Content

By default Spring Boot will serve static content from a directory called /static (or /public or /resources or /META-INF/resources) in the classpath or from the root of the ServletContext. It uses the ResourceHttpRequestHandler from Spring MVC so you can modify that behavior by adding your own WebMvcConfigurerAdapter and overriding the addResourceHandlers method.

In a stand-alone web application the default servlet from the container is also enabled, and acts as a fallback, serving content from the root of the ServletContext if Spring decides not to handle it. Most of the time this will not happen (unless you modify the default MVC configuration) because Spring will always be able to handle requests through the DispatcherServlet.

You can customize the static resource locations using spring.resources.staticLocations (replacing the default values with a list of directory locations). If you do this the default welcome page detection will switch to your custom locations, so if there is an index.html in any of your locations on startup, it will be the home page of the application.

In addition to the ‘standard’ static resource locations above, a special case is made for Webjars content. Any resources with a path in /webjars/** will be served from jar files if they are packaged in the Webjars format.

[Tip]

Do not use the src/main/webapp directory if your application will be packaged as a jar. Although this directory is a common standard, it will only work with war packaging and it will be silently ignored by most build tools if you generate a jar.

Spring Boot also supports advanced resource handling features provided by Spring MVC, allowing use cases such as cache busting static resources or using version agnostic URLs for Webjars.

To use version agnostic URLs for Webjars, simply add the webjars-locator dependency. Then declare your Webjar, taking jQuery for example, as "/webjars/jquery/dist/jquery.min.js" which results in "/webjars/jquery/x.y.z/dist/jquery.min.js" where x.y.z is the Webjar version.

[Note]

If you are using JBoss, you’ll need to declare the webjars-locator-jboss-vfs dependency instead of the webjars-locator; otherwise all Webjars resolve as a 404.

To use cache busting, the following configuration will configure a cache busting solution for all static resources, effectively adding a content hash in URLs, such as<link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>:

spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
[Note]

Links to resources are rewritten at runtime in template, thanks to a ResourceUrlEncodingFilter, auto-configured for Thymeleaf, Velocity and FreeMarker. You should manually declare this filter when using JSPs. Other template engines aren’t automatically supported right now, but can be with custom template macros/helpers and the use of the ResourceUrlProvider.

When loading resources dynamically with, for example, a JavaScript module loader, renaming files is not an option. That’s why other strategies are also supported and can be combined. A "fixed" strategy will add a static version string in the URL, without changing the file name:

spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/** spring.resources.chain.strategy.fixed.enabled=true spring.resources.chain.strategy.fixed.paths=/js/lib/ spring.resources.chain.strategy.fixed.version=v12

With this configuration, JavaScript modules located under "/js/lib/" will use a fixed versioning strategy "/v12/js/lib/mymodule.js" while other resources will still use the content one <link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>.

See ResourceProperties for more of the supported options.

[Tip]

This feature has been thoroughly described in a dedicated blog post and in Spring Framework’s reference documentation.

 

 

http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-web-applications.html


While this may not be a new revelation to those of you that have been following Spring Boot since the SpringOne announcement, there is one detail for which you may not be aware. Spring Boot will automatically add static web resources located within any of the following directories:

/META-INF/resources/
/resources/
/static/
/public/
In the case of the Consuming a RESTful Web Service with jQuery guide, we included index.html and hello.js files in the /public/ folder. This means that not only does Spring Boot offer a simple approach to building Java or Groovy apps, you can also use it to easily deploy client-side JavaScript code and test it within a real web server environment!

You can analyze the details of how this works by reviewing the source code for WebMvcAutoConfiguration in Spring Boot, you will see the following declaration for a string array containing locations for Classpath resources.

private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
"classpath:/META-INF/resources/", "classpath:/resources/",
"classpath:/static/", "classpath:/public/" };

 


Further in the code you can see that these locations are added to a Spring MVC ResourceHandlerRegistry.

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!registry.hasMappingForPattern("/webjars/**")) {
registry.addResourceHandler("/webjars/**").addResourceLocations(
"classpath:/META-INF/resources/webjars/");
}
if (!registry.hasMappingForPattern("/**")) {
registry.addResourceHandler("/**").addResourceLocations(
RESOURCE_LOCATIONS);
}
}

 


To review, web AutoConfiguration is executed when Spring Boot identifies a class with the @Controller annotation. The result is that you can place static web resources in any of these locations, and those static assets are then served by Tomcat when you access your application.

Spring Boot offers many exciting features to help easily create Spring based applications that you can “just run”. The fun byproduct is that it is equally as easy to build and test client-side JavaScript apps with Spring Boot.

https://spring.io/blog/2013/12/19/serving-static-web-content-with-spring-boot

 

 

URL重定向:

package com.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addRedirectViewController("/", "/1.txt");//1.txt文件放在src/main/resources/static/1.txt
    }
}

 

It would have worked out of the box if you hadn't used @EnableWebMvc annotation. When you do that you switch off all the things that Spring Boot does for you in WebMvcAutoConfiguration. You could remove that annotation, or you could add back the view controller that you switched off:

@Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("forward:/index.html"); }

Ok I figured it out. In case you also want to change the url from / to /index.html use "redirect:/index.html" instead of forward.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class MyWebMvcConfig {

    @Bean
    public WebMvcConfigurerAdapter forwardToIndex() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addViewControllers(ViewControllerRegistry registry) {
                // forward requests to /admin and /user to their index.html
                registry.addViewController("/admin").setViewName(
                        "forward:/admin/index.html");
                registry.addViewController("/user").setViewName(
                        "forward:/user/index.html");
            }
        };
    }

}

http://stackoverflow.com/questions/27381781/java-spring-boot-how-to-map-my-app-root-to-index-html?noredirect=1&lq=1

 

 

 

 

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
import org.springframework.web.servlet.view.tiles2.TilesConfigurer;
import org.springframework.web.servlet.view.tiles2.TilesViewResolver;

import java.util.*;

/**
 * Created by MyWorld on 2016/11/13.
 */
@Configuration
@EnableWebMvc
public class WebMvcConfig extends WebMvcConfigurerAdapter {


    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        super.addInterceptors(registry);
    }

    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver=new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/views/");
        viewResolver.setSuffix(".jsp");
        viewResolver.setViewClass(JstlView.class);//將視圖解析為JstlView而不是InternalResourceView
        return viewResolver;
    }


    @Bean
    public TilesConfigurer tilesConfigurer() {
        final TilesConfigurer configurer = new TilesConfigurer();
//        configurer.setDefinitions(new String[] { "WEB-INF/views_common.xml" });
        configurer.setDefinitions(new String[]{"/WEB-INF/views_*.xml"});
        configurer.setCheckRefresh(true);
        return configurer;
    }

    @Bean
    public TilesViewResolver tilesViewResolver() {
        return new TilesViewResolver();
    }

    @Bean
    public MappingJackson2JsonView mappingJackson2JsonView() {
        return new MappingJackson2JsonView();
    }

    @Bean
    public ContentNegotiatingViewResolver contentNegotiatingViewResolver(TilesViewResolver tilesViewResolver, MappingJackson2JsonView mappingJackson2JsonView) {
        ContentNegotiatingViewResolver viewResolver = new ContentNegotiatingViewResolver();
        viewResolver.setIgnoreAcceptHeader(true);
        viewResolver.setDefaultContentType(MediaType.TEXT_HTML);
        Map<String, String> map = new HashMap<>();
        map.put("atom", "application/atom+xml");
        map.put("html", "text/html");
        map.put("json", "application/json");
        viewResolver.setMediaTypes(map);
        viewResolver.setFavorParameter(false);
        List<ViewResolver> list = new ArrayList<>();
        list.add(tilesViewResolver);
        viewResolver.setViewResolvers(list);
        viewResolver.setDefaultViews(Collections.singletonList(mappingJackson2JsonView));
        return viewResolver;
    }

    @Bean
    public MultipartResolver multipartResolver() {
        CommonsMultipartResolver  commonsMultipartResolver=new CommonsMultipartResolver();
        commonsMultipartResolver.setDefaultEncoding("utf-8");
        commonsMultipartResolver.setMaxUploadSize(10485760000L);
        commonsMultipartResolver.setMaxInMemorySize(40960);

        return commonsMultipartResolver;
    }



}

 

56. Installing Spring Boot applications

In additional to running Spring Boot applications using java -jar it is also possible to make fully executable applications for Unix systems. This makes it very easy to install and manage Spring Boot applications in common production environments.

To create a ‘fully executable’ jar with Maven use the following plugin configuration:

<plugin>
    <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <executable>true</executable> </configuration> </plugin>

With Gradle, the equivalent configuration would be:

apply plugin: 'org.springframework.boot'

springBoot {
    executable = true
}

You can then run your application by typing ./my-application.jar (where my-application is the name of your artifact).

[Note]

Fully executable jars work by embedding an extra script at the front of the file. Not all tools currently accept this format so you may not always be able to use this technique.

[Note]

The default script supports most Linux distributions and is tested on CentOS and Ubuntu. Other platforms, such as OS X and FreeBSD, will require the use of a custom embeddedLaunchScript.

[Note]

When a fully executable jar is run, it uses the jar’s directory as the working directory.

 http://docs.spring.io/spring-boot/docs/current/reference/html/deployment-install.html

 

Spring boot executable jar/war

spring boot里其實不僅可以直接以 Java -jar demo.jar的方式啟動,還可以把jar/war變為一個可以執行的腳本來啟動,比如./demo.jar。

把這個executable jar/war 鏈接到/etc/init.d下面,還可以變為Linux下的一個service。

只要在spring boot maven plugin里配置:

1
2
3
4
5
6
7
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable> true </executable>
</configuration>
</plugin>

這樣子打包出來的jar/war就是可執行的。更多詳細的內容可以參考官方的文檔。

http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#deployment-install

 

zip 格式里的 magic number

生成的jar/war實際上是一個zip格式的文件,這個zip格式文件為什么可以在shell下面直接執行?

研究了下zip文件的格式。zip文件是由entry組成的,而每一個entry開頭都有一個4個字節的magic number:

1
2
3
Local file header signature = 0x04034b50 (read as a little-endian number)
 
即 PK\ 003 \ 004

參考:https://en.wikipedia.org/wiki/Zip_(file_format)

zip處理軟件是讀取到magic number才開始處理。所以在linux/unix下面,可以把一個bash文件直接寫在一個zip文件的開頭,這樣子會被認為是一個bash script。 而zip處理軟件在讀取這個文件時,仍然可以正確地處理。

比如spring boot生成的executable jar/war,的開頭是:

1
2
3
4
5
6
7
8
9
10
#!/bin/bash
#
# . ____ _ __ _ _
# /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
# ( ( )\___ | '_ | ' _| | '_ \/ _` | \ \ \ \
# \\/ ___)| |_)| | | | | || (_| | ) ) ) )
# ' |____| .__|_| |_|_| |_\__, | / / / /
# =========|_|==============|___/=/_/_/_/
# :: Spring Boot Startup Script ::
#

在script內容結尾,可以看到zip entry的magic number:

1
2
exit 0
PK^C^D

 

spring boot 的 launch.script

實際上spring boot maven plugin是把下面這個script打包到fat jar的最前面部分。

https://github.com/spring-projects/spring-boot/blob/1ca9cdabf71f3f972a9c1fdbfe9a9f5fda561287/spring-boot-tools/spring-boot-loader-tools/src/main/resources/org/springframework/boot/loader/tools/launch.script

這個launch.script 支持很多變量設置。還可以自動識別是處於auto還是service不同mode中。

所謂的auto mode就是指直接運行jar/war:

1
./demo.jar

而service mode則是由操作系統在啟動service的情況:

1
service demo start/stop/restart/status

所以fat jar可以直接在普通的命令行里執行,./xxx.jar 或者link到/etc/init.d/下,變為一個service。

 

http://www.importnew.com/24471.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM