Автоматическая версия статического контента с JBoss - PullRequest
9 голосов
/ 13 апреля 2010

Что касается вопросов и ответов здесь , я бы хотел внедрить аналогичную систему автоматического управления версиями для веб-приложения, работающего в JBoss 5. Есть ли что-нибудь, что уже можно сделать, илимне нужно что-то самому написать?Для ясности: Я не использую PHP.

Не очень разбираясь в PHP, я не уверен, какие есть у Tomcat / JBoss аналоги PHP .htaccess и т. Д.Если бы мне пришлось написать свое собственное автоматическое управление версиями, с чего бы мне начать?Принцип для меня ясен - переписать URL, используя временную метку файла, но я мало что знаю о перезаписи URL с помощью JBoss / Tomcat.


Обновление:

Объединение подходоврекомендовано Pascal и новичком , вот что я закончил:

1. Пользовательские <my:script/> и <my:style/> теги, такМне бы не пришлось видеть теги <c:url/> повсюду.

<%@ tag body-content="empty" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ attribute name="src" required="true" rtexprvalue="true" %>
<script src="<c:url value="${src}" />"></script>

2. Следуя довольно близко к шагам новичка, но отображая UrlRewriteFilter в /* в web.xml:

<filter-mapping>
    <filter-name>UrlRewriteFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

3. Внедрение переменной CACHE_BUST в каждый новый сеанс (более или менее ...), развертывание приложения отметка времени:

// On application deploy:
long CACHE_BUST = System.currentTimeMillis() / 1000;

// later...
session.setAttribute("cacheBust", CACHE_BUST);

4. ... так что я могу использовать эти правила в urlrewrite.xml:

<outbound-rule>
    <from>^/static/(css|js|images)/(.*)$</from>
    <to>%{context-path}/static/%{session-attribute:cacheBust}/$1/$2</to>
</outbound-rule>

<rule>
    <from>^/static/\d{10}/(css|js|images)/(.*)$</from>
    <to>/static/$1/$2</to>
</rule>

Большое спасибо Pascal и новичок за помощь.

Ответы [ 3 ]

4 голосов
/ 15 сентября 2010

Следующее решение лучше подходит для производственной среды, поскольку вы будете увеличивать номер версии для каждого выпуска.

Подход:

  • добавить номер версии продукта (номер версии) к URL-адресам js / css / images / static в файлах jsp
  • браузер будет кэшировать (js / css / static) файлы с URL-адресом, содержащим номер версии
  • при выпуске новой версии файлы jsp будут иметь URL-адреса файлов js / css / static с новым номером версии, поэтому браузер выполнит вызов, так как не может найти содержимое для нового URL

Шаги:

  • включите urlrewritefilter.jar в путь к классу (получите его из http://www.tuckey.org/urlrewrite/)
  • обновить web.xml с помощью шаблона url, например,

    <filter>
        <filter-name>urlRewriteFilter</filter-name>
        <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
    </filter>
    
    <filter-mapping>
      <filter-name>urlRewriteFilter</filter-name>
      <url-pattern>/v/*</url-pattern>
    </filter-mapping>
    
  • обновить 'abc.js' в файле jsp, например,

    <html>
        <head>
            <script type="text/javascript" src="<c:url value="/v/js/abc.js"/>"></script>
        </head>
    </html>
    
  • напишите urlrewritefilter.xml, например,

    <outbound-rule>
        <from>^/v/(css|js|static)/(.*)$</from>
        <to>%{context-path}/v/updateVersionNumberHere/$1/$2</to>
    </outbound-rule>
    
    <rule>
        <from>^/v/updateVersionNumberHere/(css|js|static|images)/(.*)$</from>
        <to>/$1/$2</to>
    </rule>
    

    Пояснение:

    когда jsp подается клиенту

    • URL, упомянутый в jsp: /v/js/abc.js
    • после применения правила для исходящих сообщений: /contextPath/v/3.4.5/js/abc.js

    когда браузер вызывает файлы js / css / static

    • входящий URL: /contextPath/v/3.4.5/js/abc.js
    • после применения правила: /js/abc.js

Очки:

  • будет перехватывать js-файлы с помощью url /contextPath/v/3.4.5/js/abc.js, затем вы развертываете новую версию jsp-файлов, у которых может быть url /contextPath/v/4.5.6/js. /abc.js, поэтому браузер будет вызывать файл js вместо использования кэшированного файла js.
  • обновление версии может быть автоматизировано, если вы используете maven или аналогичный инструмент для сборки
3 голосов
/ 19 апреля 2010

Если вы не хотите загружать приложение с помощью Apache HTTPD, вы можете использовать пользовательский фильтр сервлета или повторно использовать существующий Url Rewrite Filter . Этот фильтр основан на mod_rewrite Apache и предлагает аналогичные возможности. Другими словами, это позволило бы реализовать то же решение, что и PHP другого ответа.


Я видел фильтр перезаписи URL раньше. Не могли бы вы рассказать, как бы я это использовал? Я действительно не совсем понимаю, как применить фильтр к этой проблеме, поскольку я бы не стал вызывать функцию JSP / JSTL, обернутую вокруг каждого включенного файла JS / CSS, и я понятия не имею, как получить дата изменена из файла, который находится в WAR.

Что ж, идея заключалась в том, чтобы имитировать именно «PHP-решение» ответа, с которым вы связались (давайте назовем этот вариант 1):

  1. Настройте фильтр перезаписи URL для перезаписи любого запроса, чтобы сказать /css/my.123456.css в /css/my.css
  2. Реализация Servlet, которая бы получала объект File для данного ресурса в WAR и вставила File#lastModified() в возвращенный путь к этому ресурсу.
  3. Вызовите Servlet из JSP для CSS.

Другой подход (вариант 2) заключается в добавлении уникальной строки запроса к URL-адресу статического содержимого, например время запуска сервера:

  1. Укажите время запуска сервера в области приложения от ServletContextListener (скажем, под ключом "key").
  2. В тебе JSP

    <link rel="stylesheet" type="text/css" href="/css/my.css?${key.startupTime}">
    

Pro: URL больше не переписывается. Против: Менее оптимальный (контент будет запрашиваться при перезапуске), но приемлемый.


При поиске в Интернете некоторого кода, который мог бы помочь реализовать шаг # 2 варианта 1, я обнаружил, что Spring o.s.w.s.ResourceServlet, который делает нечто подобное, вы можете посмотреть на его исходный код. Но, читая его Javadoc более внимательно, я понял, что этот сервлет на самом деле именно то, что вы ищете. Отобразите это так:

<servlet>
  <servlet-name>Resource Servlet</servlet-name>
  <servlet-class>org.springframework.web.servlet.ResourceServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
  <servlet-name>Resource Servlet</servlet-name>
  <url-pattern>/static/*</url-pattern>
</servlet-mapping>

И установите для его свойства applyLastModified значение true. Насколько я понимаю, Javadoc - это то, что нужно. Это вариант 3, и это IMO лучший вариант, если добавление зависимости от этого сервлета не является проблемой.

1 голос
/ 22 апреля 2010

В нашем веб-приложении мы делаем следующее:

  1. Процесс сборки извлекает номер хранилища Subversion и сохраняет его в свойстве в веб-приложении.
  2. В процессе сборки также создается структура каталогов для статических активов в WAR, которая включает этот номер редакции: /assets/1234/styles/...
  3. Фильтр / перехватчик помещает путь активов (включая номер редакции) во все запросы как атрибут
  4. Шаблоны Jsp используют этот атрибут пути к ресурсам для создания URL-адресов для активов
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...