Servir recursos estáticos com o Spring
1. Visão geral
Este artigo explora comoserve static resources with Spring - usando a configuração XML e Java.
Leitura adicional:
Ativos estáticos captáveis com Spring MVC
Este artigo mostra como armazenar em cache seus ativos estáticos, como arquivos Javascript e CSS, ao servi-los com o Spring MVC.
Minificação de ativos JS e CSS com Maven
Um guia rápido para usar o Maven para reduzir os arquivos Javascript e CSS em um projeto da Web Java.
2. Configuração XML
Se você precisa seguir o método antigo com a configuração baseada em XML, pode fazer bom uso do elementomvc:resources para apontar para a localização dos recursos com um padrão de URL público específico.
Por exemplo - a linha a seguir atenderá a todas as solicitações de recursos provenientes de um padrão de URL público como “/resources/**” pesquisando no diretório “/resources/” na pasta raiz em nosso aplicativo.
Agora, podemos acessar um arquivo CSS como na seguinte página html:
Exemplo 2.1
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
" rel="stylesheet">
Home
Hello world!
3. OResourceHttpRequestHandler
Spring 3.1. introduziuResourceHandlerRegistry para configurarResourceHttpRequestHandlers para servir a recursos estáticos do classpath, WAR ou sistema de arquivos. Podemos configurar oResourceHandlerRegistry programaticamente dentro de nossa classe de configuração de contexto da web.
3.1. Servindo um recurso armazenado no WAR
Para ilustrar isso, usaremos a mesma URL de antes para apontar paramyCss.css, mas agora o arquivo real estará localizado na pastawebapp/resources do WAR, que é onde os recursos estáticos devem ser colocados durante a implantação Aplicativos Spring 3.1+:
Exemplo 3.1.1.
@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/resources/**")
.addResourceLocations("/resources/");
}
}
Vamos analisar o exemplo de bit. Primeiro, configuramos o caminho externo do URI, adicionando a definição de um manipulador de recursos. Em seguida, mapeamos internamente esse caminho externo do URI, para o caminho físico em que os recursos estão realmente localizados.
É claro que podemos definir vários manipuladores de recursos usando essa API simples e flexível.
Agora - a seguinte linha em uma páginahtml nos forneceria o recursomyCss.css dentro do diretóriowebapp/resources:
" rel="stylesheet">
3.2. Servindo um recurso armazenado no sistema de arquivos
Digamos que queremos servir um recurso armazenado no diretório/opt/files/ sempre que uma solicitação chegar para a URL pública correspondente ao padrão:/files/**. Simplesmente configuramos o padrão de URL e o mapeamos para esse local específico no disco:
Exemplo 3.2.1.
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/files/**")
.addResourceLocations("file:/opt/files/");
}
* (Para usuários do Windows: O argumento passado paraaddResourceLocations para este exemplo seria “file:///C:/opt/files/“).
Depois de configurar a localização do recurso, podemos usar o padrão de URL mapeado em nossoshome.html aload an image stored in the file system da seguinte maneira:
Exemplo 3.2.2.
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
" rel="stylesheet">
Home
Hello world!
">
3.3. Configurando vários locais para um recurso
E se quisermos procurar um recurso em mais de um local?
Podemos incluir vários locais com o métodoaddResourceLocations. A lista de locais será pesquisada em ordem até que o recurso seja encontrado. Vamos dar uma olhada no Exemplo 3.3.1.
Exemplo 3.3.1
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/resources/**")
.addResourceLocations("/resources/","classpath:/other-resources/");
}
A seguinte solicitação curl exibirá a páginaHello.html armazenada na pastawebappp/resources do aplicativo ou na pastaother-resources no classpath.
curl -i http://localhost:8080/handling-spring-static-resources/resources/Hello.html
4. O novoResourceResolvers
Primavera 4.1. fornece - com o novoResourcesResolvers - diferentes tipos de resolvedores de recursos que podem ser usados para otimizar o desempenho do navegador ao carregar recursos estáticos. Esses resolvedores podem ser encadeados e armazenados em cache no navegador para otimizar o tratamento de solicitações.
4.1. OPathResourceResolver
Esse é o resolvedor mais simples e seu objetivo é encontrar um recurso com um padrão de URL público. Na verdade, se nenhumResourceResolver for adicionado aResourceChainRegistration, este é o resolvedor padrão.
Vamos ver um exemplo:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/resources/**")
.addResourceLocations("/resources/","/other-resources/")
.setCachePeriod(3600)
.resourceChain(true)
.addResolver(new PathResourceResolver());
}
Coisas a serem observadas:
-
Estamos registrandoPathResourceResolver na cadeia de recursos como os únicosResourceResolver nela. Veja a seção 4.3. para verificar como encadear mais de umResourceResolver.
-
Os recursos servidos serão armazenados em cache no navegador por 3600 segundos.
-
A cadeia é finalmente configurada com o métodoresourceChain(true).
Agora - o código html que, em conjunto comPathResourceResolver, localiza o scriptfoo.js emwebapp/resources da pastawebapp/other-resources:
">
4.2. OEncodedResourceResolver
Este resolvedor tenta encontrar um recurso codificado com base no valor do cabeçalho da solicitaçãoAccept-Encoding.
Por exemplo, podemos precisar otimizar a largura de banda servindo a versão compactada de um recurso estático usando a codificação de conteúdogzip.
Para configurar umEncodedResourceResolver,, só precisamos configurá-lo emResourceChain da mesma forma que configuramosPathResourceResolver, como na seguinte linha de código:
registry
.addResourceHandler("/other-files/**")
.addResourceLocations("file:/Users/Me/")
.setCachePeriod(3600)
.resourceChain(true)
.addResolver(new EncodedResourceResolver());
Por padrão,EncodedResourceResolver é configurado para suportar as codificaçõesbregzip.
Portanto, a seguinte solicitaçãocurl obterá a versão compactada do arquivoHome.html localizado no sistema de arquivos no diretórioUsers/Me/:
curl -H "Accept-Encoding:gzip"
http://localhost:8080/handling-spring-static-resources/other-files/Hello.html
Observe comowe are setting the header’s “Accept-Encoding” value to gzip - isso é importante porque este resolvedor em particular só iniciará se o conteúdo gzip for válido para a resposta.
Por fim, observe que, da mesma forma que antes, a versão compactada permanecerá disponível pelo período em que for armazenada em cache no navegador - que neste caso é de 3600 segundos.
4.3. EncadeandoResourceResolvers
Para otimizar a pesquisa de recursos,ResourceResolvers pode delegar a manipulação de recursos a outros resolvedores. O único resolvedor que não pode delegar para a cadeia é oPathResourceResolver, que deve ser adicionado no final da cadeia.
Na verdade, seresourceChain não for definido comotrue, então, por padrão, apenasPathResourceResolver será usado para servir aos recursos. No exemplo 4.3.1. estamos encadeandoPathResourceResolver para resolver o recurso seGzipResourceResolver não tiver êxito.
Exemplo 4.3.1.
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/js/**")
.addResourceLocations("/js/")
.setCachePeriod(3600)
.resourceChain(true)
.addResolver(new GzipResourceResolver())
.addResolver(new PathResourceResolver());
}
Agora que adicionamos o padrão/js/** aoResourceHandler, vamos incluir o recursofoo.js localizado no diretóriowebapp/js/ em nossa páginahome.html como no Exemplo 4.3 .2.
Exemplo 4.3.2
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
" rel="stylesheet" />
">
Home
This is Home!
" />
5. Configuração de segurança adicional
Se estiver usando Spring Security - é importante permitir o acesso aos recursos estáticos. Precisamos adicionar as permissões correspondentes para acessar o URL do recurso:
6. Conclusão
Neste artigo, ilustramos várias maneiras pelas quais os recursos estáticos podem ser atendidos em um aplicativo Spring.
A configuração de recurso baseada em XML éa “legacy” option, que pode ser usada se você ainda não puder seguir a rota de configuração do java.
Spring 3.1. came out with uma alternativa programática básica por meio de seu objetoResourceHandlerRegistry.
E finalmente - o novoResourceResolverseResourceChainRegistration objetoshipped with Spring 4.1 pronto para uso. oferecem recursos de otimização de carregamento de recursos, como armazenamento em cache e encadeamento de manipulador de recursos, para melhorar a eficiência no atendimento a recursos estáticos.
Como sempre, o exemplo completo está disponívelover on Github.