Package org.springframework.web.portlet.mvc.annotation

Source Code of org.springframework.web.portlet.mvc.annotation.Portlet20AnnotationControllerTests$MySpecialArg

/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.web.portlet.mvc.annotation;

import java.io.IOException;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.EventResponse;
import javax.portlet.MimeResponse;
import javax.portlet.PortletContext;
import javax.portlet.PortletMode;
import javax.portlet.PortletRequest;
import javax.portlet.PortletResponse;
import javax.portlet.PortletSession;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ResourceResponse;
import javax.portlet.StateAwareResponse;
import javax.portlet.WindowState;
import javax.servlet.http.Cookie;

import org.junit.Test;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.core.MethodParameter;
import org.springframework.mock.web.portlet.MockActionRequest;
import org.springframework.mock.web.portlet.MockActionResponse;
import org.springframework.mock.web.portlet.MockEvent;
import org.springframework.mock.web.portlet.MockEventRequest;
import org.springframework.mock.web.portlet.MockEventResponse;
import org.springframework.mock.web.portlet.MockPortletConfig;
import org.springframework.mock.web.portlet.MockPortletContext;
import org.springframework.mock.web.portlet.MockRenderRequest;
import org.springframework.mock.web.portlet.MockRenderResponse;
import org.springframework.mock.web.portlet.MockResourceRequest;
import org.springframework.mock.web.portlet.MockResourceResponse;
import org.springframework.stereotype.Controller;
import org.springframework.tests.sample.beans.DerivedTestBean;
import org.springframework.tests.sample.beans.ITestBean;
import org.springframework.tests.sample.beans.TestBean;
import org.springframework.ui.ExtendedModelMap;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Errors;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.bind.support.WebArgumentResolver;
import org.springframework.web.bind.support.WebBindingInitializer;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.web.portlet.DispatcherPortlet;
import org.springframework.web.portlet.ModelAndView;
import org.springframework.web.portlet.NoHandlerFoundException;
import org.springframework.web.portlet.bind.annotation.ActionMapping;
import org.springframework.web.portlet.bind.annotation.EventMapping;
import org.springframework.web.portlet.bind.annotation.RenderMapping;
import org.springframework.web.portlet.bind.annotation.ResourceMapping;
import org.springframework.web.portlet.context.StaticPortletApplicationContext;
import org.springframework.web.portlet.mvc.AbstractController;

import static org.junit.Assert.*;

/**
* @author Juergen Hoeller
* @since 3.0
*/
public class Portlet20AnnotationControllerTests {

  @Test
  public void standardHandleMethod() throws Exception {
    DispatcherPortlet portlet = new DispatcherPortlet() {
      @Override
      protected ApplicationContext createPortletApplicationContext(ApplicationContext parent) throws BeansException {
        GenericWebApplicationContext wac = new GenericWebApplicationContext();
        wac.registerBeanDefinition("controller", new RootBeanDefinition(MyController.class));
        wac.refresh();
        return wac;
      }
    };
    portlet.init(new MockPortletConfig());

    MockRenderRequest request = new MockRenderRequest(PortletMode.VIEW);
    MockRenderResponse response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("test", response.getContentAsString());
  }

  @Test
  public void standardHandleMethodWithResources() throws Exception {
    DispatcherPortlet portlet = new DispatcherPortlet() {
      @Override
      protected ApplicationContext createPortletApplicationContext(ApplicationContext parent) throws BeansException {
        StaticPortletApplicationContext wac = new StaticPortletApplicationContext();
        wac.setPortletConfig(getPortletConfig());
        wac.registerBeanDefinition("controller", new RootBeanDefinition(MyController.class));
        wac.refresh();
        return wac;
      }
    };
    portlet.init(new MockPortletConfig());

    MockResourceRequest resourceRequest = new MockResourceRequest("/resource1");
    MockResourceResponse resourceResponse = new MockResourceResponse();
    portlet.serveResource(resourceRequest, resourceResponse);
    assertEquals("/resource1", resourceResponse.getForwardedUrl());
    assertNull(resourceResponse.getProperty(ResourceResponse.HTTP_STATUS_CODE));

    resourceRequest = new MockResourceRequest("/WEB-INF/resource2");
    resourceResponse = new MockResourceResponse();
    portlet.serveResource(resourceRequest, resourceResponse);
    assertNull(resourceResponse.getForwardedUrl());
    assertEquals("404", resourceResponse.getProperty(ResourceResponse.HTTP_STATUS_CODE));

    resourceRequest = new MockResourceRequest("/META-INF/resource3");
    resourceResponse = new MockResourceResponse();
    portlet.serveResource(resourceRequest, resourceResponse);
    assertNull(resourceResponse.getForwardedUrl());
    assertEquals("404", resourceResponse.getProperty(ResourceResponse.HTTP_STATUS_CODE));
  }

  @Test
  public void adaptedHandleMethods() throws Exception {
    doTestAdaptedHandleMethods(MyAdaptedController.class);
  }

  @Test
  public void adaptedHandleMethods2() throws Exception {
    doTestAdaptedHandleMethods(MyAdaptedController2.class);
  }

  @Test
  public void adaptedHandleMethods3() throws Exception {
    doTestAdaptedHandleMethods(MyAdaptedController3.class);
  }

  @Test
  public void adaptedHandleMethods4() throws Exception {
    doTestAdaptedHandleMethods(MyAdaptedController4.class);
  }

  private void doTestAdaptedHandleMethods(final Class<?> controllerClass) throws Exception {
    DispatcherPortlet portlet = new DispatcherPortlet() {
      @Override
      protected ApplicationContext createPortletApplicationContext(ApplicationContext parent) throws BeansException {
        GenericWebApplicationContext wac = new GenericWebApplicationContext();
        wac.registerBeanDefinition("controller", new RootBeanDefinition(controllerClass));
        wac.refresh();
        return wac;
      }
    };
    portlet.init(new MockPortletConfig());

    MockActionRequest actionRequest = new MockActionRequest(PortletMode.VIEW);
    MockActionResponse actionResponse = new MockActionResponse();
    portlet.processAction(actionRequest, actionResponse);
    assertEquals("value", actionResponse.getRenderParameter("test"));

    MockRenderRequest request = new MockRenderRequest(PortletMode.VIEW);
    request.setSession(actionRequest.getPortletSession());
    request.setParameters(actionResponse.getRenderParameterMap());
    request.addParameter("name", "name1");
    request.addParameter("age", "value2");
    MockRenderResponse response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("test-name1-typeMismatch", response.getContentAsString());
    assertNull(request.getPortletSession().getAttribute("testBean"));

    request = new MockRenderRequest(PortletMode.EDIT);
    request.addParameter("param1", "value1");
    request.addParameter("param2", "2");
    request.addProperty("header1", "10");
    request.setCookies(new Cookie("cookie1", "3"));
    response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("test-value1-2-10-3", response.getContentAsString());

    request = new MockRenderRequest(PortletMode.HELP);
    request.addParameter("name", "name1");
    request.addParameter("age", "2");
    response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("test-name1-2", response.getContentAsString());
  }

  @Test
  public void formController() throws Exception {
    DispatcherPortlet portlet = new DispatcherPortlet() {
      @Override
      protected ApplicationContext createPortletApplicationContext(ApplicationContext parent) throws BeansException {
        GenericWebApplicationContext wac = new GenericWebApplicationContext();
        wac.registerBeanDefinition("controller", new RootBeanDefinition(MyFormController.class));
        wac.refresh();
        return wac;
      }
      @Override
      protected void render(ModelAndView mv, PortletRequest request, MimeResponse response) throws Exception {
        new TestView().render(mv.getViewName(), mv.getModel(), request, response);
      }
    };
    portlet.init(new MockPortletConfig());

    MockRenderRequest request = new MockRenderRequest(PortletMode.VIEW);
    request.addParameter("name", "name1");
    request.addParameter("age", "value2");
    MockRenderResponse response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myView-name1-typeMismatch-tb1-myValue", response.getContentAsString());
  }

  @Test
  public void modelFormController() throws Exception {
    DispatcherPortlet portlet = new DispatcherPortlet() {
      @Override
      protected ApplicationContext createPortletApplicationContext(ApplicationContext parent) throws BeansException {
        GenericWebApplicationContext wac = new GenericWebApplicationContext();
        wac.registerBeanDefinition("controller", new RootBeanDefinition(MyModelFormController.class));
        wac.refresh();
        return wac;
      }
      @Override
      protected void render(ModelAndView mv, PortletRequest request, MimeResponse response) throws Exception {
        new TestView().render(mv.getViewName(), mv.getModel(), request, response);
      }
    };
    portlet.init(new MockPortletConfig());

    MockRenderRequest request = new MockRenderRequest(PortletMode.VIEW);
    request.addParameter("name", "name1");
    request.addParameter("age", "value2");
    MockRenderResponse response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myView-name1-typeMismatch-tb1-myValue", response.getContentAsString());
  }

  @Test
  public void commandProvidingFormController() throws Exception {
    DispatcherPortlet portlet = new DispatcherPortlet() {
      @Override
      protected ApplicationContext createPortletApplicationContext(ApplicationContext parent) throws BeansException {
        GenericWebApplicationContext wac = new GenericWebApplicationContext();
        wac.registerBeanDefinition("controller", new RootBeanDefinition(MyCommandProvidingFormController.class));
        RootBeanDefinition adapterDef = new RootBeanDefinition(AnnotationMethodHandlerAdapter.class);
        adapterDef.getPropertyValues().add("webBindingInitializer", new MyWebBindingInitializer());
        wac.registerBeanDefinition("handlerAdapter", adapterDef);
        wac.refresh();
        return wac;
      }
      @Override
      protected void render(ModelAndView mv, PortletRequest request, MimeResponse response) throws Exception {
        new TestView().render(mv.getViewName(), mv.getModel(), request, response);
      }
    };
    portlet.init(new MockPortletConfig());

    MockRenderRequest request = new MockRenderRequest(PortletMode.VIEW);
    request.addParameter("defaultName", "myDefaultName");
    request.addParameter("age", "value2");
    request.addParameter("date", "2007-10-02");
    MockRenderResponse response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myView-String:myDefaultName-typeMismatch-tb1-myOriginalValue", response.getContentAsString());
  }

  @Test
  public void typedCommandProvidingFormController() throws Exception {
    DispatcherPortlet portlet = new DispatcherPortlet() {
      @Override
      protected ApplicationContext createPortletApplicationContext(ApplicationContext parent) throws BeansException {
        GenericWebApplicationContext wac = new GenericWebApplicationContext();
        wac.registerBeanDefinition("controller", new RootBeanDefinition(MyTypedCommandProvidingFormController.class));
        wac.registerBeanDefinition("controller2", new RootBeanDefinition(MyOtherTypedCommandProvidingFormController.class));
        RootBeanDefinition adapterDef = new RootBeanDefinition(AnnotationMethodHandlerAdapter.class);
        adapterDef.getPropertyValues().add("webBindingInitializer", new MyWebBindingInitializer());
        adapterDef.getPropertyValues().add("customArgumentResolver", new MySpecialArgumentResolver());
        wac.registerBeanDefinition("handlerAdapter", adapterDef);
        wac.refresh();
        return wac;
      }
      @Override
      protected void render(ModelAndView mv, PortletRequest request, MimeResponse response) throws Exception {
        new TestView().render(mv.getViewName(), mv.getModel(), request, response);
      }
    };
    portlet.init(new MockPortletConfig());

    MockRenderRequest request = new MockRenderRequest(PortletMode.VIEW);
    request.addParameter("myParam", "myValue");
    request.addParameter("defaultName", "10");
    request.addParameter("age", "value2");
    request.addParameter("date", "2007-10-02");
    MockRenderResponse response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myView-Integer:10-typeMismatch-tb1-myOriginalValue", response.getContentAsString());

    request = new MockRenderRequest(PortletMode.VIEW);
    request.addParameter("myParam", "myOtherValue");
    request.addParameter("defaultName", "10");
    request.addParameter("age", "value2");
    request.addParameter("date", "2007-10-02");
    response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myOtherView-Integer:10-typeMismatch-tb1-myOriginalValue", response.getContentAsString());

    request = new MockRenderRequest(PortletMode.EDIT);
    request.addParameter("myParam", "myValue");
    request.addParameter("defaultName", "10");
    request.addParameter("age", "value2");
    request.addParameter("date", "2007-10-02");
    response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myView-myName-typeMismatch-tb1-myOriginalValue", response.getContentAsString());
  }

  @Test
  public void binderInitializingCommandProvidingFormController() throws Exception {
    DispatcherPortlet portlet = new DispatcherPortlet() {
      @Override
      protected ApplicationContext createPortletApplicationContext(ApplicationContext parent) throws BeansException {
        GenericWebApplicationContext wac = new GenericWebApplicationContext();
        wac.registerBeanDefinition("controller", new RootBeanDefinition(MyBinderInitializingCommandProvidingFormController.class));
        wac.refresh();
        return wac;
      }
      @Override
      protected void render(ModelAndView mv, PortletRequest request, MimeResponse response) throws Exception {
        new TestView().render(mv.getViewName(), mv.getModel(), request, response);
      }
    };
    portlet.init(new MockPortletConfig());

    MockRenderRequest request = new MockRenderRequest(PortletMode.VIEW);
    request.addParameter("defaultName", "myDefaultName");
    request.addParameter("age", "value2");
    request.addParameter("date", "2007-10-02");
    MockRenderResponse response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myView-String:myDefaultName-typeMismatch-tb1-myOriginalValue", response.getContentAsString());
  }

  @Test
  public void specificBinderInitializingCommandProvidingFormController() throws Exception {
    DispatcherPortlet portlet = new DispatcherPortlet() {
      @Override
      protected ApplicationContext createPortletApplicationContext(ApplicationContext parent) throws BeansException {
        StaticPortletApplicationContext wac = new StaticPortletApplicationContext();
        wac.registerBeanDefinition("controller", new RootBeanDefinition(MySpecificBinderInitializingCommandProvidingFormController.class));
        wac.refresh();
        return wac;
      }
      @Override
      protected void render(ModelAndView mv, PortletRequest request, MimeResponse response) throws Exception {
        new TestView().render(mv.getViewName(), mv.getModel(), request, response);
      }
    };
    portlet.init(new MockPortletConfig());

    MockRenderRequest request = new MockRenderRequest(PortletMode.VIEW);
    request.addParameter("defaultName", "myDefaultName");
    request.addParameter("age", "value2");
    request.addParameter("date", "2007-10-02");
    MockRenderResponse response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myView-String:myDefaultName-typeMismatch-tb1-myOriginalValue", response.getContentAsString());
  }

  @Test
  public void parameterDispatchingController() throws Exception {
    DispatcherPortlet portlet = new DispatcherPortlet() {
      @Override
      protected ApplicationContext createPortletApplicationContext(ApplicationContext parent) throws BeansException {
        StaticPortletApplicationContext wac = new StaticPortletApplicationContext();
        wac.setPortletContext(new MockPortletContext());
        RootBeanDefinition bd = new RootBeanDefinition(MyParameterDispatchingController.class);
        bd.setScope(WebApplicationContext.SCOPE_REQUEST);
        wac.registerBeanDefinition("controller", bd);
        AnnotationConfigUtils.registerAnnotationConfigProcessors(wac);
        wac.refresh();
        return wac;
      }
    };
    portlet.init(new MockPortletConfig());

    MockRenderRequest request = new MockRenderRequest(PortletMode.VIEW);
    MockRenderResponse response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myView", response.getContentAsString());

    request = new MockRenderRequest(PortletMode.VIEW);
    request.addParameter("view", "other");
    response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myOtherView", response.getContentAsString());

    request = new MockRenderRequest(PortletMode.VIEW);
    request.addParameter("view", "my");
    request.addParameter("lang", "de");
    response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myLangView", response.getContentAsString());

    request = new MockRenderRequest(PortletMode.VIEW);
    request.addParameter("surprise", "!");
    response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("mySurpriseView", response.getContentAsString());
  }

  @Test
  public void typeLevelParameterDispatchingController() throws Exception {
    DispatcherPortlet portlet = new DispatcherPortlet() {
      @Override
      protected ApplicationContext createPortletApplicationContext(ApplicationContext parent) throws BeansException {
        StaticPortletApplicationContext wac = new StaticPortletApplicationContext();
        wac.setPortletContext(new MockPortletContext());
        RootBeanDefinition bd = new RootBeanDefinition(MyTypeLevelParameterDispatchingController.class);
        bd.setScope(WebApplicationContext.SCOPE_REQUEST);
        wac.registerBeanDefinition("controller", bd);
        RootBeanDefinition bd2 = new RootBeanDefinition(MySpecialParameterDispatchingController.class);
        bd2.setScope(WebApplicationContext.SCOPE_REQUEST);
        wac.registerBeanDefinition("controller2", bd2);
        RootBeanDefinition bd3 = new RootBeanDefinition(MyOtherSpecialParameterDispatchingController.class);
        bd3.setScope(WebApplicationContext.SCOPE_REQUEST);
        wac.registerBeanDefinition("controller3", bd3);
        RootBeanDefinition bd4 = new RootBeanDefinition(MyParameterDispatchingController.class);
        bd4.setScope(WebApplicationContext.SCOPE_REQUEST);
        wac.registerBeanDefinition("controller4", bd4);
        AnnotationConfigUtils.registerAnnotationConfigProcessors(wac);
        wac.refresh();
        return wac;
      }
    };
    portlet.init(new MockPortletConfig());

    MockRenderRequest request = new MockRenderRequest(PortletMode.HELP);
    MockRenderResponse response = new MockRenderResponse();
    try {
      portlet.render(request, response);
      fail("Should have thrown NoHandlerFoundException");
    }
    catch (NoHandlerFoundException ex) {
      // expected
    }

    request = new MockRenderRequest(PortletMode.EDIT);
    response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myDefaultView", response.getContentAsString());

    request = new MockRenderRequest(PortletMode.EDIT);
    request.addParameter("myParam", "myValue");
    response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myView", response.getContentAsString());

    request = new MockRenderRequest(PortletMode.EDIT);
    request.addParameter("myParam", "mySpecialValue");
    response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("mySpecialView", response.getContentAsString());

    request = new MockRenderRequest(PortletMode.EDIT);
    request.addParameter("myParam", "myOtherSpecialValue");
    response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myOtherSpecialView", response.getContentAsString());

    request = new MockRenderRequest(PortletMode.VIEW);
    response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myView", response.getContentAsString());

    request = new MockRenderRequest(PortletMode.EDIT);
    request.addParameter("myParam", "myValue");
    request.addParameter("view", "other");
    response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myOtherView", response.getContentAsString());

    request = new MockRenderRequest(PortletMode.EDIT);
    request.addParameter("myParam", "myValue");
    request.addParameter("view", "my");
    request.addParameter("lang", "de");
    response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myLangView", response.getContentAsString());

    request = new MockRenderRequest(PortletMode.EDIT);
    request.addParameter("myParam", "myValue");
    request.addParameter("surprise", "!");
    response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("mySurpriseView", response.getContentAsString());
  }

  @Test
  public void portlet20DispatchingController() throws Exception {
    DispatcherPortlet portlet = new DispatcherPortlet() {
      @Override
      protected ApplicationContext createPortletApplicationContext(ApplicationContext parent) throws BeansException {
        StaticPortletApplicationContext wac = new StaticPortletApplicationContext();
        wac.setPortletContext(new MockPortletContext());
        RootBeanDefinition bd = new RootBeanDefinition(MyPortlet20DispatchingController.class);
        bd.setScope(WebApplicationContext.SCOPE_REQUEST);
        wac.registerBeanDefinition("controller", bd);
        wac.registerBeanDefinition("controller2", new RootBeanDefinition(DetailsController.class));
        AnnotationConfigUtils.registerAnnotationConfigProcessors(wac);
        wac.refresh();
        return wac;
      }
    };
    portlet.init(new MockPortletConfig());

    MockRenderRequest request = new MockRenderRequest(PortletMode.VIEW);
    MockRenderResponse response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myView", response.getContentAsString());

    MockActionRequest actionRequest = new MockActionRequest("this");
    MockActionResponse actionResponse = new MockActionResponse();
    portlet.processAction(actionRequest, actionResponse);

    request = new MockRenderRequest(PortletMode.VIEW, WindowState.MAXIMIZED);
    request.setParameters(actionResponse.getRenderParameterMap());
    response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myLargeView-value", response.getContentAsString());

    actionRequest = new MockActionRequest("that");
    actionResponse = new MockActionResponse();
    portlet.processAction(actionRequest, actionResponse);

    request = new MockRenderRequest(PortletMode.VIEW, WindowState.MAXIMIZED);
    request.setParameters(actionResponse.getRenderParameterMap());
    response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myLargeView-value2", response.getContentAsString());

    actionRequest = new MockActionRequest("else");
    actionResponse = new MockActionResponse();
    portlet.processAction(actionRequest, actionResponse);

    request = new MockRenderRequest(PortletMode.VIEW, WindowState.MAXIMIZED);
    request.setParameters(actionResponse.getRenderParameterMap());
    response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myLargeView-value3", response.getContentAsString());

    actionRequest = new MockActionRequest("error");
    actionResponse = new MockActionResponse();
    portlet.processAction(actionRequest, actionResponse);

    request = new MockRenderRequest(PortletMode.VIEW, WindowState.MAXIMIZED);
    request.setParameters(actionResponse.getRenderParameterMap());
    request.setSession(actionRequest.getPortletSession());
    response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("XXX", response.getContentAsString());

    MockEventRequest eventRequest = new MockEventRequest(new MockEvent("event1"));
    MockEventResponse eventResponse = new MockEventResponse();
    portlet.processEvent(eventRequest, eventResponse);

    request = new MockRenderRequest(PortletMode.VIEW, WindowState.MAXIMIZED);
    request.setParameters(eventResponse.getRenderParameterMap());
    response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myLargeView-value3", response.getContentAsString());

    eventRequest = new MockEventRequest(new MockEvent("event2"));
    eventResponse = new MockEventResponse();
    portlet.processEvent(eventRequest, eventResponse);

    request = new MockRenderRequest(PortletMode.VIEW, WindowState.MAXIMIZED);
    request.setParameters(eventResponse.getRenderParameterMap());
    response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myLargeView-value4", response.getContentAsString());

    request = new MockRenderRequest(PortletMode.VIEW, WindowState.NORMAL);
    request.setParameters(actionResponse.getRenderParameterMap());
    response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myView", response.getContentAsString());

    MockResourceRequest resourceRequest = new MockResourceRequest("resource1");
    MockResourceResponse resourceResponse = new MockResourceResponse();
    portlet.serveResource(resourceRequest, resourceResponse);
    assertEquals("myResource", resourceResponse.getContentAsString());

    resourceRequest = new MockResourceRequest("resource2");
    resourceResponse = new MockResourceResponse();
    portlet.serveResource(resourceRequest, resourceResponse);
    assertEquals("myDefaultResource", resourceResponse.getContentAsString());
  }

  @Test
  public void eventDispatchingController() throws Exception {
    DispatcherPortlet portlet = new DispatcherPortlet() {
      @Override
      protected ApplicationContext createPortletApplicationContext(ApplicationContext parent) throws BeansException {
        StaticPortletApplicationContext wac = new StaticPortletApplicationContext();
        wac.setPortletContext(new MockPortletContext());
        RootBeanDefinition bd = new RootBeanDefinition(MyPortlet20DispatchingController.class);
        bd.setScope(WebApplicationContext.SCOPE_REQUEST);
        wac.registerBeanDefinition("controller", bd);
        wac.registerBeanDefinition("controller2", new RootBeanDefinition(DetailsController.class));
        AnnotationConfigUtils.registerAnnotationConfigProcessors(wac);
        wac.refresh();
        return wac;
      }
    };
    portlet.init(new MockPortletConfig());

    MockRenderRequest request = new MockRenderRequest();
    MockRenderResponse response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myView", response.getContentAsString());

    MockActionRequest actionRequest = new MockActionRequest("this");
    MockActionResponse actionResponse = new MockActionResponse();
    portlet.processAction(actionRequest, actionResponse);

    request = new MockRenderRequest(PortletMode.VIEW, WindowState.MAXIMIZED);
    request.setParameters(actionResponse.getRenderParameterMap());
    request.setSession(actionRequest.getPortletSession());
    response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myLargeView-value", response.getContentAsString());

    actionRequest = new MockActionRequest();
    actionRequest.addParameter("action", "details");
    actionResponse = new MockActionResponse();
    portlet.processAction(actionRequest, actionResponse);

    request = new MockRenderRequest(PortletMode.VIEW, WindowState.MAXIMIZED);
    request.setParameters(actionResponse.getRenderParameterMap());
    request.setSession(actionRequest.getPortletSession());
    response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myLargeView-details", response.getContentAsString());

    MockEventRequest eventRequest = new MockEventRequest(new MockEvent("event1"));
    eventRequest.setParameters(actionRequest.getParameterMap());
    MockEventResponse eventResponse = new MockEventResponse();
    portlet.processEvent(eventRequest, eventResponse);

    request = new MockRenderRequest(PortletMode.VIEW, WindowState.MAXIMIZED);
    request.setParameters(eventResponse.getRenderParameterMap());
    response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myLargeView-value3", response.getContentAsString());

    eventRequest = new MockEventRequest(new MockEvent("event3"));
    eventRequest.setParameters(actionRequest.getParameterMap());
    eventResponse = new MockEventResponse();
    portlet.processEvent(eventRequest, eventResponse);

    request = new MockRenderRequest(PortletMode.VIEW, WindowState.MAXIMIZED);
    request.setParameters(eventResponse.getRenderParameterMap());
    response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myLargeView-value4", response.getContentAsString());

    request = new MockRenderRequest(PortletMode.VIEW, WindowState.NORMAL);
    request.setParameters(actionResponse.getRenderParameterMap());
    response = new MockRenderResponse();
    portlet.render(request, response);
    assertEquals("myView", response.getContentAsString());

    MockResourceRequest resourceRequest = new MockResourceRequest("resource1");
    MockResourceResponse resourceResponse = new MockResourceResponse();
    portlet.serveResource(resourceRequest, resourceResponse);
    assertEquals("myResource", resourceResponse.getContentAsString());

    resourceRequest = new MockResourceRequest("resource2");
    resourceResponse = new MockResourceResponse();
    portlet.serveResource(resourceRequest, resourceResponse);
    assertEquals("myDefaultResource", resourceResponse.getContentAsString());
  }

  @Test
  public void testPredicatePriorityComparisonAcrossControllers() throws Exception {
    DispatcherPortlet portlet = new DispatcherPortlet() {
      @Override
      protected ApplicationContext createPortletApplicationContext(ApplicationContext parent) throws BeansException {
        StaticPortletApplicationContext wac = new StaticPortletApplicationContext();
        // The order of handler registration is important to get
        // the collection with [Render,Action,Render] predicates
        wac.registerSingleton("firstController", FirstController.class);
        wac.registerSingleton("secondController", SecondController.class);
        wac.registerSingleton("thirdController", ThirdController.class);
        wac.registerSingleton("handlerMapping", DefaultAnnotationHandlerMapping.class);
        wac.registerSingleton("handlerAdapter", AnnotationMethodHandlerAdapter.class);
        wac.setPortletContext(new MockPortletContext());
        AnnotationConfigUtils.registerAnnotationConfigProcessors(wac);
        wac.refresh();
        return wac;
      }
    };
    portlet.init(new MockPortletConfig());

    // Make sure all 6 annotated methods can be called

    MockRenderRequest request = new MockRenderRequest(PortletMode.VIEW);
    MockRenderResponse response = new MockRenderResponse();

    // renderFirst
    portlet.render(request, response);
    assertArrayEquals(new String[] { "renderFirst" }, response.getProperties("RESPONSE"));

    // renderSecond
    request.setWindowState(WindowState.MAXIMIZED);
    request.setParameter("report", "second");
    portlet.render(request, response);
    assertArrayEquals(new String[] { "renderSecond" }, response.getProperties("RESPONSE"));

    // renderThirds
    request.setWindowState(WindowState.MAXIMIZED);
    request.setParameter("report", "third");
    portlet.render(request, response);
    assertArrayEquals(new String[] { "renderThird" }, response.getProperties("RESPONSE"));

    MockResourceRequest resourceRequest;
    MockResourceResponse resourceResponse = new MockResourceResponse();

    // resourceFirst
    resourceRequest = new MockResourceRequest("first");
    portlet.serveResource(resourceRequest, resourceResponse);
    assertArrayEquals(new String[] { "resourceFirst" }, resourceResponse.getProperties("RESPONSE"));

    // resourceSecond
    resourceRequest = new MockResourceRequest("second");
    portlet.serveResource(resourceRequest, resourceResponse);
    assertArrayEquals(new String[] { "resourceSecond" }, resourceResponse.getProperties("RESPONSE"));

    // resourceThirds
    resourceRequest = new MockResourceRequest("third");
    portlet.serveResource(resourceRequest, resourceResponse);
    assertArrayEquals(new String[] { "resourceThird" }, resourceResponse.getProperties("RESPONSE"));
  }


  /*
   * Controllers
   */

  @RequestMapping("VIEW")
  private static class MyController extends AbstractController {

    @Override
    protected ModelAndView handleRenderRequestInternal(RenderRequest request, RenderResponse response) throws Exception {
      response.getWriter().write("test");
      return null;
    }
  }


  @Controller
  private static class MyAdaptedController {

    @RequestMapping("VIEW")
    @ActionMapping
    public void myHandle(ActionRequest request, ActionResponse response) throws IOException {
      response.setRenderParameter("test", "value");
    }

    @RequestMapping("EDIT")
    @RenderMapping
    public void myHandle(@RequestParam("param1") String p1, @RequestParam("param2") int p2,
        @RequestHeader("header1") long h1, @CookieValue("cookie1") Cookie c1,
        RenderResponse response) throws IOException {
      response.getWriter().write("test-" + p1 + "-" + p2 + "-" + h1 + "-" + c1.getValue());
    }

    @RequestMapping("HELP")
    @RenderMapping
    public void myHandle(TestBean tb, RenderResponse response) throws IOException {
      response.getWriter().write("test-" + tb.getName() + "-" + tb.getAge());
    }

    @RequestMapping("VIEW")
    @RenderMapping
    public void myHandle(TestBean tb, Errors errors, RenderResponse response) throws IOException {
      response.getWriter().write("test-" + tb.getName() + "-" + errors.getFieldError("age").getCode());
    }
  }


  @Controller
  private static class MyAdaptedController2 {

    @RequestMapping("VIEW")
    @ActionMapping
    public void myHandle(ActionRequest request, ActionResponse response) throws IOException {
      response.setRenderParameter("test", "value");
    }

    @RequestMapping("EDIT")
    @RenderMapping
    public void myHandle(@RequestParam("param1") String p1, int param2, RenderResponse response,
        @RequestHeader("header1") String h1, @CookieValue("cookie1") String c1) throws IOException {
      response.getWriter().write("test-" + p1 + "-" + param2 + "-" + h1 + "-" + c1);
    }

    @RequestMapping("HELP")
    @RenderMapping
    public void myHandle(TestBean tb, RenderResponse response) throws IOException {
      response.getWriter().write("test-" + tb.getName() + "-" + tb.getAge());
    }

    @RequestMapping("VIEW")
    @RenderMapping
    public void myHandle(TestBean tb, Errors errors, RenderResponse response) throws IOException {
      response.getWriter().write("test-" + tb.getName() + "-" + errors.getFieldError("age").getCode());
    }
  }


  @Controller
  @RequestMapping({"VIEW", "EDIT", "HELP"})
  private static class MyAdaptedController3 {

    @ActionMapping
    public void myHandle(ActionRequest request, ActionResponse response) {
      response.setRenderParameter("test", "value");
    }

    @RequestMapping("EDIT")
    @RenderMapping
    public void myHandle(@RequestParam("param1") String p1, int param2, @RequestHeader Integer header1,
        @CookieValue int cookie1, RenderResponse response) throws IOException {
      response.getWriter().write("test-" + p1 + "-" + param2 + "-" + header1 + "-" + cookie1);
    }

    @RequestMapping("HELP")
    @RenderMapping
    public void myHandle(TestBean tb, RenderResponse response) throws IOException {
      response.getWriter().write("test-" + tb.getName() + "-" + tb.getAge());
    }

    @RenderMapping
    public void myHandle(TestBean tb, Errors errors, RenderResponse response) throws IOException {
      response.getWriter().write("test-" + tb.getName() + "-" + errors.getFieldError("age").getCode());
    }
  }


  @Controller
  @SessionAttributes("testBean")
  private static class MyAdaptedController4 {

    @RequestMapping("VIEW")
    @ActionMapping
    public void myHandle(Model model, ActionResponse response, SessionStatus status) {
      TestBean tb = new TestBean();
      tb.setJedi(true);
      model.addAttribute("testBean", tb);
      status.setComplete();
      response.setRenderParameter("test", "value");
    }

    @RequestMapping("EDIT")
    @RenderMapping
    public void myHandle(@RequestParam("param1") String p1, int param2, RenderResponse response,
        @RequestHeader("header1") String h1, @CookieValue("cookie1") String c1) throws IOException {
      response.getWriter().write("test-" + p1 + "-" + param2 + "-" + h1 + "-" + c1);
    }

    @RequestMapping("HELP")
    @RenderMapping
    public void myHandle(@ModelAttribute("tb") TestBean tb, RenderResponse response) throws IOException {
      response.getWriter().write("test-" + tb.getName() + "-" + tb.getAge());
    }

    @RequestMapping("VIEW")
    @RenderMapping
    public void myHandle(@ModelAttribute("testBean") TestBean tb, Errors errors, RenderResponse response, PortletSession session) throws IOException {
      assertTrue(tb.isJedi());
      assertNull(session.getAttribute("testBean"));
      response.getWriter().write("test-" + tb.getName() + "-" + errors.getFieldError("age").getCode());
    }
  }


  @Controller
  private static class MyFormController {

    @ModelAttribute("testBeanList")
    public List<TestBean> getTestBeans() {
      List<TestBean> list = new LinkedList<TestBean>();
      list.add(new TestBean("tb1"));
      list.add(new TestBean("tb2"));
      return list;
    }

    @RequestMapping("VIEW")
    @RenderMapping
    public String myHandle(@ModelAttribute("myCommand")TestBean tb, BindingResult errors, ModelMap model) {
      if (!model.containsKey("myKey")) {
        model.addAttribute("myKey", "myValue");
      }
      return "myView";
    }
  }


  @Controller
  private static class MyModelFormController {

    @ModelAttribute
    public List<TestBean> getTestBeans() {
      List<TestBean> list = new LinkedList<TestBean>();
      list.add(new TestBean("tb1"));
      list.add(new TestBean("tb2"));
      return list;
    }

    @RequestMapping("VIEW")
    @RenderMapping
    public String myHandle(@ModelAttribute("myCommand")TestBean tb, BindingResult errors, Model model) {
      if (!model.containsAttribute("myKey")) {
        model.addAttribute("myKey", "myValue");
      }
      return "myView";
    }
  }


  @Controller
  private static class MyCommandProvidingFormController<T, TB, TB2> extends MyFormController {

    @ModelAttribute("myCommand")
    private TestBean createTestBean(
        @RequestParam T defaultName, Map<String, Object> model, @RequestParam Date date) {
      model.put("myKey", "myOriginalValue");
      return new TestBean(defaultName.getClass().getSimpleName() + ":" + defaultName.toString());
    }

    @Override
    @RequestMapping("VIEW")
    @RenderMapping
    public String myHandle(@ModelAttribute("myCommand") TestBean tb, BindingResult errors, ModelMap model) {
      if (!model.containsKey("myKey")) {
        model.addAttribute("myKey", "myValue");
      }
      return "myView";
    }

    @RequestMapping("EDIT")
    @RenderMapping
    public String myOtherHandle(TB tb, BindingResult errors, ExtendedModelMap model, MySpecialArg arg) {
      TestBean tbReal = (TestBean) tb;
      tbReal.setName("myName");
      assertTrue(model.get("ITestBean") instanceof DerivedTestBean);
      assertNotNull(arg);
      return super.myHandle(tbReal, errors, model);
    }

    @ModelAttribute
    protected TB2 getModelAttr() {
      return (TB2) new DerivedTestBean();
    }
  }


  private static class MySpecialArg {

    public MySpecialArg(String value) {
    }
  }


  @Controller
  @RequestMapping(params = "myParam=myValue")
  private static class MyTypedCommandProvidingFormController
      extends MyCommandProvidingFormController<Integer, TestBean, ITestBean> {

  }


  @Controller
  @RequestMapping(params = "myParam=myOtherValue")
  private static class MyOtherTypedCommandProvidingFormController
      extends MyCommandProvidingFormController<Integer, TestBean, ITestBean> {

    @Override
    @RequestMapping("VIEW")
    @RenderMapping
    public String myHandle(@ModelAttribute("myCommand") TestBean tb, BindingResult errors, ModelMap model) {
      if (!model.containsKey("myKey")) {
        model.addAttribute("myKey", "myValue");
      }
      return "myOtherView";
    }
  }


  @Controller
  private static class MyBinderInitializingCommandProvidingFormController extends MyCommandProvidingFormController {

    @InitBinder
    private void initBinder(WebDataBinder binder) {
      SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
      dateFormat.setLenient(false);
      binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
    }
  }


  @Controller
  private static class MySpecificBinderInitializingCommandProvidingFormController extends MyCommandProvidingFormController {

    @SuppressWarnings("unused")
    @InitBinder({"myCommand", "date"})
    private void initBinder(WebDataBinder binder) {
      SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
      dateFormat.setLenient(false);
      binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
    }
  }


  private static class MyWebBindingInitializer implements WebBindingInitializer {

    @Override
    public void initBinder(WebDataBinder binder, WebRequest request) {
      assertNotNull(request.getLocale());
      SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
      dateFormat.setLenient(false);
      binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
    }
  }


  private static class MySpecialArgumentResolver implements WebArgumentResolver {

    @Override
    public Object resolveArgument(MethodParameter methodParameter, NativeWebRequest webRequest) {
      if (methodParameter.getParameterType().equals(MySpecialArg.class)) {
        return new MySpecialArg("myValue");
      }
      return UNRESOLVED;
    }
  }


  @Controller
  @RequestMapping("VIEW")
  private static class MyParameterDispatchingController {

    @Autowired
    private PortletContext portletContext;

    @Autowired
    private PortletRequest request;

    @Autowired
    private PortletResponse response;

    @Autowired
    private PortletSession session;

    @Autowired
    private WebRequest webRequest;

    @RenderMapping
    public void myHandle(RenderResponse response) throws IOException {
      if (this.portletContext == null || this.request == null || this.response == null ||
          this.session == null || this.webRequest == null) {
        throw new IllegalStateException();
      }
      response.getWriter().write("myView");
    }

    @RenderMapping(params = {"view", "!lang"})
    public void myOtherHandle(RenderResponse response) throws IOException {
      response.getWriter().write("myOtherView");
    }

    @RenderMapping(params = {"view=my", "lang=de"})
    public void myLangHandle(RenderResponse response) throws IOException {
      response.getWriter().write("myLangView");
    }

    @RenderMapping(params = "surprise")
    public void mySurpriseHandle(RenderResponse response) throws IOException {
      response.getWriter().write("mySurpriseView");
    }
  }


  @Controller
  @RequestMapping(value = "EDIT", params = "myParam=myValue")
  private static class MyTypeLevelParameterDispatchingController extends MyParameterDispatchingController {

  }


  @Controller
  @RequestMapping("EDIT")
  private static class MySpecialParameterDispatchingController {

    @RenderMapping(params = "myParam=mySpecialValue")
    public void myHandle(RenderResponse response) throws IOException {
      response.getWriter().write("mySpecialView");
    }

    @RenderMapping
    public void myDefaultHandle(RenderResponse response) throws IOException {
      response.getWriter().write("myDefaultView");
    }
  }


  @Controller
  @RequestMapping("EDIT")
  private static class MyOtherSpecialParameterDispatchingController {

    @RenderMapping(params = "myParam=myOtherSpecialValue")
    public void myHandle(RenderResponse response) throws IOException {
      response.getWriter().write("myOtherSpecialView");
    }
  }


  @Controller
  @RequestMapping("VIEW")
  private static class MyPortlet20DispatchingController {

    @ActionMapping("this")
    public void myHandle(StateAwareResponse response) {
      response.setRenderParameter("test", "value");
    }

    @ActionMapping("that")
    public void myHandle2(StateAwareResponse response) {
      response.setRenderParameter("test", "value2");
    }

    @ActionMapping("error")
    public void myError(StateAwareResponse response) {
      throw new IllegalStateException("XXX");
    }

    @EventMapping("event1")
    public void myHandle(EventResponse response) throws IOException {
      response.setRenderParameter("test", "value3");
    }

    @EventMapping("event2")
    public void myHandle2(EventResponse response) throws IOException {
      response.setRenderParameter("test", "value4");
    }

    @RenderMapping("MAXIMIZED")
    public void myHandle(Writer writer, @RequestParam("test") String renderParam) throws IOException {
      writer.write("myLargeView-" + renderParam);
    }

    @RenderMapping
    public void myDefaultHandle(Writer writer) throws IOException {
      writer.write("myView");
    }

    @ExceptionHandler
    public void handleException(Exception ex, Writer writer) throws IOException {
      writer.write(ex.getMessage());
    }

    @ResourceMapping("resource1")
    public void myResource(Writer writer) throws IOException {
      writer.write("myResource");
    }
  }


  @Controller
  @RequestMapping("VIEW")
  private static class DetailsController {

    @ActionMapping("else")
    public void myHandle(StateAwareResponse response) {
      response.setRenderParameter("test", "value3");
    }

    @EventMapping("event3")
    public void myHandle2(EventResponse response) throws IOException {
      response.setRenderParameter("test", "value4");
    }

    @ActionMapping(params = "action=details")
    public void renderDetails(ActionRequest request, ActionResponse response, Model model) {
      response.setRenderParameter("test", "details");
    }

    @ResourceMapping
    public void myDefaultResource(Writer writer) throws IOException {
      writer.write("myDefaultResource");
    }
  }


  private static class TestView {

    public void render(String viewName, Map<String, Object> model, PortletRequest request, MimeResponse response) throws Exception {
      TestBean tb = (TestBean) model.get("testBean");
      if (tb == null) {
        tb = (TestBean) model.get("myCommand");
      }
      if (tb.getName().endsWith("myDefaultName")) {
        assertTrue(tb.getDate().getYear() == 107);
      }
      Errors errors = (Errors) model.get(BindingResult.MODEL_KEY_PREFIX + "testBean");
      if (errors == null) {
        errors = (Errors) model.get(BindingResult.MODEL_KEY_PREFIX + "myCommand");
      }
      if (errors.hasFieldErrors("date")) {
        throw new IllegalStateException();
      }
      List<?> testBeans = (List<?>) model.get("testBeanList");
      response.getWriter().write(viewName + "-" + tb.getName() + "-" + errors.getFieldError("age").getCode() +
          "-" + ((TestBean) testBeans.get(0)).getName() + "-" + model.get("myKey"));
    }
  }


  @RequestMapping(value="view")
  public static class FirstController {

    @RenderMapping
    public String renderFirst(RenderResponse response) {
      response.setProperty("RESPONSE", "renderFirst");
      return "renderFirst";
    }

    @ResourceMapping("first")
    public String resourceFirst(ResourceResponse response) {
      response.setProperty("RESPONSE", "resourceFirst");
      return "resourceFirst";
    }
  }


  @RequestMapping(value="view")
  public static class SecondController {

    @ResourceMapping("second")
    public String processResource(ResourceResponse response) {
      response.setProperty("RESPONSE", "resourceSecond");
      return "resourceSecond";
    }

    @RenderMapping(value = "MAXIMIZED", params = "report=second")
    public String renderSecond(RenderResponse response) {
      response.setProperty("RESPONSE", "renderSecond");
      return "renderSecond";
    }
  }


  @RequestMapping(value="view")
  public static class ThirdController {

    @ResourceMapping("third")
    public String processResource(ResourceResponse response) {
      response.setProperty("RESPONSE", "resourceThird");
      return "resourceThird";
    }

    @RenderMapping(value = "MAXIMIZED", params = "report=third")
    public String renderSecond(RenderResponse response) {
      response.setProperty("RESPONSE", "renderThird");
      return "renderThird";
    }
  }

}
TOP

Related Classes of org.springframework.web.portlet.mvc.annotation.Portlet20AnnotationControllerTests$MySpecialArg

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.