springboot默认采用Jenkins作为JSON解析器,而我们在实际开发中,需要对实体做一些特殊处理。比如日期格式化,属性忽略等。常用fastjson代替默认的JSON解析器。
1:引入fastJson的依赖
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fastjson.version}</version> </dependency>
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.3</version> </dependency>
2:
package com.itclj.config;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4;
import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.web.client.RestTemplate;
/**
* Fastjson配置,
*
* 把spring-boot默认的json解析器由Jenkins换为fastjson
* Created by lujun.chen on 2017/4/18.
*/
@Configuration
public class FastjsonConfiguration {
@Bean
public HttpMessageConverters fastjsonConverter() {
FastJsonConfig fastJsonConfig = new FastJsonConfig();
//自定义格式化输出
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat,
SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.WriteNullNumberAsZero);
FastJsonHttpMessageConverter4 fastjson = new FastJsonHttpMessageConverter4();
fastjson.setFastJsonConfig(fastJsonConfig);
return new HttpMessageConverters(fastjson);
}
}
3:配置RestTemplate
package com.itclj.config;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4;
import java.nio.charset.StandardCharsets;
import java.util.List;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;
/**
* Rest Template config
* Created by lujun.chen on 2017/4/17.
*/
@Configuration
@ConditionalOnClass(value = {RestTemplate.class, HttpClient.class})
public class RestTemplateConfiguration {
@Value("${remote.maxTotalConnect:0}")
private int maxTotalConnect; //连接池的最大连接数默认为0
@Value("${remote.maxConnectPerRoute:200}")
private int maxConnectPerRoute; //单个主机的最大连接数
@Value("${remote.connectTimeout:2000}")
private int connectTimeout; //连接超时默认2s
@Value("${remote.readTimeout:30000}")
private int readTimeout; //读取超时默认30s
private ClientHttpRequestFactory createFactory() {
if (this.maxTotalConnect <= 0) {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(this.connectTimeout);
factory.setReadTimeout(this.readTimeout);
return factory;
}
HttpClient httpClient = HttpClientBuilder.create().setMaxConnTotal(this.maxTotalConnect)
.setMaxConnPerRoute(this.maxConnectPerRoute).build();
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(
httpClient);
factory.setConnectTimeout(this.connectTimeout);
factory.setReadTimeout(this.readTimeout);
return factory;
}
@Bean
@ConditionalOnMissingBean(RestTemplate.class)
public RestTemplate getRestTemplate() {
RestTemplate restTemplate = new RestTemplate(this.createFactory());
List<HttpMessageConverter<?>> converterList = restTemplate.getMessageConverters();
HttpMessageConverter<?> converterTarget = null;
for (HttpMessageConverter<?> item : converterList) {
if (StringHttpMessageConverter.class == item.getClass()) {
converterTarget = item;
break;
}
}
if (null != converterTarget) {
converterList.remove(converterTarget);
}
converterList.add(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
converterList.add(new FastJsonHttpMessageConverter4());
return restTemplate;
}
}
4:测试
注意:如果以实体的格式进行传参。服务端的方法入参需要用@RequestBody修饰。否则无法接受到参数
package com.itclj;
import com.alibaba.fastjson.JSON;
import com.itclj.bean.UserBean;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.util.Date;
/**
* Created by lujun.chen on 2017/4/17.
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class RestClientTest {
private Logger logger = LoggerFactory.getLogger(RestClientTest.class);
private RestTemplate restTemplate;
@Before
public void setRestTemplate(){
restTemplate = new RestTemplate();
}
/**
* 模拟RestTemp 客户端调用
*
* 以实体对象直接向服务端传参数的时候服务端需加上@RequestBody注解
*/
@Test
public void restClient() {
UserBean u = new UserBean();
u.setName("zs");
u.setAge(30);
u.setBirthday(new Date());
String result = restTemplate
.postForObject("http://127.0.0.1:8280/user/add", u, String.class);
logger.info("result:{}", result);
}
/**
* MultiValueMap传参
*
* 这种方式服务端是接受得到参数的
*/
@Test
public void multiValueMapParam() {
MultiValueMap<String, String> requestParam = new LinkedMultiValueMap<>();
requestParam.set("name", "张三");
UserBean result = restTemplate
.postForObject("http://127.0.0.1:8280/user/add", requestParam, UserBean.class);
logger.info("result:{}", JSON.toJSON(result));
}
}