1 16 17 package org.springframework.web.portlet; 18 19 import java.io.IOException ; 20 import java.util.ArrayList ; 21 import java.util.Collections ; 22 import java.util.Iterator ; 23 import java.util.List ; 24 import java.util.Map ; 25 import java.util.Properties ; 26 27 import javax.portlet.ActionRequest; 28 import javax.portlet.ActionResponse; 29 import javax.portlet.PortletException; 30 import javax.portlet.PortletRequest; 31 import javax.portlet.PortletResponse; 32 import javax.portlet.PortletSession; 33 import javax.portlet.RenderRequest; 34 import javax.portlet.RenderResponse; 35 import javax.portlet.UnavailableException; 36 37 import org.apache.commons.logging.Log; 38 import org.apache.commons.logging.LogFactory; 39 40 import org.springframework.beans.BeansException; 41 import org.springframework.beans.factory.BeanFactoryUtils; 42 import org.springframework.beans.factory.BeanInitializationException; 43 import org.springframework.beans.factory.NoSuchBeanDefinitionException; 44 import org.springframework.beans.factory.config.AutowireCapableBeanFactory; 45 import org.springframework.context.i18n.LocaleContext; 46 import org.springframework.context.i18n.LocaleContextHolder; 47 import org.springframework.context.i18n.SimpleLocaleContext; 48 import org.springframework.core.OrderComparator; 49 import org.springframework.core.io.ClassPathResource; 50 import org.springframework.core.io.support.PropertiesLoaderUtils; 51 import org.springframework.util.ClassUtils; 52 import org.springframework.util.StringUtils; 53 import org.springframework.web.context.request.RequestAttributes; 54 import org.springframework.web.context.request.RequestContextHolder; 55 import org.springframework.web.multipart.MultipartException; 56 import org.springframework.web.portlet.context.PortletRequestAttributes; 57 import org.springframework.web.portlet.multipart.MultipartActionRequest; 58 import org.springframework.web.portlet.multipart.PortletMultipartResolver; 59 import org.springframework.web.servlet.View; 60 import org.springframework.web.servlet.ViewRendererServlet; 61 import org.springframework.web.servlet.ViewResolver; 62 63 125 public class DispatcherPortlet extends FrameworkPortlet { 126 127 130 public static final String MULTIPART_RESOLVER_BEAN_NAME = "portletMultipartResolver"; 131 132 137 public static final String HANDLER_MAPPING_BEAN_NAME = "handlerMapping"; 138 139 144 public static final String HANDLER_ADAPTER_BEAN_NAME = "handlerAdapter"; 145 146 151 public static final String HANDLER_EXCEPTION_RESOLVER_BEAN_NAME = "handlerExceptionResolver"; 152 153 156 public static final String VIEW_RESOLVER_BEAN_NAME = "viewResolver"; 157 158 163 public static final String DEFAULT_VIEW_RENDERER_URL = "/WEB-INF/servlet/view"; 164 165 169 public static final String HANDLER_EXECUTION_CHAIN_ATTRIBUTE = 170 DispatcherPortlet.class.getName() + ".HANDLER"; 171 172 186 public static final String ACTION_EXCEPTION_SESSION_ATTRIBUTE = 187 DispatcherPortlet.class.getName() + ".ACTION_EXCEPTION"; 188 189 193 public static final String ACTION_EXCEPTION_RENDER_PARAMETER = "actionException"; 194 195 198 public static final String PAGE_NOT_FOUND_LOG_CATEGORY = "org.springframework.web.portlet.PageNotFound"; 199 200 204 private static final String DEFAULT_STRATEGIES_PATH = "DispatcherPortlet.properties"; 205 206 207 210 protected static final Log pageNotFoundLogger = LogFactory.getLog(PAGE_NOT_FOUND_LOG_CATEGORY); 211 212 private static final Properties defaultStrategies; 213 214 static { 215 try { 219 ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherPortlet.class); 220 defaultStrategies = PropertiesLoaderUtils.loadProperties(resource); 221 } 222 catch (IOException ex) { 223 throw new IllegalStateException ("Could not load 'DispatcherPortlet.properties': " + ex.getMessage()); 224 } 225 } 226 227 228 229 private boolean detectAllHandlerMappings = true; 230 231 232 private boolean detectAllHandlerAdapters = true; 233 234 235 private boolean detectAllHandlerExceptionResolvers = true; 236 237 238 private boolean detectAllViewResolvers = true; 239 240 241 private String viewRendererUrl = DEFAULT_VIEW_RENDERER_URL; 242 243 244 private boolean threadContextInheritable = false; 245 246 247 248 private PortletMultipartResolver multipartResolver; 249 250 251 private List handlerMappings; 252 253 254 private List handlerAdapters; 255 256 257 private List handlerExceptionResolvers; 258 259 260 private List viewResolvers; 261 262 263 270 public void setDetectAllHandlerMappings(boolean detectAllHandlerMappings) { 271 this.detectAllHandlerMappings = detectAllHandlerMappings; 272 } 273 274 281 public void setDetectAllHandlerAdapters(boolean detectAllHandlerAdapters) { 282 this.detectAllHandlerAdapters = detectAllHandlerAdapters; 283 } 284 285 292 public void setDetectAllHandlerExceptionResolvers(boolean detectAllHandlerExceptionResolvers) { 293 this.detectAllHandlerExceptionResolvers = detectAllHandlerExceptionResolvers; 294 } 295 296 303 public void setDetectAllViewResolvers(boolean detectAllViewResolvers) { 304 this.detectAllViewResolvers = detectAllViewResolvers; 305 } 306 307 311 public void setViewRendererUrl(String viewRendererUrl) { 312 this.viewRendererUrl = viewRendererUrl; 313 } 314 315 327 public void setThreadContextInheritable(boolean threadContextInheritable) { 328 this.threadContextInheritable = threadContextInheritable; 329 } 330 331 332 338 protected void initFrameworkPortlet() throws PortletException, BeansException { 339 initMultipartResolver(); 340 initHandlerMappings(); 341 initHandlerAdapters(); 342 initHandlerExceptionResolvers(); 343 initViewResolvers(); 344 } 345 346 351 private void initMultipartResolver() { 352 try { 353 this.multipartResolver = (PortletMultipartResolver) 354 getPortletApplicationContext().getBean(MULTIPART_RESOLVER_BEAN_NAME, PortletMultipartResolver.class); 355 if (logger.isInfoEnabled()) { 356 logger.info("Using MultipartResolver [" + this.multipartResolver + "]"); 357 } 358 } 359 catch (NoSuchBeanDefinitionException ex) { 360 this.multipartResolver = null; 362 if (logger.isInfoEnabled()) { 363 logger.info("Unable to locate PortletMultipartResolver with name '" + MULTIPART_RESOLVER_BEAN_NAME + 364 "': no multipart request handling provided"); 365 } 366 } 367 } 368 369 374 private void initHandlerMappings() { 375 if (this.detectAllHandlerMappings) { 376 Map matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors( 379 getPortletApplicationContext(), HandlerMapping.class, true, false); 380 if (!matchingBeans.isEmpty()) { 381 this.handlerMappings = new ArrayList (matchingBeans.values()); 382 Collections.sort(this.handlerMappings, new OrderComparator()); 384 } 385 } 386 else { 387 try { 388 Object hm = getPortletApplicationContext().getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class); 389 this.handlerMappings = Collections.singletonList(hm); 390 } 391 catch (NoSuchBeanDefinitionException ex) { 392 } 394 } 395 396 if (this.handlerMappings == null) { 399 this.handlerMappings = getDefaultStrategies(HandlerMapping.class); 400 if (logger.isInfoEnabled()) { 401 logger.info("No HandlerMappings found in portlet '" + getPortletName() + "': using default"); 402 } 403 } 404 } 405 406 411 private void initHandlerAdapters() { 412 if (this.detectAllHandlerAdapters) { 413 Map matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors( 416 getPortletApplicationContext(), HandlerAdapter.class, true, false); 417 if (!matchingBeans.isEmpty()) { 418 this.handlerAdapters = new ArrayList (matchingBeans.values()); 419 Collections.sort(this.handlerAdapters, new OrderComparator()); 421 } 422 } 423 else { 424 try { 425 Object ha = getPortletApplicationContext().getBean(HANDLER_ADAPTER_BEAN_NAME, HandlerAdapter.class); 426 this.handlerAdapters = Collections.singletonList(ha); 427 } 428 catch (NoSuchBeanDefinitionException ex) { 429 } 431 } 432 433 if (this.handlerAdapters == null) { 436 this.handlerAdapters = getDefaultStrategies(HandlerAdapter.class); 437 if (logger.isInfoEnabled()) { 438 logger.info("No HandlerAdapters found in portlet '" + getPortletName() + "': using default"); 439 } 440 } 441 } 442 443 448 private void initHandlerExceptionResolvers() { 449 if (this.detectAllHandlerExceptionResolvers) { 450 Map matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors( 453 getPortletApplicationContext(), HandlerExceptionResolver.class, true, false); 454 this.handlerExceptionResolvers = new ArrayList (matchingBeans.values()); 455 Collections.sort(this.handlerExceptionResolvers, new OrderComparator()); 457 } 458 else { 459 try { 460 Object her = getPortletApplicationContext().getBean( 461 HANDLER_EXCEPTION_RESOLVER_BEAN_NAME, HandlerExceptionResolver.class); 462 this.handlerExceptionResolvers = Collections.singletonList(her); 463 } 464 catch (NoSuchBeanDefinitionException ex) { 465 this.handlerExceptionResolvers = getDefaultStrategies(HandlerExceptionResolver.class); 467 } 468 } 469 } 470 471 476 private void initViewResolvers() { 477 if (this.detectAllViewResolvers) { 478 Map matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors( 481 getPortletApplicationContext(), ViewResolver.class, true, false); 482 if (!matchingBeans.isEmpty()) { 483 this.viewResolvers = new ArrayList (matchingBeans.values()); 484 Collections.sort(this.viewResolvers, new OrderComparator()); 486 } 487 } 488 else { 489 try { 490 Object vr = getPortletApplicationContext().getBean(VIEW_RESOLVER_BEAN_NAME, ViewResolver.class); 491 this.viewResolvers = Collections.singletonList(vr); 492 } 493 catch (NoSuchBeanDefinitionException ex) { 494 } 496 } 497 498 if (this.viewResolvers == null) { 501 this.viewResolvers = getDefaultStrategies(ViewResolver.class); 502 if (logger.isInfoEnabled()) { 503 logger.info("No ViewResolvers found in portlet '" + getPortletName() + "': using default"); 504 } 505 } 506 } 507 508 509 518 protected Object getDefaultStrategy(Class strategyInterface) throws BeansException { 519 List strategies = getDefaultStrategies(strategyInterface); 520 if (strategies.size() != 1) { 521 throw new BeanInitializationException( 522 "DispatcherPortlet needs exactly 1 strategy for interface [" + strategyInterface.getName() + "]"); 523 } 524 return strategies.get(0); 525 } 526 527 537 protected List getDefaultStrategies(Class strategyInterface) throws BeansException { 538 String key = strategyInterface.getName(); 539 List strategies = null; 540 String value = defaultStrategies.getProperty(key); 541 if (value != null) { 542 String [] classNames = StringUtils.commaDelimitedListToStringArray(value); 543 strategies = new ArrayList (classNames.length); 544 for (int i = 0; i < classNames.length; i++) { 545 String className = classNames[i]; 546 try { 547 Class clazz = ClassUtils.forName(className, getClass().getClassLoader()); 548 Object strategy = createDefaultStrategy(clazz); 549 strategies.add(strategy); 550 } 551 catch (ClassNotFoundException ex) { 552 throw new BeanInitializationException( 553 "Could not find DispatcherPortlet's default strategy class [" + className + 554 "] for interface [" + key + "]", ex); 555 } 556 catch (LinkageError err) { 557 throw new BeanInitializationException( 558 "Error loading DispatcherPortlet's default strategy class [" + className + 559 "] for interface [" + key + "]: problem with class file or dependent class", err); 560 } 561 } 562 } 563 else { 564 strategies = Collections.EMPTY_LIST; 565 } 566 return strategies; 567 } 568 569 579 protected Object createDefaultStrategy(Class clazz) throws BeansException { 580 return getPortletApplicationContext().getAutowireCapableBeanFactory().createBean( 581 clazz, AutowireCapableBeanFactory.AUTOWIRE_NO, false); 582 } 583 584 585 594 protected void doActionService(ActionRequest request, ActionResponse response) throws Exception { 595 if (logger.isDebugEnabled()) { 596 logger.debug("DispatcherPortlet with name '" + getPortletName() + "' received action request"); 597 } 598 599 LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext(); 601 LocaleContextHolder.setLocaleContext(buildLocaleContext(request), this.threadContextInheritable); 602 603 RequestAttributes previousRequestAttributes = RequestContextHolder.getRequestAttributes(); 605 PortletRequestAttributes requestAttributes = new PortletRequestAttributes(request); 606 RequestContextHolder.setRequestAttributes(requestAttributes, this.threadContextInheritable); 607 608 if (logger.isDebugEnabled()) { 609 logger.debug("Bound action request context to thread: " + request); 610 } 611 612 ActionRequest processedRequest = request; 613 HandlerExecutionChain mappedHandler = null; 614 int interceptorIndex = -1; 615 616 try { 617 processedRequest = checkMultipart(request); 618 619 mappedHandler = getHandler(processedRequest, false); 621 if (mappedHandler == null || mappedHandler.getHandler() == null) { 622 noHandlerFound(processedRequest, response); 623 return; 624 } 625 626 if (mappedHandler.getInterceptors() != null) { 628 for (int i = 0; i < mappedHandler.getInterceptors().length; i++) { 629 HandlerInterceptor interceptor = mappedHandler.getInterceptors()[i]; 630 if (!interceptor.preHandleAction(processedRequest, response, mappedHandler.getHandler())) { 631 triggerAfterActionCompletion(mappedHandler, interceptorIndex, processedRequest, response, null); 632 return; 633 } 634 interceptorIndex = i; 635 } 636 } 637 638 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); 640 ha.handleAction(processedRequest, response, mappedHandler.getHandler()); 641 642 triggerAfterActionCompletion(mappedHandler, interceptorIndex, processedRequest, response, null); 644 } 645 646 catch (Exception ex) { 647 triggerAfterActionCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex); 649 logger.debug("Caught exception during action phase - forwarding to render phase", ex); 651 PortletSession session = request.getPortletSession(); 652 session.setAttribute(ACTION_EXCEPTION_SESSION_ATTRIBUTE, ex); 653 response.setRenderParameter(ACTION_EXCEPTION_RENDER_PARAMETER, ex.toString()); 654 } 655 catch (Error err) { 656 PortletException ex = 657 new PortletException("Error occured during request processing: " + err.getMessage(), err); 658 triggerAfterActionCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex); 660 throw ex; 661 } 662 663 finally { 664 if (processedRequest instanceof MultipartActionRequest && processedRequest != request) { 666 this.multipartResolver.cleanupMultipart((MultipartActionRequest) processedRequest); 667 } 668 669 RequestContextHolder.setRequestAttributes(previousRequestAttributes, this.threadContextInheritable); 671 LocaleContextHolder.setLocaleContext(previousLocaleContext, this.threadContextInheritable); 672 673 requestAttributes.requestCompleted(); 675 if (logger.isDebugEnabled()) { 676 logger.debug("Cleared thread-bound action request context: " + request); 677 } 678 } 679 } 680 681 690 protected void doRenderService(RenderRequest request, RenderResponse response) throws Exception { 691 if (logger.isDebugEnabled()) { 692 logger.debug("DispatcherPortlet with name '" + getPortletName() + "' received render request"); 693 } 694 695 LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext(); 697 LocaleContextHolder.setLocaleContext(buildLocaleContext(request), this.threadContextInheritable); 698 699 RequestAttributes previousRequestAttributes = RequestContextHolder.getRequestAttributes(); 701 PortletRequestAttributes requestAttributes = new PortletRequestAttributes(request); 702 RequestContextHolder.setRequestAttributes(requestAttributes, this.threadContextInheritable); 703 704 if (logger.isDebugEnabled()) { 705 logger.debug("Bound render request context to thread: " + request); 706 } 707 708 RenderRequest processedRequest = request; 709 HandlerExecutionChain mappedHandler = null; 710 int interceptorIndex = -1; 711 712 try { 713 ModelAndView mv = null; 714 try { 715 PortletSession session = request.getPortletSession(false); 717 if (session != null) { 718 if (request.getParameter(ACTION_EXCEPTION_RENDER_PARAMETER) != null) { 719 Exception ex = (Exception ) session.getAttribute(ACTION_EXCEPTION_SESSION_ATTRIBUTE); 720 if (ex != null) { 721 logger.debug("Render phase found exception caught during action phase - rethrowing it"); 722 throw ex; 723 } 724 } 725 else { 726 session.removeAttribute(ACTION_EXCEPTION_SESSION_ATTRIBUTE); 727 } 728 } 729 730 mappedHandler = getHandler(processedRequest, false); 732 if (mappedHandler == null || mappedHandler.getHandler() == null) { 733 noHandlerFound(processedRequest, response); 734 return; 735 } 736 737 if (mappedHandler.getInterceptors() != null) { 739 for (int i = 0; i < mappedHandler.getInterceptors().length; i++) { 740 HandlerInterceptor interceptor = mappedHandler.getInterceptors()[i]; 741 if (!interceptor.preHandleRender(processedRequest, response, mappedHandler.getHandler())) { 742 triggerAfterRenderCompletion(mappedHandler, interceptorIndex, processedRequest, response, null); 743 return; 744 } 745 interceptorIndex = i; 746 } 747 } 748 749 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); 751 mv = ha.handleRender(processedRequest, response, mappedHandler.getHandler()); 752 753 if (mappedHandler.getInterceptors() != null) { 755 for (int i = mappedHandler.getInterceptors().length - 1; i >= 0; i--) { 756 HandlerInterceptor interceptor = mappedHandler.getInterceptors()[i]; 757 interceptor.postHandleRender(processedRequest, response, mappedHandler.getHandler(), mv); 758 } 759 } 760 } 761 catch (ModelAndViewDefiningException ex) { 762 logger.debug("ModelAndViewDefiningException encountered", ex); 763 mv = ex.getModelAndView(); 764 } 765 catch (Exception ex) { 766 Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null); 767 mv = processHandlerException(request, response, handler, ex); 768 } 769 770 if (mv != null && !mv.isEmpty()) { 772 render(mv, processedRequest, response); 773 } 774 else { 775 if (logger.isDebugEnabled()) { 776 logger.debug("Null ModelAndView returned to DispatcherPortlet with name '" + 777 getPortletName() + "': assuming HandlerAdapter completed request handling"); 778 } 779 } 780 781 triggerAfterRenderCompletion(mappedHandler, interceptorIndex, processedRequest, response, null); 783 } 784 785 catch (Exception ex) { 786 triggerAfterRenderCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex); 788 throw ex; 789 } 790 catch (Error err) { 791 PortletException ex = 792 new PortletException("Error occured during request processing: " + err.getMessage(), err); 793 triggerAfterRenderCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex); 795 throw ex; 796 } 797 798 finally { 799 RequestContextHolder.setRequestAttributes(previousRequestAttributes, this.threadContextInheritable); 801 LocaleContextHolder.setLocaleContext(previousLocaleContext, this.threadContextInheritable); 802 803 requestAttributes.requestCompleted(); 805 if (logger.isDebugEnabled()) { 806 logger.debug("Cleared thread-bound render request context: " + request); 807 } 808 } 809 } 810 811 812 818 protected LocaleContext buildLocaleContext(PortletRequest request) { 819 return new SimpleLocaleContext(request.getLocale()); 820 } 821 822 828 protected ActionRequest checkMultipart(ActionRequest request) throws MultipartException { 829 if (this.multipartResolver != null && this.multipartResolver.isMultipart(request)) { 830 if (request instanceof MultipartActionRequest) { 831 logger.debug("Request is already a MultipartActionRequest - probably in a forward"); 832 } 833 else { 834 return this.multipartResolver.resolveMultipart(request); 835 } 836 } 837 return request; 839 } 840 841 848 protected HandlerExecutionChain getHandler(PortletRequest request, boolean cache) throws Exception { 849 HandlerExecutionChain handler = 850 (HandlerExecutionChain) request.getAttribute(HANDLER_EXECUTION_CHAIN_ATTRIBUTE); 851 if (handler != null) { 852 if (!cache) { 853 request.removeAttribute(HANDLER_EXECUTION_CHAIN_ATTRIBUTE); 854 } 855 return handler; 856 } 857 858 Iterator it = this.handlerMappings.iterator(); 859 while (it.hasNext()) { 860 HandlerMapping hm = (HandlerMapping) it.next(); 861 if (logger.isDebugEnabled()) { 862 logger.debug("Testing handler map [" + hm + "] in DispatcherPortlet with name '" + 863 getPortletName() + "'"); 864 } 865 handler = hm.getHandler(request); 866 if (handler != null) { 867 if (cache) { 868 request.setAttribute(HANDLER_EXECUTION_CHAIN_ATTRIBUTE, handler); 869 } 870 return handler; 871 } 872 } 873 return null; 874 } 875 876 881 protected void noHandlerFound(PortletRequest request, PortletResponse response) throws PortletException { 882 if (pageNotFoundLogger.isWarnEnabled()) { 883 pageNotFoundLogger.warn("No mapping found for current request " + 884 "in DispatcherPortlet with name '" + getPortletName() + "'" + 885 " mode '" + request.getPortletMode() + "'" + 886 " type '" + (request instanceof ActionRequest ? "action" : "render") + "'" + 887 " session '" + request.getRequestedSessionId() + "'" + 888 " user '" + getUsernameForRequest(request) + "'"); 889 } 890 throw new UnavailableException("No handler found for request"); 891 } 892 893 899 protected HandlerAdapter getHandlerAdapter(Object handler) throws PortletException { 900 Iterator it = this.handlerAdapters.iterator(); 901 while (it.hasNext()) { 902 HandlerAdapter ha = (HandlerAdapter) it.next(); 903 if (logger.isDebugEnabled()) { 904 logger.debug("Testing handler adapter [" + ha + "]"); 905 } 906 if (ha.supports(handler)) { 907 return ha; 908 } 909 } 910 throw new PortletException("No adapter for handler [" + handler + 911 "]: Does your handler implement a supported interface like Controller?"); 912 } 913 914 924 protected ModelAndView processHandlerException( 925 RenderRequest request, RenderResponse response, Object handler, Exception ex) 926 throws Exception { 927 928 ModelAndView exMv = null; 929 for (Iterator it = this.handlerExceptionResolvers.iterator(); exMv == null && it.hasNext();) { 930 HandlerExceptionResolver resolver = (HandlerExceptionResolver) it.next(); 931 exMv = resolver.resolveException(request, response, handler, ex); 932 } 933 if (exMv != null) { 934 if (logger.isDebugEnabled()) { 935 logger.debug("HandlerExceptionResolver returned ModelAndView [" + exMv + "] for exception"); 936 } 937 logger.warn("Handler execution resulted in exception - forwarding to resolved error view", ex); 938 return exMv; 939 } 940 else { 941 throw ex; 942 } 943 } 944 945 954 private void triggerAfterActionCompletion(HandlerExecutionChain mappedHandler, int interceptorIndex, 955 ActionRequest request, ActionResponse response, Exception ex) 956 throws Exception { 957 958 if (mappedHandler != null) { 960 if (mappedHandler.getInterceptors() != null) { 961 for (int i = interceptorIndex; i >= 0; i--) { 962 HandlerInterceptor interceptor = mappedHandler.getInterceptors()[i]; 963 try { 964 interceptor.afterActionCompletion(request, response, mappedHandler.getHandler(), ex); 965 } 966 catch (Throwable ex2) { 967 logger.error("HandlerInterceptor.afterCompletion threw exception", ex2); 968 } 969 } 970 } 971 } 972 } 973 974 975 983 protected void render(ModelAndView mv, RenderRequest request, RenderResponse response) throws Exception { 984 View view = null; 985 if (mv.isReference()) { 986 view = resolveViewName(mv.getViewName(), mv.getModelInternal(), request); 988 if (view == null) { 989 throw new PortletException("Could not resolve view with name '" + mv.getViewName() + 990 "' in portlet with name '" + getPortletName() + "'"); 991 } 992 } 993 else { 994 Object viewObject = mv.getView(); 996 if (viewObject == null) { 997 throw new PortletException("ModelAndView [" + mv + "] neither contains a view name nor a " + 998 "View object in portlet with name '" + getPortletName() + "'"); 999 } 1000 if (!(viewObject instanceof View)) { 1001 throw new PortletException( 1002 "View object [" + viewObject + "] is not an instance of [org.springframework.web.servlet.View] - " + 1003 "DispatcherPortlet does not support any other view types"); 1004 } 1005 view = (View) viewObject; 1006 } 1007 1008 if (view == null) { 1009 throw new PortletException("Could not resolve view with name '" + mv.getViewName() + 1010 "' in portlet with name '" + getPortletName() + "'"); 1011 } 1012 1013 if (response.getContentType() != null) { 1017 if (logger.isDebugEnabled()) { 1018 logger.debug("Portlet response content type already set to [" + response.getContentType() + "]"); 1019 } 1020 } 1021 else { 1022 String contentType = view.getContentType(); 1024 if (contentType != null) { 1025 if (logger.isDebugEnabled()) { 1026 logger.debug("Setting portlet response content type to view-determined type [" + contentType + "]"); 1027 } 1028 response.setContentType(contentType); 1029 } 1030 } 1031 1032 request.setAttribute(ViewRendererServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, getPortletApplicationContext()); 1034 1035 request.setAttribute(ViewRendererServlet.VIEW_ATTRIBUTE, view); 1037 request.setAttribute(ViewRendererServlet.MODEL_ATTRIBUTE, mv.getModel()); 1038 1039 getPortletContext().getRequestDispatcher(this.viewRendererUrl).include(request, response); 1041 } 1042 1043 1056 protected View resolveViewName(String viewName, Map model, RenderRequest request) throws Exception { 1057 for (Iterator it = this.viewResolvers.iterator(); it.hasNext();) { 1058 ViewResolver viewResolver = (ViewResolver) it.next(); 1059 View view = viewResolver.resolveViewName(viewName, request.getLocale()); 1060 if (view != null) { 1061 return view; 1062 } 1063 } 1064 return null; 1065 } 1066 1067 1076 private void triggerAfterRenderCompletion(HandlerExecutionChain mappedHandler, int interceptorIndex, 1077 RenderRequest request, RenderResponse response, Exception ex) 1078 throws Exception { 1079 1080 if (mappedHandler != null) { 1082 if (mappedHandler.getInterceptors() != null) { 1083 for (int i = interceptorIndex; i >= 0; i--) { 1084 HandlerInterceptor interceptor = mappedHandler.getInterceptors()[i]; 1085 try { 1086 interceptor.afterRenderCompletion(request, response, mappedHandler.getHandler(), ex); 1087 } 1088 catch (Throwable ex2) { 1089 logger.error("HandlerInterceptor.afterCompletion threw exception", ex2); 1090 } 1091 } 1092 } 1093 } 1094 } 1095 1096} 1097 | Popular Tags |