Consistent Map/Set ordering
Use LinkedHashMaps/Sets wherever exposed to users, and code tests defensively in terms of expected Map/Set ordering. Otherwise, there'll be runtime order differences between JDK 7 and JDK 8 due to internal HashMap/Set implementation differences.
Issue: SPR-9639
(cherry picked from commit 9c09a0a)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -51,7 +51,7 @@ public abstract class AbstractHandlerExceptionResolver implements HandlerExcepti
|
||||
|
||||
private int order = Ordered.LOWEST_PRECEDENCE;
|
||||
|
||||
private Set mappedHandlers;
|
||||
private Set<?> mappedHandlers;
|
||||
|
||||
private Class[] mappedHandlerClasses;
|
||||
|
||||
@@ -76,7 +76,7 @@ public abstract class AbstractHandlerExceptionResolver implements HandlerExcepti
|
||||
* as fallback for all exceptions; any further HandlerExceptionResolvers in the chain will be
|
||||
* ignored in this case.
|
||||
*/
|
||||
public void setMappedHandlers(Set mappedHandlers) {
|
||||
public void setMappedHandlers(Set<?> mappedHandlers) {
|
||||
this.mappedHandlers = mappedHandlers;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -28,11 +28,12 @@ import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.util.WebUtils;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.web.servlet.HandlerExceptionResolver} implementation that allows for mapping exception
|
||||
* class names to view names, either for a set of given handlers or for all handlers in the DispatcherServlet.
|
||||
* {@link org.springframework.web.servlet.HandlerExceptionResolver} implementation
|
||||
* that allows for mapping exception class names to view names, either for a set of
|
||||
* given handlers or for all handlers in the DispatcherServlet.
|
||||
*
|
||||
* <p>Error views are analogous to error page JSPs, but can be used with any kind of exception including any checked
|
||||
* one, with fine-granular mappings for specific handlers.
|
||||
* <p>Error views are analogous to error page JSPs, but can be used with any kind of
|
||||
* exception including any checked one, with fine-granular mappings for specific handlers.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Arjen Poutsma
|
||||
@@ -87,18 +88,20 @@ public class SimpleMappingExceptionResolver extends AbstractHandlerExceptionReso
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the default error view. This view will be returned if no specific mapping was found. <p>Default is
|
||||
* none.
|
||||
* Set the name of the default error view.
|
||||
* This view will be returned if no specific mapping was found.
|
||||
* <p>Default is none.
|
||||
*/
|
||||
public void setDefaultErrorView(String defaultErrorView) {
|
||||
this.defaultErrorView = defaultErrorView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the HTTP status code that this exception resolver will apply for a given resolved error view. Keys are
|
||||
* view names; values are status codes.
|
||||
* <p>Note that this error code will only get applied in case of a top-level request. It will not be set for an include
|
||||
* request, since the HTTP status cannot be modified from within an include.
|
||||
* Set the HTTP status code that this exception resolver will apply for a given
|
||||
* resolved error view. Keys are view names; values are status codes.
|
||||
* <p>Note that this error code will only get applied in case of a top-level request.
|
||||
* It will not be set for an include request, since the HTTP status cannot be modified
|
||||
* from within an include.
|
||||
* <p>If not specified, the default status code will be applied.
|
||||
* @see #setDefaultStatusCode(int)
|
||||
*/
|
||||
@@ -127,12 +130,13 @@ public class SimpleMappingExceptionResolver extends AbstractHandlerExceptionReso
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default HTTP status code that this exception resolver will apply if it resolves an error view and if there
|
||||
* is no status code mapping defined.
|
||||
* <p>Note that this error code will only get applied in case of a top-level request. It will not be set for an
|
||||
* include request, since the HTTP status cannot be modified from within an include.
|
||||
* <p>If not specified, no status code will be applied, either leaving this to the controller or view, or keeping
|
||||
* the servlet engine's default of 200 (OK).
|
||||
* Set the default HTTP status code that this exception resolver will apply
|
||||
* if it resolves an error view and if there is no status code mapping defined.
|
||||
* <p>Note that this error code will only get applied in case of a top-level request.
|
||||
* It will not be set for an include request, since the HTTP status cannot be modified
|
||||
* from within an include.
|
||||
* <p>If not specified, no status code will be applied, either leaving this to the
|
||||
* controller or view, or keeping the servlet engine's default of 200 (OK).
|
||||
* @param defaultStatusCode HTTP status code value, for example 500
|
||||
* ({@link HttpServletResponse#SC_INTERNAL_SERVER_ERROR}) or 404 ({@link HttpServletResponse#SC_NOT_FOUND})
|
||||
* @see #setStatusCodes(Properties)
|
||||
@@ -142,31 +146,34 @@ public class SimpleMappingExceptionResolver extends AbstractHandlerExceptionReso
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the model attribute as which the exception should be exposed. Default is "exception". <p>This can be
|
||||
* either set to a different attribute name or to {@code null} for not exposing an exception attribute at all.
|
||||
* Set the name of the model attribute as which the exception should be exposed.
|
||||
* Default is "exception".
|
||||
* <p>This can be either set to a different attribute name or to {@code null}
|
||||
* for not exposing an exception attribute at all.
|
||||
* @see #DEFAULT_EXCEPTION_ATTRIBUTE
|
||||
*/
|
||||
public void setExceptionAttribute(String exceptionAttribute) {
|
||||
this.exceptionAttribute = exceptionAttribute;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Actually resolve the given exception that got thrown during on handler execution, returning a ModelAndView that
|
||||
* represents a specific error page if appropriate. <p>May be overridden in subclasses, in order to apply specific
|
||||
* exception checks. Note that this template method will be invoked <i>after</i> checking whether this resolved applies
|
||||
* ("mappedHandlers" etc), so an implementation may simply proceed with its actual exception handling.
|
||||
* Actually resolve the given exception that got thrown during on handler execution,
|
||||
* returning a ModelAndView that represents a specific error page if appropriate.
|
||||
* <p>May be overridden in subclasses, in order to apply specific exception checks.
|
||||
* Note that this template method will be invoked <i>after</i> checking whether this
|
||||
* resolved applies ("mappedHandlers" etc), so an implementation may simply proceed
|
||||
* with its actual exception handling.
|
||||
* @param request current HTTP request
|
||||
* @param response current HTTP response
|
||||
* @param handler the executed handler, or {@code null} if none chosen at the time of the exception (for example,
|
||||
* if multipart resolution failed)
|
||||
* @param handler the executed handler, or {@code null} if none chosen at the time
|
||||
* of the exception (for example, if multipart resolution failed)
|
||||
* @param ex the exception that got thrown during handler execution
|
||||
* @return a corresponding ModelAndView to forward to, or {@code null} for default processing
|
||||
*/
|
||||
@Override
|
||||
protected ModelAndView doResolveException(HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
Object handler,
|
||||
Exception ex) {
|
||||
protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response,
|
||||
Object handler, Exception ex) {
|
||||
|
||||
// Expose ModelAndView for chosen error view.
|
||||
String viewName = determineViewName(ex, request);
|
||||
@@ -231,7 +238,8 @@ public class SimpleMappingExceptionResolver extends AbstractHandlerExceptionReso
|
||||
for (Enumeration<?> names = exceptionMappings.propertyNames(); names.hasMoreElements();) {
|
||||
String exceptionMapping = (String) names.nextElement();
|
||||
int depth = getDepth(exceptionMapping, ex);
|
||||
if (depth >= 0 && depth < deepest) {
|
||||
if (depth >= 0 && (depth < deepest || (depth == deepest &&
|
||||
dominantMapping != null && exceptionMapping.length() > dominantMapping.length()))) {
|
||||
deepest = depth;
|
||||
dominantMapping = exceptionMapping;
|
||||
viewName = exceptionMappings.getProperty(exceptionMapping);
|
||||
|
||||
@@ -20,10 +20,10 @@ import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
@@ -86,7 +86,6 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
|
||||
|
||||
/**
|
||||
* Expose URI template variables, matrix variables, and producible media types in the request.
|
||||
*
|
||||
* @see HandlerMapping#URI_TEMPLATE_VARIABLES_ATTRIBUTE
|
||||
* @see HandlerMapping#MATRIX_VARIABLES_ATTRIBUTE
|
||||
* @see HandlerMapping#PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE
|
||||
@@ -149,19 +148,16 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
|
||||
/**
|
||||
* Iterate all RequestMappingInfos once again, look if any match by URL at
|
||||
* least and raise exceptions accordingly.
|
||||
*
|
||||
* @throws HttpRequestMethodNotSupportedException
|
||||
* if there are matches by URL but not by HTTP method
|
||||
* @throws HttpMediaTypeNotAcceptableException
|
||||
* if there are matches by URL but not by consumable media types
|
||||
* @throws HttpMediaTypeNotAcceptableException
|
||||
* if there are matches by URL but not by producible media types
|
||||
* @throws HttpRequestMethodNotSupportedException if there are matches by URL
|
||||
* but not by HTTP method
|
||||
* @throws HttpMediaTypeNotAcceptableException if there are matches by URL
|
||||
* but not by consumable/producible media types
|
||||
*/
|
||||
@Override
|
||||
protected HandlerMethod handleNoMatch(Set<RequestMappingInfo> requestMappingInfos,
|
||||
String lookupPath, HttpServletRequest request) throws ServletException {
|
||||
|
||||
Set<String> allowedMethods = new HashSet<String>(6);
|
||||
Set<String> allowedMethods = new LinkedHashSet<String>(4);
|
||||
|
||||
Set<RequestMappingInfo> patternMatches = new HashSet<RequestMappingInfo>();
|
||||
Set<RequestMappingInfo> patternAndMethodMatches = new HashSet<RequestMappingInfo>();
|
||||
@@ -193,12 +189,12 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
|
||||
|
||||
if (patternAndMethodMatches.isEmpty()) {
|
||||
consumableMediaTypes = getConsumableMediaTypes(request, patternMatches);
|
||||
producibleMediaTypes = getProdicubleMediaTypes(request, patternMatches);
|
||||
producibleMediaTypes = getProducibleMediaTypes(request, patternMatches);
|
||||
paramConditions = getRequestParams(request, patternMatches);
|
||||
}
|
||||
else {
|
||||
consumableMediaTypes = getConsumableMediaTypes(request, patternAndMethodMatches);
|
||||
producibleMediaTypes = getProdicubleMediaTypes(request, patternAndMethodMatches);
|
||||
producibleMediaTypes = getProducibleMediaTypes(request, patternAndMethodMatches);
|
||||
paramConditions = getRequestParams(request, patternAndMethodMatches);
|
||||
}
|
||||
|
||||
@@ -236,7 +232,7 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
|
||||
return result;
|
||||
}
|
||||
|
||||
private Set<MediaType> getProdicubleMediaTypes(HttpServletRequest request, Set<RequestMappingInfo> partialMatches) {
|
||||
private Set<MediaType> getProducibleMediaTypes(HttpServletRequest request, Set<RequestMappingInfo> partialMatches) {
|
||||
Set<MediaType> result = new HashSet<MediaType>();
|
||||
for (RequestMappingInfo partialMatch : partialMatches) {
|
||||
if (partialMatch.getProducesCondition().getMatchingCondition(request) == null) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -19,11 +19,10 @@ package org.springframework.web.servlet.view;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
@@ -70,7 +69,7 @@ public abstract class AbstractView extends WebApplicationObjectSupport implement
|
||||
private String requestContextAttribute;
|
||||
|
||||
/** Map of static attributes, keyed by attribute name (String) */
|
||||
private final Map<String, Object> staticAttributes = new HashMap<String, Object>();
|
||||
private final Map<String, Object> staticAttributes = new LinkedHashMap<String, Object>();
|
||||
|
||||
/** Whether or not the view should add path variables in the model */
|
||||
private boolean exposePathVariables = true;
|
||||
@@ -269,6 +268,7 @@ public abstract class AbstractView extends WebApplicationObjectSupport implement
|
||||
* Dynamic values take precedence over static attributes.
|
||||
*/
|
||||
protected Map<String, Object> createMergedOutputModel(Map<String, ?> model, HttpServletRequest request,
|
||||
|
||||
HttpServletResponse response) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> pathVars = this.exposePathVariables ?
|
||||
@@ -278,7 +278,7 @@ public abstract class AbstractView extends WebApplicationObjectSupport implement
|
||||
int size = this.staticAttributes.size();
|
||||
size += (model != null) ? model.size() : 0;
|
||||
size += (pathVars != null) ? pathVars.size() : 0;
|
||||
Map<String, Object> mergedModel = new HashMap<String, Object>(size);
|
||||
Map<String, Object> mergedModel = new LinkedHashMap<String, Object>(size);
|
||||
mergedModel.putAll(this.staticAttributes);
|
||||
if (pathVars != null) {
|
||||
mergedModel.putAll(pathVars);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -249,7 +249,7 @@ public class SimpleMappingExceptionResolverTests {
|
||||
exceptionResolver.setMappedHandlers(Collections.singleton(handler1));
|
||||
exceptionResolver.setExceptionMappings(props);
|
||||
ModelAndView mav = exceptionResolver.resolveException(request, response, handler1, oddException);
|
||||
assertEquals("error", mav.getViewName());
|
||||
assertEquals("another-error", mav.getViewName());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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.servlet.view.document;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.lowagie.text.Document;
|
||||
import com.lowagie.text.PageSize;
|
||||
import com.lowagie.text.Paragraph;
|
||||
import com.lowagie.text.pdf.PdfWriter;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.test.MockHttpServletResponse;
|
||||
|
||||
/**
|
||||
* @author Alef Arendsen
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class PdfViewTests extends TestCase {
|
||||
|
||||
public void testPdf() throws Exception {
|
||||
final String text = "this should be in the PDF";
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
AbstractPdfView pdfView = new AbstractPdfView() {
|
||||
@Override
|
||||
protected void buildPdfDocument(Map model, Document document, PdfWriter writer,
|
||||
HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
document.add(new Paragraph(text));
|
||||
}
|
||||
};
|
||||
|
||||
pdfView.render(new HashMap(), request, response);
|
||||
byte[] pdfContent = response.getContentAsByteArray();
|
||||
assertEquals("correct response content type", "application/pdf", response.getContentType());
|
||||
assertEquals("correct response content length", pdfContent.length, response.getContentLength());
|
||||
|
||||
// rebuild iText document for comparison
|
||||
Document document = new Document(PageSize.A4);
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
PdfWriter writer = PdfWriter.getInstance(document, baos);
|
||||
writer.setViewerPreferences(PdfWriter.AllowPrinting | PdfWriter.PageLayoutSinglePage);
|
||||
document.open();
|
||||
document.add(new Paragraph(text));
|
||||
document.close();
|
||||
byte[] baosContent = baos.toByteArray();
|
||||
assertEquals("correct size", pdfContent.length, baosContent.length);
|
||||
|
||||
int diffCount = 0;
|
||||
for (int i = 0; i < pdfContent.length; i++) {
|
||||
if (pdfContent[i] != baosContent[i]) {
|
||||
diffCount++;
|
||||
}
|
||||
}
|
||||
assertTrue("difference only in encryption", diffCount < 70);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright ${YEAR} the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -17,8 +17,8 @@
|
||||
package org.springframework.web.servlet.view.feed;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -27,16 +27,20 @@ import javax.servlet.http.HttpServletResponse;
|
||||
import com.sun.syndication.feed.atom.Content;
|
||||
import com.sun.syndication.feed.atom.Entry;
|
||||
import com.sun.syndication.feed.atom.Feed;
|
||||
import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
|
||||
import static org.custommonkey.xmlunit.XMLUnit.setIgnoreWhitespace;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.test.MockHttpServletResponse;
|
||||
|
||||
public class AtomFeedViewTest {
|
||||
import static org.custommonkey.xmlunit.XMLAssert.*;
|
||||
import static org.custommonkey.xmlunit.XMLUnit.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class AtomFeedViewTests {
|
||||
|
||||
private AbstractAtomFeedView view;
|
||||
|
||||
@@ -51,9 +55,9 @@ public class AtomFeedViewTest {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
Map<String, String> model = new HashMap<String, String>();
|
||||
model.put("1", "This is entry 1");
|
||||
Map<String, String> model = new LinkedHashMap<String, String>();
|
||||
model.put("2", "This is entry 2");
|
||||
model.put("1", "This is entry 1");
|
||||
|
||||
view.render(model, request, response);
|
||||
assertEquals("Invalid content-type", "application/atom+xml", response.getContentType());
|
||||
@@ -17,8 +17,8 @@
|
||||
package org.springframework.web.servlet.view.feed;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -27,16 +27,20 @@ import javax.servlet.http.HttpServletResponse;
|
||||
import com.sun.syndication.feed.rss.Channel;
|
||||
import com.sun.syndication.feed.rss.Description;
|
||||
import com.sun.syndication.feed.rss.Item;
|
||||
import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
|
||||
import static org.custommonkey.xmlunit.XMLUnit.setIgnoreWhitespace;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.test.MockHttpServletResponse;
|
||||
|
||||
public class RssFeedViewTest {
|
||||
import static org.custommonkey.xmlunit.XMLAssert.*;
|
||||
import static org.custommonkey.xmlunit.XMLUnit.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class RssFeedViewTests {
|
||||
|
||||
private AbstractRssFeedView view;
|
||||
|
||||
@@ -52,9 +56,9 @@ public class RssFeedViewTest {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
Map<String, String> model = new HashMap<String, String>();
|
||||
model.put("1", "This is entry 1");
|
||||
Map<String, String> model = new LinkedHashMap<String, String>();
|
||||
model.put("2", "This is entry 2");
|
||||
model.put("1", "This is entry 1");
|
||||
|
||||
view.render(model, request, response);
|
||||
assertEquals("Invalid content-type", "application/rss+xml", response.getContentType());
|
||||
Reference in New Issue
Block a user