View Javadoc
1   /*
2    * Copyright 2002-2014 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.web.servlet.mvc.method.annotation;
18  
19  import java.io.Serializable;
20  import java.lang.reflect.Method;
21  import java.util.ArrayList;
22  import java.util.List;
23  
24  import org.junit.Before;
25  import org.junit.Test;
26  
27  import org.springframework.core.MethodParameter;
28  import org.springframework.http.HttpEntity;
29  import org.springframework.http.MediaType;
30  import org.springframework.http.converter.HttpMessageConverter;
31  import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
32  import org.springframework.mock.web.test.MockHttpServletRequest;
33  import org.springframework.mock.web.test.MockHttpServletResponse;
34  import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
35  import org.springframework.web.bind.WebDataBinder;
36  import org.springframework.web.bind.support.WebDataBinderFactory;
37  import org.springframework.web.context.request.NativeWebRequest;
38  import org.springframework.web.context.request.ServletWebRequest;
39  import org.springframework.web.method.HandlerMethod;
40  import org.springframework.web.method.support.ModelAndViewContainer;
41  
42  import static org.junit.Assert.*;
43  
44  /**
45   * Test fixture with {@link HttpEntityMethodProcessor} delegating to
46   * actual {@link HttpMessageConverter} instances.
47   *
48   * <p>Also see {@link HttpEntityMethodProcessorMockTests}.
49   *
50   * @author Rossen Stoyanchev
51   */
52  public class HttpEntityMethodProcessorTests {
53  
54  	private MethodParameter paramList;
55  
56  	private MethodParameter paramSimpleBean;
57  
58  	private ModelAndViewContainer mavContainer;
59  
60  	private WebDataBinderFactory binderFactory;
61  
62  	private MockHttpServletRequest servletRequest;
63  
64  	private MockHttpServletResponse servletResponse;
65  
66  	private ServletWebRequest webRequest;
67  
68  
69  	@Before
70  	public void setUp() throws Exception {
71  		Method method = getClass().getMethod("handle", HttpEntity.class, HttpEntity.class);
72  		paramList = new MethodParameter(method, 0);
73  		paramSimpleBean = new MethodParameter(method, 1);
74  
75  		mavContainer = new ModelAndViewContainer();
76  		binderFactory = new ValidatingBinderFactory();
77  		servletRequest = new MockHttpServletRequest();
78  		servletResponse = new MockHttpServletResponse();
79  		webRequest = new ServletWebRequest(servletRequest, servletResponse);
80  	}
81  
82  	@Test
83  	public void resolveArgument() throws Exception {
84  		String content = "{\"name\" : \"Jad\"}";
85  		this.servletRequest.setContent(content.getBytes("UTF-8"));
86  		this.servletRequest.setContentType("application/json");
87  
88  		List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
89  		converters.add(new MappingJackson2HttpMessageConverter());
90  		HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor(converters);
91  
92  		@SuppressWarnings("unchecked")
93  		HttpEntity<SimpleBean> result = (HttpEntity<SimpleBean>) processor.resolveArgument(
94  				paramSimpleBean, mavContainer, webRequest, binderFactory);
95  
96  		assertNotNull(result);
97  		assertEquals("Jad", result.getBody().getName());
98  	}
99  
100 	@Test
101 	public void resolveGenericArgument() throws Exception {
102 		String content = "[{\"name\" : \"Jad\"}, {\"name\" : \"Robert\"}]";
103 		this.servletRequest.setContent(content.getBytes("UTF-8"));
104 		this.servletRequest.setContentType("application/json");
105 
106 		List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
107 		converters.add(new MappingJackson2HttpMessageConverter());
108 		HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor(converters);
109 
110 		@SuppressWarnings("unchecked")
111 		HttpEntity<List<SimpleBean>> result = (HttpEntity<List<SimpleBean>>) processor.resolveArgument(
112 				paramList, mavContainer, webRequest, binderFactory);
113 
114 		assertNotNull(result);
115 		assertEquals("Jad", result.getBody().get(0).getName());
116 		assertEquals("Robert", result.getBody().get(1).getName());
117 	}
118 
119 	@Test
120 	public void resolveArgumentTypeVariable() throws Exception {
121 		Method method = MySimpleParameterizedController.class.getMethod("handleDto", HttpEntity.class);
122 		HandlerMethod handlerMethod = new HandlerMethod(new MySimpleParameterizedController(), method);
123 		MethodParameter methodParam = handlerMethod.getMethodParameters()[0];
124 
125 		String content = "{\"name\" : \"Jad\"}";
126 		this.servletRequest.setContent(content.getBytes("UTF-8"));
127 		this.servletRequest.setContentType(MediaType.APPLICATION_JSON_VALUE);
128 
129 		List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
130 		converters.add(new MappingJackson2HttpMessageConverter());
131 		HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor(converters);
132 
133 		@SuppressWarnings("unchecked")
134 		HttpEntity<SimpleBean> result = (HttpEntity<SimpleBean>)
135 				processor.resolveArgument(methodParam, mavContainer, webRequest, binderFactory);
136 
137 		assertNotNull(result);
138 		assertEquals("Jad", result.getBody().getName());
139 	}
140 
141 
142 	public void handle(HttpEntity<List<SimpleBean>> arg1, HttpEntity<SimpleBean> arg2) {
143 	}
144 
145 
146 	private static abstract class MyParameterizedController<DTO extends Identifiable> {
147 
148 		public void handleDto(HttpEntity<DTO> dto) {
149 		}
150 	}
151 
152 
153 	private static class MySimpleParameterizedController extends MyParameterizedController<SimpleBean> {
154 	}
155 
156 
157 	private interface Identifiable extends Serializable {
158 
159 		public Long getId();
160 
161 		public void setId(Long id);
162 	}
163 
164 
165 	@SuppressWarnings({ "serial" })
166 	private static class SimpleBean implements Identifiable {
167 
168 		private Long id;
169 
170 		private String name;
171 
172 		@Override
173 		public Long getId() {
174 			return id;
175 		}
176 
177 		@Override
178 		public void setId(Long id) {
179 			this.id = id;
180 		}
181 
182 		public String getName() {
183 			return name;
184 		}
185 
186 		@SuppressWarnings("unused")
187 		public void setName(String name) {
188 			this.name = name;
189 		}
190 	}
191 
192 
193 	private final class ValidatingBinderFactory implements WebDataBinderFactory {
194 
195 		@Override
196 		public WebDataBinder createBinder(NativeWebRequest webRequest, Object target, String objectName) {
197 			LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
198 			validator.afterPropertiesSet();
199 			WebDataBinder dataBinder = new WebDataBinder(target, objectName);
200 			dataBinder.setValidator(validator);
201 			return dataBinder;
202 		}
203 	}
204 
205 }