/** * Convert model to request parameters and redirect to the given URL. * @see #appendQueryProperties * @see #sendRedirect */ @Override protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws IOException { String targetUrl = createTargetUrl(model, request); targetUrl = updateTargetUrl(targetUrl, model, request, response); FlashMap flashMap = RequestContextUtils.getOutputFlashMap(request); if (!CollectionUtils.isEmpty(flashMap)) { UriComponents uriComponents = UriComponentsBuilder.fromUriString(targetUrl).build(); flashMap.setTargetRequestPath(uriComponents.getPath()); flashMap.addTargetRequestParams(uriComponents.getQueryParams()); FlashMapManager flashMapManager = RequestContextUtils.getFlashMapManager(request); if (flashMapManager == null) { throw new IllegalStateException("FlashMapManager not found despite output FlashMap having been set"); } flashMapManager.saveOutputFlashMap(flashMap, request, response); } sendRedirect(request, response, targetUrl, this.http10Compatible); }
/** * Return a FlashMap contained in the given list that matches the request. * @return a matching FlashMap or {@code null} */ private FlashMap getMatchingFlashMap(List<FlashMap> allMaps, HttpServletRequest request) { List<FlashMap> result = new LinkedList<FlashMap>(); for (FlashMap flashMap : allMaps) { if (isFlashMapForRequest(flashMap, request)) { result.add(flashMap); } } if (!result.isEmpty()) { Collections.sort(result); if (logger.isDebugEnabled()) { logger.debug("Found matching FlashMap(s): " + result); } return result.get(0); } return null; }
/** * Whether the given FlashMap matches the current request. * Uses the expected request path and query parameters saved in the FlashMap. */ protected boolean isFlashMapForRequest(FlashMap flashMap, HttpServletRequest request) { String expectedPath = flashMap.getTargetRequestPath(); if (expectedPath != null) { String requestUri = getUrlPathHelper().getOriginatingRequestUri(request); if (!requestUri.equals(expectedPath) && !requestUri.equals(expectedPath + "/")) { return false; } } UriComponents uriComponents = ServletUriComponentsBuilder.fromRequest(request).build(); MultiValueMap<String, String> actualParams = uriComponents.getQueryParams(); MultiValueMap<String, String> expectedParams = flashMap.getTargetRequestParams(); for (String expectedName : expectedParams.keySet()) { List<String> actualValues = actualParams.get(expectedName); if (actualValues == null) { return false; } for (String expectedValue : expectedParams.get(expectedName)) { if (!actualValues.contains(expectedValue)) { return false; } } } return true; }
@Test public void setAlwaysUseRedirectAttributes() throws Exception { HandlerMethodArgumentResolver redirectAttributesResolver = new RedirectAttributesMethodArgumentResolver(); HandlerMethodArgumentResolver modelResolver = new ModelMethodProcessor(); HandlerMethodReturnValueHandler viewHandler = new ViewNameMethodReturnValueHandler(); this.handlerAdapter.setArgumentResolvers(Arrays.asList(redirectAttributesResolver, modelResolver)); this.handlerAdapter.setReturnValueHandlers(Collections.singletonList(viewHandler)); this.handlerAdapter.setIgnoreDefaultModelOnRedirect(true); this.handlerAdapter.afterPropertiesSet(); this.request.setAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap()); HandlerMethod handlerMethod = handlerMethod(new RedirectAttributeController(), "handle", Model.class); ModelAndView mav = this.handlerAdapter.handle(request, response, handlerMethod); assertTrue("Without RedirectAttributes arg, model should be empty", mav.getModel().isEmpty()); }
@Test public void retrieveAndUpdateMatchByParams() { FlashMap flashMap = new FlashMap(); flashMap.put("key", "value"); flashMap.addTargetRequestParam("number", "one"); this.flashMapManager.setFlashMaps(Arrays.asList(flashMap)); this.request.setQueryString("number="); FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(this.request, this.response); assertNull(inputFlashMap); assertEquals("FlashMap should not have been removed", 1, this.flashMapManager.getFlashMaps().size()); this.request.setQueryString("number=two"); inputFlashMap = this.flashMapManager.retrieveAndUpdate(this.request, this.response); assertNull(inputFlashMap); assertEquals("FlashMap should not have been removed", 1, this.flashMapManager.getFlashMaps().size()); this.request.setQueryString("number=one"); inputFlashMap = this.flashMapManager.retrieveAndUpdate(this.request, this.response); assertEquals(flashMap, inputFlashMap); assertEquals("Input FlashMap should have been removed", 0, this.flashMapManager.getFlashMaps().size()); }
@Test public void retrieveAndUpdateMatchWithMultiValueParam() { FlashMap flashMap = new FlashMap(); flashMap.put("name", "value"); flashMap.addTargetRequestParam("id", "1"); flashMap.addTargetRequestParam("id", "2"); this.flashMapManager.setFlashMaps(Arrays.asList(flashMap)); this.request.setQueryString("id=1"); FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(this.request, this.response); assertNull(inputFlashMap); assertEquals("FlashMap should not have been removed", 1, this.flashMapManager.getFlashMaps().size()); this.request.setQueryString("id=1&id=2"); inputFlashMap = this.flashMapManager.retrieveAndUpdate(this.request, this.response); assertEquals(flashMap, inputFlashMap); assertEquals("Input FlashMap should have been removed", 0, this.flashMapManager.getFlashMaps().size()); }
@Test public void retrieveAndUpdateSortMultipleMatches() { FlashMap emptyFlashMap = new FlashMap(); FlashMap flashMapOne = new FlashMap(); flashMapOne.put("key1", "value1"); flashMapOne.setTargetRequestPath("/one"); FlashMap flashMapTwo = new FlashMap(); flashMapTwo.put("key1", "value1"); flashMapTwo.put("key2", "value2"); flashMapTwo.setTargetRequestPath("/one/two"); this.flashMapManager.setFlashMaps(Arrays.asList(emptyFlashMap, flashMapOne, flashMapTwo)); this.request.setRequestURI("/one/two"); FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(this.request, this.response); assertEquals(flashMapTwo, inputFlashMap); assertEquals("Input FlashMap should have been removed", 2, this.flashMapManager.getFlashMaps().size()); }
@Test public void saveOutputFlashMapDecodeParameters() throws Exception { FlashMap flashMap = new FlashMap(); flashMap.put("key", "value"); flashMap.setTargetRequestPath("/path"); flashMap.addTargetRequestParam("param", "%D0%90%D0%90"); flashMap.addTargetRequestParam("param", "%D0%91%D0%91"); flashMap.addTargetRequestParam("param", "%D0%92%D0%92"); flashMap.addTargetRequestParam("%3A%2F%3F%23%5B%5D%40", "value"); this.request.setCharacterEncoding("UTF-8"); this.flashMapManager.saveOutputFlashMap(flashMap, this.request, this.response); MockHttpServletRequest requestAfterRedirect = new MockHttpServletRequest("GET", "/path"); requestAfterRedirect.setQueryString("param=%D0%90%D0%90¶m=%D0%91%D0%91¶m=%D0%92%D0%92&%3A%2F%3F%23%5B%5D%40=value"); requestAfterRedirect.addParameter("param", "\u0410\u0410"); requestAfterRedirect.addParameter("param", "\u0411\u0411"); requestAfterRedirect.addParameter("param", "\u0412\u0412"); requestAfterRedirect.addParameter(":/?#[]@", "value"); flashMap = this.flashMapManager.retrieveAndUpdate(requestAfterRedirect, new MockHttpServletResponse()); assertNotNull(flashMap); assertEquals(1, flashMap.size()); assertEquals("value", flashMap.get("key")); }
@Test public void flashAttributesWithQueryParamsWithSpace() throws Exception { String encodedValue = URLEncoder.encode("1 2", "UTF-8"); FlashMap flashMap = new FlashMap(); flashMap.put("key", "value"); flashMap.setTargetRequestPath("/path"); flashMap.addTargetRequestParam("param", encodedValue); this.request.setCharacterEncoding("UTF-8"); this.flashMapManager.saveOutputFlashMap(flashMap, this.request, this.response); MockHttpServletRequest requestAfterRedirect = new MockHttpServletRequest("GET", "/path"); requestAfterRedirect.setQueryString("param=" + encodedValue); requestAfterRedirect.addParameter("param", "1 2"); flashMap = this.flashMapManager.retrieveAndUpdate(requestAfterRedirect, new MockHttpServletResponse()); assertNotNull(flashMap); assertEquals(1, flashMap.size()); assertEquals("value", flashMap.get("key")); }
@ExceptionHandler({Exception.class, RuntimeException.class}) public ModelAndView handleAllExceptions(Exception ex, HttpServletRequest request) { log.error(String.format("An unhandled error occurred on page %s.", request.getRequestURL()) ,ex); if (config.isDevOn()) { FlashMap flashMap = RequestContextUtils.getOutputFlashMap(request); flashMap.put("exceptionName", ex.getClass().getSimpleName()); flashMap.put("exception", ex.getMessage()); StringWriter errors = new StringWriter(); ex.printStackTrace(new PrintWriter(errors)); flashMap.put("stackTrace", errors.toString()); } return new ModelAndView("redirect:/error"); }
@Test public void testAddSuccessMessage() { FlashMap flashMap = new FlashMap(); RedirectAttributes redirectAttributes = mock(RedirectAttributes.class); when(redirectAttributes.addFlashAttribute(anyObject(), anyObject())).then(invocation -> { flashMap.put((String)invocation.getArguments()[0], invocation.getArguments()[1]); return invocation.getMock(); }); when(redirectAttributes.getFlashAttributes()).then(invocation -> flashMap); MockHttpServletRequest request = new MockHttpServletRequest(RequestMethod.GET.name(), "/"); request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, webApplicationContext); request.setAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE, flashMap); RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); statusMessageService.addSuccessStatusMessage(redirectAttributes, "Success!"); statusMessageService.addSuccessStatusMessage(redirectAttributes, "Success2"); Iterator<String> it = ((Set)flashMap.get(StatusMessageService.SUCCESS_MESSAGE_KEY)).iterator(); assertEquals("Success!", it.next()); assertEquals("Success2", it.next()); }
@Test public void testAddWarningMessage() { FlashMap flashMap = new FlashMap(); RedirectAttributes redirectAttributes = mock(RedirectAttributes.class); when(redirectAttributes.addFlashAttribute(anyObject(), anyObject())).then(invocation -> { flashMap.put((String)invocation.getArguments()[0], invocation.getArguments()[1]); return invocation.getMock(); }); when(redirectAttributes.getFlashAttributes()).then(invocation -> flashMap); MockHttpServletRequest request = new MockHttpServletRequest(RequestMethod.GET.name(), "/"); request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, webApplicationContext); request.setAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE, flashMap); RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); statusMessageService.addWarningStatusMessage(redirectAttributes, "Warning!"); statusMessageService.addWarningStatusMessage(redirectAttributes, "Warning2"); Iterator<String> it = ((Set)flashMap.get(StatusMessageService.WARNING_MESSAGE_KEY)).iterator(); assertEquals("Warning!", it.next()); assertEquals("Warning2", it.next()); }
@Test public void testAddErrorMessage() { final FlashMap flashMap = new FlashMap(); RedirectAttributes redirectAttributes = mock(RedirectAttributes.class); when(redirectAttributes.addFlashAttribute(anyObject(), anyObject())).then(invocation -> { flashMap.put((String)invocation.getArguments()[0], invocation.getArguments()[1]); return invocation.getMock(); }); when(redirectAttributes.getFlashAttributes()).then(invocation -> flashMap); MockHttpServletRequest request = new MockHttpServletRequest(RequestMethod.GET.name(), "/"); request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, webApplicationContext); request.setAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE, flashMap); RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); statusMessageService.addErrorStatusMessage(redirectAttributes, "Error!"); statusMessageService.addErrorStatusMessage(redirectAttributes, "Error2"); Iterator<String> it = ((Set)flashMap.get(StatusMessageService.ERROR_MESSAGE_KEY)).iterator(); assertEquals("Error!", it.next()); assertEquals("Error2", it.next()); }
@Test public void testAddSuccessMessageWithExistingString() { FlashMap flashMap = new FlashMap(); RedirectAttributes redirectAttributes = mock(RedirectAttributes.class); when(redirectAttributes.addFlashAttribute(anyObject(), anyObject())).then(invocation -> { flashMap.put((String)invocation.getArguments()[0], invocation.getArguments()[1]); return invocation.getMock(); }); when(redirectAttributes.getFlashAttributes()).then(invocation -> flashMap); flashMap.put(StatusMessageService.SUCCESS_MESSAGE_KEY, "Success!"); MockHttpServletRequest request = new MockHttpServletRequest(RequestMethod.GET.name(), "/"); request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, webApplicationContext); request.setAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE, flashMap); RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); statusMessageService.addSuccessStatusMessage(redirectAttributes, "Success2"); Iterator<String> it = ((Set)flashMap.get(StatusMessageService.SUCCESS_MESSAGE_KEY)).iterator(); assertEquals("Success!", it.next()); assertEquals("Success2", it.next()); }
@Test public void testAddWarningMessageWithExistingString() { FlashMap flashMap = new FlashMap(); RedirectAttributes redirectAttributes = mock(RedirectAttributes.class); when(redirectAttributes.addFlashAttribute(anyObject(), anyObject())).then(invocation -> { flashMap.put((String)invocation.getArguments()[0], invocation.getArguments()[1]); return invocation.getMock(); }); when(redirectAttributes.getFlashAttributes()).then(invocation -> flashMap); flashMap.put(StatusMessageService.WARNING_MESSAGE_KEY, "Warning!"); MockHttpServletRequest request = new MockHttpServletRequest(RequestMethod.GET.name(), "/"); request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, webApplicationContext); request.setAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE, flashMap); RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); statusMessageService.addWarningStatusMessage(redirectAttributes, "Warning2"); Iterator<String> it = ((Set)flashMap.get(StatusMessageService.WARNING_MESSAGE_KEY)).iterator(); assertEquals("Warning!", it.next()); assertEquals("Warning2", it.next()); }
@Test public void testAddErrorMessageWithExistingString() { FlashMap flashMap = new FlashMap(); RedirectAttributes redirectAttributes = mock(RedirectAttributes.class); when(redirectAttributes.addFlashAttribute(anyObject(), anyObject())).then(invocation -> { flashMap.put((String)invocation.getArguments()[0], invocation.getArguments()[1]); return invocation.getMock(); }); when(redirectAttributes.getFlashAttributes()).then(invocation -> flashMap); flashMap.put(StatusMessageService.ERROR_MESSAGE_KEY, "Error!"); MockHttpServletRequest request = new MockHttpServletRequest(RequestMethod.GET.name(), "/"); request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, webApplicationContext); request.setAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE, flashMap); RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); statusMessageService.addErrorStatusMessage(redirectAttributes, "Error2"); Iterator<String> it = ((Set)flashMap.get(StatusMessageService.ERROR_MESSAGE_KEY)).iterator(); assertEquals("Error!", it.next()); assertEquals("Error2", it.next()); }
@Test public void testAddSuccessMessageWithExistingNull() { FlashMap flashMap = new FlashMap(); RedirectAttributes redirectAttributes = mock(RedirectAttributes.class); when(redirectAttributes.addFlashAttribute(anyObject(), anyObject())).then(invocation -> { flashMap.put((String)invocation.getArguments()[0], invocation.getArguments()[1]); return invocation.getMock(); }); when(redirectAttributes.getFlashAttributes()).then(invocation -> flashMap); flashMap.put(StatusMessageService.SUCCESS_MESSAGE_KEY, null); MockHttpServletRequest request = new MockHttpServletRequest(RequestMethod.GET.name(), "/"); request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, webApplicationContext); request.setAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE, flashMap); RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); statusMessageService.addSuccessStatusMessage(redirectAttributes, "Success!"); statusMessageService.addSuccessStatusMessage(redirectAttributes, "Success2"); Iterator<String> it = ((Set)flashMap.get(StatusMessageService.SUCCESS_MESSAGE_KEY)).iterator(); assertEquals("Success!", it.next()); assertEquals("Success2", it.next()); }
@Test public void testAddWarningMessageWithExistingNull() { FlashMap flashMap = new FlashMap(); RedirectAttributes redirectAttributes = mock(RedirectAttributes.class); when(redirectAttributes.addFlashAttribute(anyObject(), anyObject())).then(invocation -> { flashMap.put((String)invocation.getArguments()[0], invocation.getArguments()[1]); return invocation.getMock(); }); when(redirectAttributes.getFlashAttributes()).then(invocation -> flashMap); flashMap.put(StatusMessageService.WARNING_MESSAGE_KEY, null); MockHttpServletRequest request = new MockHttpServletRequest(RequestMethod.GET.name(), "/"); request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, webApplicationContext); request.setAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE, flashMap); RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); statusMessageService.addWarningStatusMessage(redirectAttributes, "Warning!"); statusMessageService.addWarningStatusMessage(redirectAttributes, "Warning2"); Iterator<String> it = ((Set)flashMap.get(StatusMessageService.WARNING_MESSAGE_KEY)).iterator(); assertEquals("Warning!", it.next()); assertEquals("Warning2", it.next()); }
@Test public void testAddErrorMessageWithExistingNull() { FlashMap flashMap = new FlashMap(); RedirectAttributes redirectAttributes = mock(RedirectAttributes.class); when(redirectAttributes.addFlashAttribute(anyObject(), anyObject())).then(invocation -> { flashMap.put((String)invocation.getArguments()[0], invocation.getArguments()[1]); return invocation.getMock(); }); when(redirectAttributes.getFlashAttributes()).then(invocation -> flashMap); flashMap.put(StatusMessageService.ERROR_MESSAGE_KEY, null); MockHttpServletRequest request = new MockHttpServletRequest(RequestMethod.GET.name(), "/"); request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, webApplicationContext); request.setAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE, flashMap); RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); statusMessageService.addErrorStatusMessage(redirectAttributes, "Error!"); statusMessageService.addErrorStatusMessage(redirectAttributes, "Error2"); Iterator<String> it = ((Set)flashMap.get(StatusMessageService.ERROR_MESSAGE_KEY)).iterator(); assertEquals("Error!", it.next()); assertEquals("Error2", it.next()); }
@Test public void testGetSuccessMessagesSet() { FlashMap flashMap = new FlashMap(); RedirectAttributes redirectAttributes = mock(RedirectAttributes.class); when(redirectAttributes.addFlashAttribute(anyObject(), anyObject())).then(invocation -> { flashMap.put((String)invocation.getArguments()[0], invocation.getArguments()[1]); return invocation.getMock(); }); when(redirectAttributes.getFlashAttributes()).then(invocation -> flashMap); MockHttpServletRequest request = new MockHttpServletRequest(RequestMethod.GET.name(), "/"); request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, webApplicationContext); request.setAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE, flashMap); RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); statusMessageService.addSuccessStatusMessage(redirectAttributes, "Success!"); statusMessageService.addSuccessStatusMessage(redirectAttributes, "Success2"); request = new MockHttpServletRequest(RequestMethod.GET.name(), "/"); request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, webApplicationContext); request.setAttribute(DispatcherServlet.INPUT_FLASH_MAP_ATTRIBUTE, flashMap); RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); Iterator<String> it = statusMessageService.getSuccessStatusMessages().iterator(); assertEquals("Success!", it.next()); assertEquals("Success2", it.next()); }
@Test public void testGetWarningMessagesSet() { FlashMap flashMap = new FlashMap(); RedirectAttributes redirectAttributes = mock(RedirectAttributes.class); when(redirectAttributes.addFlashAttribute(anyObject(), anyObject())).then(invocation -> { flashMap.put((String)invocation.getArguments()[0], invocation.getArguments()[1]); return invocation.getMock(); }); when(redirectAttributes.getFlashAttributes()).then(invocation -> flashMap); MockHttpServletRequest request = new MockHttpServletRequest(RequestMethod.GET.name(), "/"); request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, webApplicationContext); request.setAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE, flashMap); RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); statusMessageService.addWarningStatusMessage(redirectAttributes, "Warning!"); statusMessageService.addWarningStatusMessage(redirectAttributes, "Warning2"); request = new MockHttpServletRequest(RequestMethod.GET.name(), "/"); request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, webApplicationContext); request.setAttribute(DispatcherServlet.INPUT_FLASH_MAP_ATTRIBUTE, flashMap); RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); Iterator<String> it = statusMessageService.getWarningStatusMessages().iterator(); assertEquals("Warning!", it.next()); assertEquals("Warning2", it.next()); }
@Test public void testGetErrorMessagesSet() { FlashMap flashMap = new FlashMap(); RedirectAttributes redirectAttributes = mock(RedirectAttributes.class); when(redirectAttributes.addFlashAttribute(anyObject(), anyObject())).then(invocation -> { flashMap.put((String)invocation.getArguments()[0], invocation.getArguments()[1]); return invocation.getMock(); }); when(redirectAttributes.getFlashAttributes()).then(invocation -> flashMap); MockHttpServletRequest request = new MockHttpServletRequest(RequestMethod.GET.name(), "/"); request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, webApplicationContext); request.setAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE, flashMap); RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); statusMessageService.addErrorStatusMessage(redirectAttributes, "Error!"); statusMessageService.addErrorStatusMessage(redirectAttributes, "Error2"); request = new MockHttpServletRequest(RequestMethod.GET.name(), "/"); request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, webApplicationContext); request.setAttribute(DispatcherServlet.INPUT_FLASH_MAP_ATTRIBUTE, flashMap); RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); Iterator<String> it = statusMessageService.getErrorStatusMessages().iterator(); assertEquals("Error!", it.next()); assertEquals("Error2", it.next()); }
/** * Return a FlashMap contained in the given list that matches the request. * @return a matching FlashMap or {@code null} */ private FlashMap getMatchingFlashMap(List<FlashMap> allMaps, HttpServletRequest request) { List<FlashMap> result = new ArrayList<FlashMap>(); for (FlashMap flashMap : allMaps) { if (isFlashMapForRequest(flashMap, request)) { result.add(flashMap); } } if (!result.isEmpty()) { Collections.sort(result); if (logger.isDebugEnabled()) { logger.debug("Found matching FlashMap(s): " + result); } return result.get(0); } return null; }
/** * Whether the given FlashMap matches the current request. * Uses the expected request path and query parameters saved in the FlashMap. */ protected boolean isFlashMapForRequest(FlashMap flashMap, HttpServletRequest request) { String expectedPath = flashMap.getTargetRequestPath(); if (expectedPath != null) { String requestUri = this.urlPathHelper.getOriginatingRequestUri(request); if (!requestUri.equals(expectedPath) && !requestUri.equals(expectedPath + "/")) { return false; } } MultiValueMap<String, String> targetParams = flashMap.getTargetRequestParams(); for (String expectedName : targetParams.keySet()) { for (String expectedValue : targetParams.get(expectedName)) { if (!ObjectUtils.containsElement(request.getParameterValues(expectedName), expectedValue)) { return false; } } } return true; }
public final void saveOutputFlashMap(FlashMap flashMap, HttpServletRequest request, HttpServletResponse response) { if (CollectionUtils.isEmpty(flashMap)) { return; } String path = decodeAndNormalizePath(flashMap.getTargetRequestPath(), request); flashMap.setTargetRequestPath(path); decodeParameters(flashMap.getTargetRequestParams(), request); if (logger.isDebugEnabled()) { logger.debug("Saving FlashMap=" + flashMap); } flashMap.startExpirationPeriod(this.flashMapTimeout); synchronized (writeLock) { List<FlashMap> allMaps = retrieveFlashMaps(request); allMaps = (allMaps != null ? allMaps : new CopyOnWriteArrayList<FlashMap>()); allMaps.add(flashMap); updateFlashMaps(allMaps, request, response); } }
@Test public void setAlwaysUseRedirectAttributes() throws Exception { HandlerMethodArgumentResolver redirectAttributesResolver = new RedirectAttributesMethodArgumentResolver(); HandlerMethodArgumentResolver modelResolver = new ModelMethodProcessor(); HandlerMethodReturnValueHandler viewHandler = new ViewNameMethodReturnValueHandler(); this.handlerAdapter.setArgumentResolvers(Arrays.asList(redirectAttributesResolver, modelResolver)); this.handlerAdapter.setReturnValueHandlers(Arrays.asList(viewHandler)); this.handlerAdapter.setIgnoreDefaultModelOnRedirect(true); this.handlerAdapter.afterPropertiesSet(); this.request.setAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap()); HandlerMethod handlerMethod = handlerMethod(new RedirectAttributeController(), "handle", Model.class); ModelAndView mav = this.handlerAdapter.handle(request, response, handlerMethod); assertTrue("Without RedirectAttributes arg, model should be empty", mav.getModel().isEmpty()); }
@Test public void retrieveAndUpdateMatchByParams() { FlashMap flashMap = new FlashMap(); flashMap.put("key", "value"); flashMap.addTargetRequestParam("number", "one"); this.flashMapManager.setFlashMaps(flashMap); this.request.setParameter("number", (String) null); FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(this.request, this.response); assertNull(inputFlashMap); assertEquals("FlashMap should not have been removed", 1, this.flashMapManager.getFlashMaps().size()); this.request.setParameter("number", "two"); inputFlashMap = this.flashMapManager.retrieveAndUpdate(this.request, this.response); assertNull(inputFlashMap); assertEquals("FlashMap should not have been removed", 1, this.flashMapManager.getFlashMaps().size()); this.request.setParameter("number", "one"); inputFlashMap = this.flashMapManager.retrieveAndUpdate(this.request, this.response); assertEquals(flashMap, inputFlashMap); assertEquals("Input FlashMap should have been removed", 0, this.flashMapManager.getFlashMaps().size()); }
@Test public void retrieveAndUpdateMatchWithMultiValueParam() { FlashMap flashMap = new FlashMap(); flashMap.put("name", "value"); flashMap.addTargetRequestParam("id", "1"); flashMap.addTargetRequestParam("id", "2"); this.flashMapManager.setFlashMaps(flashMap); this.request.setParameter("id", "1"); FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(this.request, this.response); assertNull(inputFlashMap); assertEquals("FlashMap should not have been removed", 1, this.flashMapManager.getFlashMaps().size()); this.request.addParameter("id", "2"); inputFlashMap = this.flashMapManager.retrieveAndUpdate(this.request, this.response); assertEquals(flashMap, inputFlashMap); assertEquals("Input FlashMap should have been removed", 0, this.flashMapManager.getFlashMaps().size()); }
@Test public void retrieveAndUpdateSortMultipleMatches() { FlashMap emptyFlashMap = new FlashMap(); FlashMap flashMapOne = new FlashMap(); flashMapOne.put("key1", "value1"); flashMapOne.setTargetRequestPath("/one"); FlashMap flashMapTwo = new FlashMap(); flashMapTwo.put("key1", "value1"); flashMapTwo.put("key2", "value2"); flashMapTwo.setTargetRequestPath("/one/two"); this.flashMapManager.setFlashMaps(emptyFlashMap, flashMapOne, flashMapTwo); this.request.setRequestURI("/one/two"); FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(this.request, this.response); assertEquals(flashMapTwo, inputFlashMap); assertEquals("Input FlashMap should have been removed", 2, this.flashMapManager.getFlashMaps().size()); }
@Test public void saveOutputFlashMapDecodeParameters() throws Exception { this.request.setCharacterEncoding("UTF-8"); FlashMap flashMap = new FlashMap(); flashMap.put("anyKey", "anyValue"); flashMap.addTargetRequestParam("key", "%D0%90%D0%90"); flashMap.addTargetRequestParam("key", "%D0%91%D0%91"); flashMap.addTargetRequestParam("key", "%D0%92%D0%92"); flashMap.addTargetRequestParam("%3A%2F%3F%23%5B%5D%40", "value"); this.flashMapManager.saveOutputFlashMap(flashMap, this.request, this.response); MultiValueMap<String,String> targetRequestParams = flashMap.getTargetRequestParams(); assertEquals(Arrays.asList("\u0410\u0410", "\u0411\u0411", "\u0412\u0412"), targetRequestParams.get("key")); assertEquals(Arrays.asList("value"), targetRequestParams.get(":/?#[]@")); }
/** * {@link PostBack} インスタンスを保存します。 * @param postBack {@link PostBack} インスタンス */ public static void save(PostBack postBack) { RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); DispatchType dispatchType = getDispatchType(postBack.getException()); switch (dispatchType) { case JSP: requestAttributes.setAttribute(PostBack.POST_BACK_ATTRIBUTE_KEY, postBack, RequestAttributes.SCOPE_REQUEST); break; case FORWARD: requestAttributes.setAttribute(PostBack.POST_BACK_ATTRIBUTE_KEY, postBack, RequestAttributes.SCOPE_REQUEST); break; case REDIRECT: PostBackManager instance = (PostBackManager) requestAttributes.getAttribute(STORE_KEY_TO_REQUEST, RequestAttributes.SCOPE_REQUEST); FlashMap flashMap = RequestContextUtils.getOutputFlashMap(instance.request); flashMap.put(PostBack.POST_BACK_ATTRIBUTE_KEY, postBack); break; default: throw new InternalException(PostBackManager.class, "E-POSTBACK#0001"); } }
@Test public void インフォメーションメッセージがリクエストとフラッシュスコープにセットされ出力される() throws Exception { MessageContext context = new MessageContext(request); context.saveInformationMessageToRequest("I-JX_INFORMATIONS_TAG_TEST#0001"); context.saveInformationMessageToFlash("I-JX_INFORMATIONS_TAG_TEST#0002"); FlashMap flashMap = RequestContextUtils.getOutputFlashMap(request); request.setAttribute(MessageContext.INFORMATION_MESSAGE_KEY_TO_FLASH, flashMap.get(MessageContext.INFORMATION_MESSAGE_KEY_TO_FLASH)); JseInformationsTag tag = new JseInformationsTag(); tag.setJspContext(page); tag.doTag(); assertThat(response.getContentAsString(), is("<div class=\"jfw_messages\">" + "<p class=\"jfw_msg_style\">I-JX_INFORMATIONS_TAG_TEST#0001</p>" + "<p class=\"jfw_msg_style\">I-JX_INFORMATIONS_TAG_TEST#0002</p></div>")); }
@Test public void エラーメッセージがリクエストとフラッシュスコープにセットされ出力される() throws Exception { MessageContext context = new MessageContext(request); context.saveErrorMessageToRequest("E-JX_ERRORS_TAG_TEST#0001"); context.saveErrorMessageToFlash("E-JX_ERRORS_TAG_TEST#0002"); FlashMap flashMap = RequestContextUtils.getOutputFlashMap(request); request.setAttribute(MessageContext.ERROR_MESSAGE_KEY_TO_FLASH, flashMap.get(MessageContext.ERROR_MESSAGE_KEY_TO_FLASH)); JseErrorsTag tag = new JseErrorsTag(); tag.setJspContext(page); tag.doTag(); assertThat(response.getContentAsString(), is("<div class=\"jfw_messages\">" + "<p class=\"jfw_err_msg_style\">E-JX_ERRORS_TAG_TEST#0001</p>" + "<p class=\"jfw_err_msg_style\">E-JX_ERRORS_TAG_TEST#0002</p></div>")); }
@Override public final FlashMap retrieveAndUpdate(HttpServletRequest request, HttpServletResponse response) { List<FlashMap> allFlashMaps = retrieveFlashMaps(request); if (CollectionUtils.isEmpty(allFlashMaps)) { return null; } if (logger.isDebugEnabled()) { logger.debug("Retrieved FlashMap(s): " + allFlashMaps); } List<FlashMap> mapsToRemove = getExpiredFlashMaps(allFlashMaps); FlashMap match = getMatchingFlashMap(allFlashMaps, request); if (match != null) { mapsToRemove.add(match); } if (!mapsToRemove.isEmpty()) { if (logger.isDebugEnabled()) { logger.debug("Removing FlashMap(s): " + mapsToRemove); } Object mutex = getFlashMapsMutex(request); if (mutex != null) { synchronized (mutex) { allFlashMaps = retrieveFlashMaps(request); if (allFlashMaps != null) { allFlashMaps.removeAll(mapsToRemove); updateFlashMaps(allFlashMaps, request, response); } } } else { allFlashMaps.removeAll(mapsToRemove); updateFlashMaps(allFlashMaps, request, response); } } return match; }
/** * Return a list of expired FlashMap instances contained in the given list. */ private List<FlashMap> getExpiredFlashMaps(List<FlashMap> allMaps) { List<FlashMap> result = new LinkedList<FlashMap>(); for (FlashMap map : allMaps) { if (map.isExpired()) { result.add(map); } } return result; }
/** * Retrieves saved FlashMap instances from the HTTP session, if any. */ @Override @SuppressWarnings("unchecked") protected List<FlashMap> retrieveFlashMaps(HttpServletRequest request) { HttpSession session = request.getSession(false); return (session != null ? (List<FlashMap>) session.getAttribute(FLASH_MAPS_SESSION_ATTRIBUTE) : null); }
@Before public void setUp() { this.request = new MockHttpServletRequest(); this.response = new MockHttpServletResponse(); this.request.setAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap()); this.request.setAttribute(DispatcherServlet.FLASH_MAP_MANAGER_ATTRIBUTE, new SessionFlashMapManager()); }
@Test public void http11() throws Exception { RedirectView rv = new RedirectView(); rv.setUrl("http://url.somewhere.com"); rv.setHttp10Compatible(false); MockHttpServletRequest request = createRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); request.setAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap()); request.setAttribute(DispatcherServlet.FLASH_MAP_MANAGER_ATTRIBUTE, new SessionFlashMapManager()); rv.render(new HashMap<String, Object>(), request, response); assertEquals(303, response.getStatus()); assertEquals("http://url.somewhere.com", response.getHeader("Location")); }
@Test public void retrieveAndUpdateMatchByPath() { FlashMap flashMap = new FlashMap(); flashMap.put("key", "value"); flashMap.setTargetRequestPath("/path"); this.flashMapManager.setFlashMaps(Arrays.asList(flashMap)); this.request.setRequestURI("/path"); FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(this.request, this.response); assertEquals(flashMap, inputFlashMap); }