最近在优化项目,将里面的交易日志插入部分分离了出来,现在就要将主系统得到的日志发送到
日志系统,来减轻主项目对数据库的压力,现将日志发送给日志系统的方案有三个,其一为
RestTemplate发送,其二为kafka,其三为PostMethod。此处仅讲解RestTemplate的具体用
法,以备后用。
服务端代码
@RequestMapping("/json.do")
public void myJson(@RequestParam("repo") String repo, HttpServletResponse po) throws Exception {
System.out.println(repo);
JSONObject jo = new JSONObject();
jo.put("message",
"{ringDialTime=\"1111122\", ringdialTimestamp=\"1513059248647\", establishedTimestamp=\"1513099248647\"}");
po.getWriter().write(jo.toString());
}
@RequestMapping("/getEntity.do")
public void getEntity(@RequestBody User user, HttpServletResponse po) throws Exception {
System.out.println(user.getName());
JSONObject jo = new JSONObject();
jo.put("message",
"{ringDialTime=\"1111122\", ringdialTimestamp=\"1513059248647\", establishedTimestamp=\"1513099248647\"}");
po.getWriter().write(jo.toString());
}
客户端代码
public static void main(String[] args) throws HttpException, IOException {
RestTemplate pp =new RestTemplate();
User a = new User();
a.setEmail("email");
a.setName("ljp");
ResponseEntity<String> postForEntity = pp.postForEntity("http://127.0.0.1:8081/SpringMVC-T/inde/getEntity.do",a,String.class);//传递实体
ResponseEntity<String> postForEntity2 = pp.postForEntity("http://127.0.0.1:8081/SpringMVC-T/inde/json.do?repo=ljp",null,String.class);//传参
System.out.println(postForEntity+"\n"+postForEntity2);
System.out.println(postForEntity.getBody());
}
客户端接收的返回值
可以看到服务器端返回的json串,可以通过postForEntity.getBody()
获取得到{"message":"{ringDialTime=\"1111122\"}"}
,具体返回的数据可以做交互验证之类的操作
服务器端接收到的数据展示
由此可以看到服务器端完全接收到了传递的参数和对象
**
解决方案
**
跨域传输的对象参数之间难免有汉字,但是restTemplate 的请求默认的参数是iso-9958-1,这个时候就出现了乱码的问题,我在网上也找了不少方法,很多的都是如下
RestTemplate restTemplate = new RestTemplateBuilder().additionalMessageConverters(m).build();
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(type);
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
String jsonStr = JSONObject.toJSONString(params);
HttpEntity formEntity = new HttpEntity( headers);
String result = restTemplate.getForObject("http://www.baidu.com", String.class);
但是我的并不行,依然是乱码,然后只好用了个笨方法,重写了 StringHttpMessageConverter 这个类,这个效果是立竿见影,立马就好了
package org.springframework.http.converter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.SortedMap;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.util.StreamUtils;
public class StringHttpMessageConverter
extends AbstractHttpMessageConverter<String>
{
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private final Charset defaultCharset;
private final List<Charset> availableCharsets;
private boolean writeAcceptCharset = true;
public StringHttpMessageConverter()
{
this(DEFAULT_CHARSET);
}
public StringHttpMessageConverter(Charset defaultCharset)
{
super(new MediaType[] { new MediaType("text", "plain", defaultCharset), MediaType.ALL });
this.defaultCharset = defaultCharset;
this.availableCharsets = new ArrayList(Charset.availableCharsets().values());
}
public void setWriteAcceptCharset(boolean writeAcceptCharset)
{
this.writeAcceptCharset = writeAcceptCharset;
}
public boolean supports(Class<?> clazz)
{
return String.class.equals(clazz);
}
protected String readInternal(Class<? extends String> clazz, HttpInputMessage inputMessage) throws IOException
{
Charset charset = getContentTypeCharset(inputMessage.getHeaders().getContentType());
return StreamUtils.copyToString(inputMessage.getBody(), charset);
}
protected Long getContentLength(String s, MediaType contentType)
{
Charset charset = getContentTypeCharset(contentType);
try {
return Long.valueOf(s.getBytes(charset.name()).length);
}
catch (UnsupportedEncodingException ex)
{
throw new IllegalStateException(ex);
}
}
protected void writeInternal(String s, HttpOutputMessage outputMessage) throws IOException
{
if (this.writeAcceptCharset) {
outputMessage.getHeaders().setAcceptCharset(getAcceptedCharsets());
}
Charset charset = getContentTypeCharset(outputMessage.getHeaders().getContentType());
StreamUtils.copy(s, charset, outputMessage.getBody());
}
protected List<Charset> getAcceptedCharsets()
{
return this.availableCharsets;
}
private Charset getContentTypeCharset(MediaType contentType) {
if ((contentType != null) && (contentType.getCharSet() != null)) {
return contentType.getCharSet();
}
return this.defaultCharset;
}
}
我们知道,调用reseful接口传递的数据内容是json格式的字符串,返回的响应也是json格式的字符串。然而restTemplate.postForObject方法的请求参数RequestBean和返回参数ResponseBean却都是java类。是RestTemplate通过HttpMessageConverter自动帮我们做了转换的操作。想要详细了解的可以看看这篇:https://www.jianshu.com/p/c9644755dd5e,