#apache #tomcat #struts2 #mod-jk #sitemesh
#apache #tomcat #struts2 #mod-jk #sitemesh
Вопрос:
В моем приложении Java / Struts2 / Tomcat при запросе некоторых ресурсов, которые генерируют ответ «304 Not Modified», файл все еще отправляется в ответе.
Это пример ответа, полученный с помощью Fiddler:
HTTP/1.1 304 Not Modified
Date: Thu, 26 Jun 2014 11:27:27 GMT
Server: Apache/2.2.16 (Ubuntu)
Connection: Keep-Alive
Keep-Alive: timeout=15, max=100
Vary: Accept-Encoding
/*! jQuery v1.7.2 jquery.com | jquery.org/license */
(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?
a.defaultView||a.parentWindow:!1}function cu(a){if(!cj[a]){var b=c.body,d=f("
<" a ">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ck||
[...]
Это проблема, потому что содержимое возвращенного файла вставляется в следующий запрошенный файл, что приводит к повреждению и странному поведению.
Это происходит только для ресурсов, загруженных из пути «/ struts», например:
/struts/utils.js
/struts/js/base/jquery-1.10.2.min.js
/struts/js/base/jquery.ui.core.min.js?s2j=3.7.0
Путь «/struts» обрабатывается классом struts2
org.apache.struts2.dispatcher.DefaultStaticContentLoader
Это соответствующие элементы системы:
- Ubuntu 12.04.4 LTS (GNU / Linux 3.5.0-27-generic x86_64)
- JVM 1.6.0_31-b31 Sun Microsystems Inc. (также проверено с ibm-java-x86_64-71)
- Apache2 2.2.22-1ubuntu1.6 с modjk
- Apache Tomcat / 6.0.35
- Struts 2.3.16
- Sitemesh 3.0.0
При подключении напрямую к tomcat я не получаю никаких неожиданных данных после заголовка Not Modified.
Конфигурация сервера Apache не претерпела значительных изменений, только псевдоним для /contents и две директивы modjk:
JkMount /* ajp13_worker
JkUnMount /contents/* ajp13_worker
Нет ничего, связанного с / struts или кэшированием, или чем-то экзотическим. Конфигурация ModJK — это настройки по умолчанию.
Есть предложения?
Комментарии:
1. Используете ли вы сервер apache перед tomcat? Если на локальном компьютере приложение работает, то, вероятно, это проблема с конфигурацией сервера.
2. Да, я использую apache при удаленной установке. Спасибо, что указали на это. Я обновлю вопрос.
3. Также измените свой экземпляр JVM, версия, которую вы используете, содержит много ошибок, настоятельно рекомендую запустить службу автоматического обновления на вашем компьютере.
4. Версия Java не имеет никакого значения. Я запустил tomcat с IBM java7 «ibm-java-x86_64-71» (pxa6470_27-20131115_04, как сообщает Tomcat Manager), и проблема сохраняется.
Ответ №1:
Это ответ, который не решает проблему, но открывает новые вопросы.
Повреждение ответа происходит при использовании sitemesh3 за сервером apache. Если я обращаюсь к серверу tomcat напрямую, ответом будет чистый 304. Если я получаю доступ через modjk / apache, ответ содержит неожиданные данные.
Причина неожиданных данных связана с тем, как работает sitemesh: при отправке ответа в какой-то момент он заставляет struts игнорировать любой заголовок «If-Modified-Since», записывая запрошенное содержимое в буфер ответов. Затем он продолжается, добавляя заголовки 304 также в начало буфера.
Для начала посмотрите
org.sitemesh.webapp.contentfilter.HttpServletRequestFilterable
org.apache.struts2.dispatcher.DefaultStaticContentLoader.process()
Я не знаю, куда идти дальше. Это ошибка? Это ошибка сервера Apache, ошибка Tomcat, ошибка Struts или ошибка Sitemesh ?!
Чтобы воспроизвести проблему, вам нужен tomcat за apache, запускающий веб-приложение struts с sitemesh в нем, и извлекающий этот URL дважды, пока fiddler2 активен:
http://[test.server.address]/struts/utils.js
Кусок пирога o_O ‘
Редактировать:
Если я проверю журнал modjk, я смогу четко увидеть файл, переданный обратно на сервер Apache:
: trying to connect socket 29 to 127.0.0.1:9009
: socket 29 [127.0.0.1:57195 -> 127.0.0.1:9009] connected
: sending to ajp13 pos=4 len=581 max=8192
.4.A....HTTP/1.1
.../struts/utils
.js...2.235.97.2
[...]
...Accept-Langua
ge..#en,en-US;q=
0.8,it-IT;q=0.6,
it;q=0.4.... JSE
SSIONID=B77369AB
D8239724A27A5CC5
6E06DED8...If-Mo
dified-Since...F
ri,.27.Jun.2014.
08:37:46.GMT....
.0....AJP_REMOTE
_PORT...19143...
.JK_LB_ACTIVATIO
N...............
: (rdp_worker) request body to send 0 - request body to resend 0
: received from ajp13 pos=0 len=20 max=8192
..0..Not.Modifie
d...............
: status = 304
: Number of headers is = 0
: received from ajp13 pos=0 len=4767 max=8192
.../*..*.$Id:.ut
ils.js.1240312.2
012-02-03.19:44:
51Z.jogep.$..*..
*.Licensed.to.th
e.Apache.Softwar
e.Foundation.(AS
F).under.one..*.
or.more.contribu
tor.license.agre
ements...See.the
[...]
the.ajaxValidati
on.interceptor.S
trutsUtils.getVa
lidationErrors.=
: ws_write::mod_jk.c (537): written 4763 out of 4763
: received from ajp13 pos=0 len=4 max=8192
................
: received from ajp13 pos=0 len=2 max=8192
................
: AJP13 protocol: Reuse is OK
Когда я обращаюсь к tomcat напрямую и сбрасываю TCP-трафик с помощью tcpflow, я не вижу никаких ложных данных:
# tcpflow -p -s -c host xxx.xxx.xxx.xxx and port 8080
xxx.xxx.xxx.xxx.19292-yyy.yyy.yyy.yyy.08080: GET /rdp/struts/utils.js HTTP/1.1
Host: xxx.net:8080
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en,en-US;q=0.8,it-IT;q=0.6,it;q=0.4
Cookie: JSESSIONID=B0F02CXXXEC3448F1B927C0E8C579A9B
If-Modified-Since: Fri, 27 Jun 2014 08:49:23 GMT
yyy.yyy.yyy.yyy.08080-xxx.xxx.xxx.xxx.19292: HTTP/1.1 304 Not Modified
Server: Apache-Coyote/1.1
Date: Fri, 27 Jun 2014 08:52:43 GMT
Таким образом, похоже, что при возврате буфера в порт ajp и возврате его в сетевой сокет поведение отличается. Это слишком низкий уровень для меня, чтобы продвинуться дальше.
Редактировать:
Обходной путь
Реализованный мной обходной путь состоит в том, чтобы позволить серверу Apache обрабатывать контекст /struts:
- извлеките из банок struts и struts-jquery-plugin все файлы, которые затронуты (содержимое org apache struts2 static и содержимое шаблона соответственно)
- скопируйте эти файлы в каталог на сервере
- создайте псевдоним в apache для обслуживания этого каталога при обнаружении пути /struts
- отмените отображение пути /struts из modJK
Комментарии:
1. Я открыл проблему на сайте Sitemesh3, чтобы мы могли объединить усилия: github.com/sitemesh/sitemesh3/issues/62