Struts 2 - Понимание работы между OGNL и params interceptor
Я новичок в Struts 2. Я изучаю его из книги Struts2 In Action. У меня возникают трудности в понимании некоторых понятий в OGNL, которые заключаются в следующем:
Мы знаем это
params
Перехватчик перемещает данные из параметров запроса в объект действия вValueStack
, Теперь, читая, я натолкнулся на строку, которая гласит: "Сложная часть работы заключается в сопоставлении имени параметра с фактическим свойством вValueStack
, Вот где приходит OGNL.params
Перехватчик интерпретирует имя параметра запроса как выражение OGNL, чтобы найти правильное свойство назначения в ValueStack".Вопрос 1) Здесь, что означает "интерпретирует"? Является ли это тем, что params interceptor переводит параметр запроса в некоторое выражение OGNL, а затем выражение OGNL обеспечивает сопоставление со свойствами в ValueStack ИЛИ это означает что-то еще?
Когда результат начинает процесс рендеринга, теги Struts 2 извлекают данные из ValueStack, ссылаясь на конкретные значения с помощью выражений OGNL.
Вопрос 2) Итак, теги принимают выражения OGNL, но как перемещаются данные? Ранее,
params
перехватчик был тем, кто переместил данные, но теперь нетparams
перехватчик. Итак, как перемещаются данные?
3 ответа
Ответ № 1
Имена параметров являются выражениями OGNL. Это случай ConventionOverConfiguraiton. Если мы согласимся сделать имена параметров допустимыми выражениями OGNL, которые могут обращаться к свойству javabeans, то легко передать это имя OGNL в качестве выражения. Это делается внутренне, конечно; вам действительно не нужно знать, как это работает, если вы не взламываете эту часть кода Struts 2.
Ответ № 2
Объект действия находится сверху ValueStack. ValueStack доступен через его существование как часть ThreadLocal ActionContext из любого кода, выполняющегося в том же потоке. Поскольку веб-приложение использует один поток для обработки запроса, мы знаем, что слой Result сможет получить доступ к ValueStack для извлечения данных, снова используя имя в теге в качестве выражения OGNL.
Замечания:
Ключевой частью всего этого является тот факт, что ValueStack доступен для любого кода, выполняющегося в том же потоке. Это позволяет всему коду, обрабатывающему один запрос, иметь доступ к ValueStack, который они могут получить через ThreadLocal ActionContext (читайте о Java-классе ThreadLocal, если вы не понимаете).
Перехватчик параметров может затем попытаться использовать имя параметра в качестве выражения OGNL для записи данных в ValueStack (какие серверы являются контекстом OGNL - еще раз прочитайте об API OGNL, если вы не понимаете). Затем код в классах Result, которые обрабатывают рендеринг ответа, может интерпретировать различные имена и значения из библиотек тегов как выражения OGNL для чтения данных из ValueStack.
Допустим, вы пишете страницу входа и соответствующее действие входа. На странице у вас есть текстовое поле с именем, которое говорит, что это поле имени объекта User. У вас также есть поле пароля на странице, которое говорит, что оно сопоставляется с полем pwd на объекте User.
Теперь объектный граф будет означать, что он должен сообщить перехватчику params, что поле имени на самом деле является полем имени пользовательского объекта в действии входа в систему. Контекст действия, valuestack и OGNL будут вместе знать, что: Ну, может быть, есть и другие действия, такие как FileUploadAction. И эти другие действия также могут иметь ссылку на объект пользователя. Но для текущего контекста действия поле имени со страницы входа в систему на самом деле отображается только в поле имени объекта пользователя действия входа. Он не принадлежит полю имени пользовательского объекта FileUploadAction. Они обладают этими знаниями, а также ведут себя так, как будто само поле (фактически весь граф объектов) находится в стеке значений и является непосредственно доступным. (Небольшая предыстория на ThreadLocal будет лучше понять это.)
Перехватчики скованы цепью, и это становится цепью ответственности на пути вперед и назад. Перехватчик может выполнять какое-либо действие - прямое направление или обратное направление, или оба. Итак, давайте скажем, что поток как показано ниже:
Page 1-->Interceptor_1--> Interceptor_2 --> Interceptor_3 -->Action_1
Тогда обратный поток будет выглядеть так:
Action_1 --> Interceptor_3 --> Interceptor_2 --> Interceptor_1 --> The result Page
Поэтому, чтобы ответить на ваш вопрос, в обратном потоке будет вызван params inteceptor.
На самом деле имя параметра оценивается как выражение OGNL с использованием контекста OGNL, где ValueStack
является корневым объектом. Здесь вы можете найти полезную информацию о OGNL в XWork. На ваш вопрос: отображение означает, что в контексте, возвращаемом OGNL после оценки выражения, не существует нулевой ссылки. Таким образом, само выражение является ключом в абстрактной карте, которая является контекстом OGNL.
JSP визуализируются на стороне сервера, поэтому нет необходимости перемещать данные на клиент. Но выражения OGNL оцениваются тегами Struts, а значения копируются в виде строк, если значения записываются в ответ или используют ту же ссылку на объект с помощью ключа, используемого в качестве выражения OGNL. Также вы можете создать новый ключ или поместить объект на вершину стека значений.