Mercurial > pub > Impl
comparison Lib/IMPL/Web/Application/Action.pm @ 206:c8fe3f84feba
+IMPL::Web::Handlers::ViewSelector
+IMPL::Web::Handlers::ErrorHandler
*IMPL::Web::Handlers::RestController moved types mappings to ViewSelector
| author | sergey |
|---|---|
| date | Thu, 03 May 2012 16:48:39 +0400 |
| parents | 4d0e1962161c |
| children | 47f77e6409f7 |
comparison
equal
deleted
inserted
replaced
| 205:891c04080658 | 206:c8fe3f84feba |
|---|---|
| 4 use parent qw(IMPL::Object IMPL::Object::Autofill); | 4 use parent qw(IMPL::Object IMPL::Object::Autofill); |
| 5 | 5 |
| 6 __PACKAGE__->PassThroughArgs; | 6 __PACKAGE__->PassThroughArgs; |
| 7 | 7 |
| 8 use IMPL::Class::Property; | 8 use IMPL::Class::Property; |
| 9 use Carp qw(carp); | |
| 9 | 10 |
| 10 BEGIN { | 11 BEGIN { |
| 11 public property application => prop_get | owner_set; | 12 public property application => prop_get | owner_set; |
| 12 public property query => prop_get | owner_set; | 13 public property query => prop_get | owner_set; |
| 13 public property response => prop_get | owner_set; | 14 public property response => prop_get | owner_set; |
| 43 $this->response($this->responseFactory->new(query => $this->query)); | 44 $this->response($this->responseFactory->new(query => $this->query)); |
| 44 } | 45 } |
| 45 | 46 |
| 46 sub ChainHandler { | 47 sub ChainHandler { |
| 47 my ($this,$handler) = @_; | 48 my ($this,$handler) = @_; |
| 49 | |
| 50 carp "deprecated, use Application->handlers instead"; | |
| 48 | 51 |
| 49 my $delegateNext = $this->_entryPoint(); | 52 my $delegateNext = $this->_entryPoint(); |
| 50 | 53 |
| 51 if (ref $handler eq 'CODE') { | 54 if (ref $handler eq 'CODE') { |
| 52 $this->_entryPoint( sub { | 55 $this->_entryPoint( sub { |
| 123 C<IMPL::Web::Application::Action> - Обертка вокруг C<CGI> запроса. | 126 C<IMPL::Web::Application::Action> - Обертка вокруг C<CGI> запроса. |
| 124 | 127 |
| 125 =head1 DESCRIPTION | 128 =head1 DESCRIPTION |
| 126 | 129 |
| 127 C<[Infrastructure]> | 130 C<[Infrastructure]> |
| 128 | 131 Свзяывет CGI запрос, приложение, орабатывающее его и ответ, который будет отправлен клиенту. |
| 129 Определяет порядок выполнения запроса. Запрос выполняется последовательным вызовом | |
| 130 цепочки обработчиков, при этом обработчики сами вызывают следующие. | |
| 131 Обработчики выполняются в порядке, обратном их добавлению. | |
| 132 | |
| 133 Типичная цепочка может быть такой, в порядке добавления | |
| 134 | |
| 135 =begin code | |
| 136 | |
| 137 IMPL::Web::QueryHandler::SecCallToMethod | |
| 138 IMPL::Web::QueryHandler::AuthenticateCookie | |
| 139 IMPL::Web::QueryHandler::PageFormat | |
| 140 | |
| 141 =end code | |
| 142 | |
| 143 что приведет к следующей последовательности | |
| 144 | |
| 145 =begin code | |
| 146 | |
| 147 # the application creates a new Action object | |
| 148 | |
| 149 my $action = $application->actionFactory->new( | |
| 150 action => $application, # the application passes self | |
| 151 query => $query # current CGI query | |
| 152 ); | |
| 153 | |
| 154 # forms query handlers stack | |
| 155 | |
| 156 $action->ChainHandler($_) foreach qw ( | |
| 157 IMPL::Web::QueryHandler::SecCallToMethod | |
| 158 IMPL::Web::QueryHandler::AuthenticateCookie | |
| 159 IMPL::Web::QueryHandler::PageFormat | |
| 160 ); | |
| 161 | |
| 162 # and finally invokes the action | |
| 163 | |
| 164 $action->Invoke() { | |
| 165 | |
| 166 # some internals | |
| 167 | |
| 168 IMPL::Web::QueryHandler::PageFormat->Invoke($action,$nextHandlerIsAuthHandler) { | |
| 169 | |
| 170 #some internals | |
| 171 | |
| 172 my $result = $nextHandlerIsAuthHandler() { | |
| 173 | |
| 174 # some internals | |
| 175 | |
| 176 IMPL::Web::QueryHandler::AuthenticateCookie->Invoke($action,$nextHandlerIsSecCall) { | |
| 177 | |
| 178 # some internals | |
| 179 # do auth and generate security $context | |
| 180 | |
| 181 # impersonate $context and call the next handler | |
| 182 return $context->Impersonate($nextHandlerIsSecCall) { | |
| 183 | |
| 184 # some internals | |
| 185 | |
| 186 IMPL::Web::QueryHandler::SecCallToMethod->Invoke($action,undef) { | |
| 187 | |
| 188 # next handler isn't present as it is the last hanler | |
| 189 | |
| 190 # some internals | |
| 191 # calculate the $method and the $target from CGI request | |
| 192 | |
| 193 IMPL::Security->AccessCheck($target,$method); | |
| 194 return $target->$method(); | |
| 195 | |
| 196 } | |
| 197 | |
| 198 } | |
| 199 | |
| 200 } | |
| 201 } | |
| 202 | |
| 203 # some intenals | |
| 204 # formatted output to $action->response->streamBody | |
| 205 } | |
| 206 } | |
| 207 | |
| 208 =end code | |
| 209 | |
| 210 или как альтернатива может быть еще | |
| 211 | |
| 212 =begin code | |
| 213 | |
| 214 IMPL::Web::QueryHandler::SecCallToMethod | |
| 215 IMPL::Web::QueryHandler::AuthenticateCookie | |
| 216 IMPL::Web::QueryHandler::Filter->new( target => IMPL::Transform::ObjectToJSON->new() , method => 'Transform') | |
| 217 IMLP::Web::QueryHandler::JSONFormat | |
| 218 | |
| 219 | |
| 220 =end code | |
| 221 | |
| 222 В данной цепочке также происходит вызов метода, но его результат потом преобразуется | |
| 223 в простые структуры и передается JSON преобразователю. Таким образом модулю логики | |
| 224 не требуется знать о выходном формате, всю работу проделают дополнительные фильтры. | |
| 225 | 132 |
| 226 =head1 MEMBERS | 133 =head1 MEMBERS |
| 227 | 134 |
| 228 =head2 PROPERTIES | 135 =head2 PROPERTIES |
| 229 | 136 |
| 262 Данная операция обычно проводится при обработке ошибок, когда | 169 Данная операция обычно проводится при обработке ошибок, когда |
| 263 уже сформированный ответ требуется отменить. Следует заметить, | 170 уже сформированный ответ требуется отменить. Следует заметить, |
| 264 что эта операция не возможна, если ответ частично или полностью | 171 что эта операция не возможна, если ответ частично или полностью |
| 265 отправлен клиенту. Тогда возникает исключение C<IMPL::InvalidOperationException>. | 172 отправлен клиенту. Тогда возникает исключение C<IMPL::InvalidOperationException>. |
| 266 | 173 |
| 267 =item C< ChainHandler($handler) > | |
| 268 | |
| 269 Добавляет новый обработчик в цепочку. Выполнение цепочки начинается с конца, | |
| 270 тоесть последний добавленный будет выполнен первым. | |
| 271 | |
| 272 =back | |
| 273 | |
| 274 =head1 HANDLERS | |
| 275 | |
| 276 =head2 subroutines | |
| 277 | |
| 278 =over | |
| 279 | |
| 280 =item CODE ref | |
| 281 | |
| 282 Ссылка на процедуру может являться обработчиком, при этом функция будет вызвана с | |
| 283 двумя параметрами: ссылкой на action объект, и точкой входа следующего обработчика. | |
| 284 | |
| 285 =item Method Name | |
| 286 | |
| 287 Имя метода, передается в виде строки. У текущего объекта action ищется метод с | |
| 288 указанным именем, после чего используется ссылка на этот метод для вызова с двумя | |
| 289 параметрами: ссылкой на action объект, и точкой входа следующего обработчика. | |
| 290 | |
| 291 Получается вызов идентичный следующему C<< $action->MethodName($nextHandler) >>; | |
| 292 | |
| 293 =back | |
| 294 | |
| 295 =head2 C< IMPL::Web::QueryHandler > | |
| 296 | |
| 297 Любой объект наследованный от C< IMPL::Web::QueryHandler > может быть | |
| 298 использован в качестве обработчика запроса | |
| 299 | |
| 300 =cut | 174 =cut |
