@Test // SPR-12149 public void jacksonJsonViewWithResponseBodyAndXmlMessageConverter() throws Exception { Method method = JacksonController.class.getMethod("handleResponseBody"); HandlerMethod handlerMethod = new HandlerMethod(new JacksonController(), method); MethodParameter methodReturnType = handlerMethod.getReturnType(); List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>(); converters.add(new MappingJackson2XmlHttpMessageConverter()); RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor( converters, null, Collections.singletonList(new JsonViewResponseBodyAdvice())); Object returnValue = new JacksonController().handleResponseBody(); processor.handleReturnValue(returnValue, methodReturnType, this.mavContainer, this.webRequest); String content = this.servletResponse.getContentAsString(); assertFalse(content.contains("<withView1>with</withView1>")); assertTrue(content.contains("<withView2>with</withView2>")); assertFalse(content.contains("<withoutView>without</withoutView>")); }
@Test // SPR-12149 public void jacksonJsonViewWithResponseEntityAndXmlMessageConverter() throws Exception { Method method = JacksonController.class.getMethod("handleResponseEntity"); HandlerMethod handlerMethod = new HandlerMethod(new JacksonController(), method); MethodParameter methodReturnType = handlerMethod.getReturnType(); List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>(); converters.add(new MappingJackson2XmlHttpMessageConverter()); HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor( converters, null, Collections.singletonList(new JsonViewResponseBodyAdvice())); Object returnValue = new JacksonController().handleResponseEntity(); processor.handleReturnValue(returnValue, methodReturnType, this.mavContainer, this.webRequest); String content = this.servletResponse.getContentAsString(); assertFalse(content.contains("<withView1>with</withView1>")); assertTrue(content.contains("<withView2>with</withView2>")); assertFalse(content.contains("<withoutView>without</withoutView>")); }
@Test // SPR-12501 public void resolveArgumentWithJacksonJsonViewAndXmlMessageConverter() throws Exception { String content = "<root><withView1>with</withView1><withView2>with</withView2><withoutView>without</withoutView></root>"; this.servletRequest.setContent(content.getBytes("UTF-8")); this.servletRequest.setContentType(MediaType.APPLICATION_XML_VALUE); Method method = JacksonController.class.getMethod("handleRequestBody", JacksonViewBean.class); HandlerMethod handlerMethod = new HandlerMethod(new JacksonController(), method); MethodParameter methodParameter = handlerMethod.getMethodParameters()[0]; List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>(); converters.add(new MappingJackson2XmlHttpMessageConverter()); RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor( converters, null, Collections.singletonList(new JsonViewRequestBodyAdvice())); @SuppressWarnings("unchecked") JacksonViewBean result = (JacksonViewBean)processor.resolveArgument(methodParameter, this.mavContainer, this.webRequest, this.binderFactory); assertNotNull(result); assertEquals("with", result.getWithView1()); assertNull(result.getWithView2()); assertNull(result.getWithoutView()); }
@Test // SPR-12501 public void resolveHttpEntityArgumentWithJacksonJsonViewAndXmlMessageConverter() throws Exception { String content = "<root><withView1>with</withView1><withView2>with</withView2><withoutView>without</withoutView></root>"; this.servletRequest.setContent(content.getBytes("UTF-8")); this.servletRequest.setContentType(MediaType.APPLICATION_XML_VALUE); Method method = JacksonController.class.getMethod("handleHttpEntity", HttpEntity.class); HandlerMethod handlerMethod = new HandlerMethod(new JacksonController(), method); MethodParameter methodParameter = handlerMethod.getMethodParameters()[0]; List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>(); converters.add(new MappingJackson2XmlHttpMessageConverter()); HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor( converters, null, Collections.singletonList(new JsonViewRequestBodyAdvice())); @SuppressWarnings("unchecked") HttpEntity<JacksonViewBean> result = (HttpEntity<JacksonViewBean>)processor.resolveArgument(methodParameter, this.mavContainer, this.webRequest, this.binderFactory); assertNotNull(result); assertNotNull(result.getBody()); assertEquals("with", result.getBody().getWithView1()); assertNull(result.getBody().getWithView2()); assertNull(result.getBody().getWithoutView()); }
public AllEncompassingFormHttpMessageConverter() { addPartConverter(new SourceHttpMessageConverter<Source>()); if (jaxb2Present && !jackson2Present) { addPartConverter(new Jaxb2RootElementHttpMessageConverter()); } if (jackson2Present) { addPartConverter(new MappingJackson2HttpMessageConverter()); } else if (gsonPresent) { addPartConverter(new GsonHttpMessageConverter()); } if (jackson2XmlPresent) { addPartConverter(new MappingJackson2XmlHttpMessageConverter()); } }
@Test public void defaultJacksonConvertersWithBuilder() throws Exception { this.context.register(JacksonObjectMapperBuilderConfig.class, HttpMessageConvertersAutoConfiguration.class); this.context.refresh(); assertConverterBeanExists(MappingJackson2HttpMessageConverter.class, "mappingJackson2HttpMessageConverter"); assertConverterBeanExists(MappingJackson2XmlHttpMessageConverter.class, "mappingJackson2XmlHttpMessageConverter"); assertConverterBeanRegisteredWithHttpMessageConverters( MappingJackson2HttpMessageConverter.class); assertConverterBeanRegisteredWithHttpMessageConverters( MappingJackson2XmlHttpMessageConverter.class); }
@Test public void containsDefaults() throws Exception { HttpMessageConverters converters = new HttpMessageConverters(); List<Class<?>> converterClasses = new ArrayList<Class<?>>(); for (HttpMessageConverter<?> converter : converters) { converterClasses.add(converter.getClass()); } assertThat(converterClasses, equalTo(Arrays.<Class<?>>asList(ByteArrayHttpMessageConverter.class, StringHttpMessageConverter.class, ResourceHttpMessageConverter.class, SourceHttpMessageConverter.class, AllEncompassingFormHttpMessageConverter.class, MappingJackson2HttpMessageConverter.class, MappingJackson2XmlHttpMessageConverter.class))); }
/** * This is called from requestMappingHandlerAdapter to configure the message converters. We override it to configure our own converter in addition to the * default converters. * * @param converters the converter list we configure. */ @Override @SuppressWarnings("rawtypes") protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) { // Add in our custom converter first. converters.add(marshallingMessageConverter()); // Add in the default converters (e.g. standard JAXB, Jackson, etc.). addDefaultHttpMessageConverters(converters); // Remove the Jackson2Xml converter since we want to use JAXB instead when we encounter "application/xml". Otherwise, the XSD auto-generated // classes with JAXB annotations won't get used. // Set jackson mapper to include only properties with non-null values. for (HttpMessageConverter httpMessageConverter : converters) { if (httpMessageConverter instanceof MappingJackson2XmlHttpMessageConverter) { converters.remove(httpMessageConverter); break; } } }
/** * springboot初始化restTemplate */ @Bean public RestTemplate initRestTemplate() { // 长连接保持30秒 PoolingHttpClientConnectionManager pollingConnectionManager = new PoolingHttpClientConnectionManager(30, TimeUnit.SECONDS); // 总连接数 pollingConnectionManager.setMaxTotal(1000); // 同路由的并发数 pollingConnectionManager.setDefaultMaxPerRoute(1000); HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); httpClientBuilder.setConnectionManager(pollingConnectionManager); // 重试次数,默认是3次,没有开启 httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(2, true)); // 保持长连接配置,需要在头添加Keep-Alive httpClientBuilder.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy()); RequestConfig.Builder builder = RequestConfig.custom(); builder.setConnectionRequestTimeout(200); builder.setConnectTimeout(5000); builder.setSocketTimeout(5000); RequestConfig requestConfig = builder.build(); httpClientBuilder.setDefaultRequestConfig(requestConfig); List<Header> headers = new ArrayList<>(); headers.add(new BasicHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.16 Safari/537.36")); headers.add(new BasicHeader("Accept-Encoding", "gzip,deflate")); headers.add(new BasicHeader("Accept-Language", "zh-CN")); headers.add(new BasicHeader("Connection", "Keep-Alive")); httpClientBuilder.setDefaultHeaders(headers); HttpClient httpClient = httpClientBuilder.build(); // httpClient连接配置,底层是配置RequestConfig HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); // 连接超时 clientHttpRequestFactory.setConnectTimeout(5000); // 数据读取超时时间,即SocketTimeout clientHttpRequestFactory.setReadTimeout(5000); // 连接不够用的等待时间,不宜过长,必须设置,比如连接不够用时,时间过长将是灾难性的 clientHttpRequestFactory.setConnectionRequestTimeout(200); // 缓冲请求数据,默认值是true。通过POST或者PUT大量发送数据时,建议将此属性更改为false,以免耗尽内存。 clientHttpRequestFactory.setBufferRequestBody(false); // 添加内容转换器 List<HttpMessageConverter<?>> messageConverters = new ArrayList<>(); messageConverters.add(initStringHttpMessageConverter()); messageConverters.add(new FormHttpMessageConverter()); messageConverters.add(new MappingJackson2XmlHttpMessageConverter()); messageConverters.add(new MappingJackson2HttpMessageConverter()); RestTemplate restTemplate = new RestTemplate(messageConverters); restTemplate.setRequestFactory(clientHttpRequestFactory); restTemplate.setErrorHandler(new DefaultResponseErrorHandler()); return restTemplate; }
@Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); builder.indentOutput(true).dateFormat(new SimpleDateFormat("yyyy-MM-dd")); converters.add(new MappingJackson2HttpMessageConverter(builder.build())); converters.add(new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build())); }
@Test public void requestMappingHandlerAdapter() throws Exception { ApplicationContext context = initContext(WebConfig.class); RequestMappingHandlerAdapter adapter = context.getBean(RequestMappingHandlerAdapter.class); List<HttpMessageConverter<?>> converters = adapter.getMessageConverters(); assertEquals(9, converters.size()); for(HttpMessageConverter<?> converter : converters) { if (converter instanceof AbstractJackson2HttpMessageConverter) { ObjectMapper objectMapper = ((AbstractJackson2HttpMessageConverter)converter).getObjectMapper(); assertFalse(objectMapper.getDeserializationConfig().isEnabled(MapperFeature.DEFAULT_VIEW_INCLUSION)); assertFalse(objectMapper.getSerializationConfig().isEnabled(MapperFeature.DEFAULT_VIEW_INCLUSION)); assertFalse(objectMapper.getDeserializationConfig().isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)); if (converter instanceof MappingJackson2XmlHttpMessageConverter) { assertEquals(XmlMapper.class, objectMapper.getClass()); } } } ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer) adapter.getWebBindingInitializer(); assertNotNull(initializer); ConversionService conversionService = initializer.getConversionService(); assertNotNull(conversionService); assertTrue(conversionService instanceof FormattingConversionService); Validator validator = initializer.getValidator(); assertNotNull(validator); assertTrue(validator instanceof LocalValidatorFactoryBean); DirectFieldAccessor fieldAccessor = new DirectFieldAccessor(adapter); @SuppressWarnings("unchecked") List<Object> bodyAdvice = (List<Object>) fieldAccessor.getPropertyValue("requestResponseBodyAdvice"); assertEquals(2, bodyAdvice.size()); assertEquals(JsonViewRequestBodyAdvice.class, bodyAdvice.get(0).getClass()); assertEquals(JsonViewResponseBodyAdvice.class, bodyAdvice.get(1).getClass()); }
/** * Create a new instance of the {@link RestTemplate} using default settings. * Default {@link HttpMessageConverter}s are initialized. */ public RestTemplate() { this.messageConverters.add(new ByteArrayHttpMessageConverter()); this.messageConverters.add(new StringHttpMessageConverter()); this.messageConverters.add(new ResourceHttpMessageConverter()); this.messageConverters.add(new SourceHttpMessageConverter<Source>()); this.messageConverters.add(new AllEncompassingFormHttpMessageConverter()); if (romePresent) { this.messageConverters.add(new AtomFeedHttpMessageConverter()); this.messageConverters.add(new RssChannelHttpMessageConverter()); } if (jackson2XmlPresent) { this.messageConverters.add(new MappingJackson2XmlHttpMessageConverter()); } else if (jaxb2Present) { this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter()); } if (jackson2Present) { this.messageConverters.add(new MappingJackson2HttpMessageConverter()); } else if (gsonPresent) { this.messageConverters.add(new GsonHttpMessageConverter()); } }
@Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder = new Jackson2ObjectMapperBuilder() .annotationIntrospector(new JaxbAnnotationIntrospector(TypeFactory.defaultInstance())) .indentOutput(true); converters.add(new StringHttpMessageConverter()); converters.add(new MappingJackson2HttpMessageConverter()); converters.add(new MappingJackson2XmlHttpMessageConverter( jacksonObjectMapperBuilder .createXmlMapper(true) .build())); }
@Bean @ConditionalOnMissingBean public MappingJackson2XmlHttpMessageConverter mappingJackson2XmlHttpMessageConverter( Jackson2ObjectMapperBuilder builder) { return new MappingJackson2XmlHttpMessageConverter( builder.createXmlMapper(true).build()); }
private void reorderXmlConvertersToEnd(List<HttpMessageConverter<?>> converters) { List<HttpMessageConverter<?>> xml = new ArrayList<HttpMessageConverter<?>>(); for (Iterator<HttpMessageConverter<?>> iterator = converters.iterator(); iterator .hasNext();) { HttpMessageConverter<?> converter = iterator.next(); if ((converter instanceof AbstractXmlHttpMessageConverter) || (converter instanceof MappingJackson2XmlHttpMessageConverter)) { xml.add(converter); iterator.remove(); } } converters.addAll(xml); }
@Test public void containsDefaults() throws Exception { HttpMessageConverters converters = new HttpMessageConverters(); List<Class<?>> converterClasses = new ArrayList<Class<?>>(); for (HttpMessageConverter<?> converter : converters) { converterClasses.add(converter.getClass()); } assertThat(converterClasses).containsExactly(ByteArrayHttpMessageConverter.class, StringHttpMessageConverter.class, ResourceHttpMessageConverter.class, SourceHttpMessageConverter.class, AllEncompassingFormHttpMessageConverter.class, MappingJackson2HttpMessageConverter.class, MappingJackson2XmlHttpMessageConverter.class); }
@Test public void noObjectMapperMeansNoConverter() throws Exception { this.context.register(HttpMessageConvertersAutoConfiguration.class); this.context.refresh(); assertThat(this.context.getBeansOfType(ObjectMapper.class)).isEmpty(); assertThat(this.context.getBeansOfType(MappingJackson2HttpMessageConverter.class)) .isEmpty(); assertThat( this.context.getBeansOfType(MappingJackson2XmlHttpMessageConverter.class)) .isEmpty(); }
@Test public void noObjectMapperMeansNoConverter() throws Exception { this.context.register(HttpMessageConvertersAutoConfiguration.class); this.context.refresh(); assertTrue(this.context.getBeansOfType(ObjectMapper.class).isEmpty()); assertTrue(this.context.getBeansOfType(MappingJackson2HttpMessageConverter.class) .isEmpty()); assertTrue(this.context .getBeansOfType(MappingJackson2XmlHttpMessageConverter.class).isEmpty()); }
@Override public MockMvc mvc() { final ObjectMapper mapper = mapper(); return MockMvcBuilders.standaloneSetup(new ExampleRestController()) .setControllerAdvice(unit()) .setMessageConverters( new MappingJackson2HttpMessageConverter(mapper), new MappingJackson2XmlHttpMessageConverter()) .build(); }
@Test public void testDefaultConfig() throws Exception { loadBeanDefinitions("mvc-config.xml", 14); RequestMappingHandlerMapping mapping = appContext.getBean(RequestMappingHandlerMapping.class); assertNotNull(mapping); assertEquals(0, mapping.getOrder()); assertTrue(mapping.getUrlPathHelper().shouldRemoveSemicolonContent()); mapping.setDefaultHandler(handlerMethod); MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo.json"); NativeWebRequest webRequest = new ServletWebRequest(request); ContentNegotiationManager manager = mapping.getContentNegotiationManager(); assertEquals(Arrays.asList(MediaType.APPLICATION_JSON), manager.resolveMediaTypes(webRequest)); RequestMappingHandlerAdapter adapter = appContext.getBean(RequestMappingHandlerAdapter.class); assertNotNull(adapter); assertEquals(false, new DirectFieldAccessor(adapter).getPropertyValue("ignoreDefaultModelOnRedirect")); List<HttpMessageConverter<?>> converters = adapter.getMessageConverters(); assertTrue(converters.size() > 0); for (HttpMessageConverter<?> converter : converters) { if (converter instanceof AbstractJackson2HttpMessageConverter) { ObjectMapper objectMapper = ((AbstractJackson2HttpMessageConverter) converter).getObjectMapper(); assertFalse(objectMapper.getDeserializationConfig().isEnabled(MapperFeature.DEFAULT_VIEW_INCLUSION)); assertFalse(objectMapper.getSerializationConfig().isEnabled(MapperFeature.DEFAULT_VIEW_INCLUSION)); assertFalse(objectMapper.getDeserializationConfig().isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)); if (converter instanceof MappingJackson2XmlHttpMessageConverter) { assertEquals(XmlMapper.class, objectMapper.getClass()); } } } assertNotNull(appContext.getBean(FormattingConversionServiceFactoryBean.class)); assertNotNull(appContext.getBean(ConversionService.class)); assertNotNull(appContext.getBean(LocalValidatorFactoryBean.class)); assertNotNull(appContext.getBean(Validator.class)); // default web binding initializer behavior test request = new MockHttpServletRequest("GET", "/"); request.addParameter("date", "2009-10-31"); request.addParameter("percent", "99.99%"); MockHttpServletResponse response = new MockHttpServletResponse(); HandlerExecutionChain chain = mapping.getHandler(request); assertEquals(1, chain.getInterceptors().length); assertTrue(chain.getInterceptors()[0] instanceof ConversionServiceExposingInterceptor); ConversionServiceExposingInterceptor interceptor = (ConversionServiceExposingInterceptor) chain.getInterceptors()[0]; interceptor.preHandle(request, response, handlerMethod); assertSame(appContext.getBean(ConversionService.class), request.getAttribute(ConversionService.class.getName())); adapter.handle(request, response, handlerMethod); assertTrue(handler.recordedValidationError); assertEquals(LocalDate.parse("2009-10-31").toDate(), handler.date); assertEquals(Double.valueOf(0.9999), handler.percent); CompositeUriComponentsContributor uriComponentsContributor = this.appContext.getBean( MvcUriComponentsBuilder.MVC_URI_COMPONENTS_CONTRIBUTOR_BEAN_NAME, CompositeUriComponentsContributor.class); assertNotNull(uriComponentsContributor); }
static public String xml(MappingJackson2XmlHttpMessageConverter mapping, Object o) throws IOException { MockHttpOutputMessage mockHttpOutputMessage = new MockHttpOutputMessage(); mapping.write(o, MediaType.APPLICATION_XML, mockHttpOutputMessage); return mockHttpOutputMessage.getBodyAsString(); }
private void filterXmlConverters(RestTemplate restTemplate) { Stream<HttpMessageConverter<?>> messageConverterStream = restTemplate.getMessageConverters().stream(); Predicate<HttpMessageConverter<?>> noXmlConverters = httpMessageConverter -> !(httpMessageConverter instanceof Jaxb2RootElementHttpMessageConverter) && !(httpMessageConverter instanceof MappingJackson2XmlHttpMessageConverter); List<HttpMessageConverter<?>> filtered = messageConverterStream.filter(noXmlConverters).collect(Collectors.toList()); restTemplate.setMessageConverters(filtered); }
private HttpMessageConverter<Object> createXmlHttpMessageConverter() { Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.xml(); builder.indentOutput(true); return new MappingJackson2XmlHttpMessageConverter(builder.build()); }
protected HttpMessageConverter<?> getXmlConverter() { MappingJackson2XmlHttpMessageConverter converter = new MappingJackson2XmlHttpMessageConverter(); converter.setObjectMapper(JacksonUtils.XML_MAPPER); // use shared mapper return converter; }
/** * Subclasses might override this method to use JAXB natively for XML serialization by * {@code return new Jaxb2RootElementHttpMessageConverter()} * @see {@link #getObjectMapper(boolean)} */ protected HttpMessageConverter<?> getXmlConverter() { return new MappingJackson2XmlHttpMessageConverter(getObjectMapper(true)); }