Closed vieyahn2017 closed 5 years ago
11.12 终于发现,坑了那么久的问题:
原因竟然是该class不是public的
2018-11-12 09:21:05.533 ERROR 10192 --- [http-nio-8080-exec-9] o.a.c.c.C.[.[.[.0].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [/fusion1.0] threw exception [Request processing failed; nested exception is org.springframework.beans.InvalidPropertyException: Invalid property 'edges[0]' of bean class [com.huawei.bigdata.algorithms.visualization.model.domain.EdgeDTOList]: Illegal attempt to get property 'edges' threw exception; nested exception is org.springframework.beans.NullValueInNestedPathException: Invalid property 'edges' of bean class [com.huawei.bigdata.algorithms.visualization.model.domain.EdgeDTOList]: Could not instantiate property type [com.huawei.bigdata.algorithms.visualization.model.domain.CapitalFlowEdgeDTO] to auto-grow nested property path; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.huawei.bigdata.algorithms.visualization.model.domain.CapitalFlowEdgeDTO]: Is the constructor accessible?; nested exception is java.lang.IllegalAccessException: Class org.springframework.beans.BeanUtils can not access a member of class com.huawei.bigdata.algorithms.visualization.model.domain.CapitalFlowEdgeDTO with modifiers ""] with root cause
java.lang.IllegalAccessException: Class org.springframework.beans.BeanUtils can not access a member of class com.huawei.bigdata.algorithms.visualization.model.domain.CapitalFlowEdgeDTO with modifiers ""
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102) ~[na:1.8.0_131]
at java.lang.Class.newInstance(Class.java:436) ~[na:1.8.0_131]
at org.springframework.beans.BeanUtils.instantiate(BeanUtils.java:77) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.AbstractNestablePropertyAccessor.newValue(AbstractNestablePropertyAccessor.java:928) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.AbstractNestablePropertyAccessor.growCollectionIfNecessary(AbstractNestablePropertyAccessor.java:796) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyValue(AbstractNestablePropertyAccessor.java:665) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.AbstractNestablePropertyAccessor.getNestedPropertyAccessor(AbstractNestablePropertyAccessor.java:850) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyAccessorForPropertyPath(AbstractNestablePropertyAccessor.java:827) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:270) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:95) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.validation.DataBinder.applyPropertyValues(DataBinder.java:859) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.validation.DataBinder.doBind(DataBinder.java:755) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.web.bind.WebDataBinder.doBind(WebDataBinder.java:192) ~[spring-web-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.web.bind.ServletRequestDataBinder.bind(ServletRequestDataBinder.java:106) ~[spring-web-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.bindRequestParameters(ServletModelAttributeMethodProcessor.java:150) ~[spring-webmvc-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:114) ~[spring-web-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) ~[spring-web-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:158) ~[spring-web-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128) ~[spring-web-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:116) ~[spring-webmvc-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) ~[spring-webmvc-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) ~[spring-webmvc-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) ~[spring-webmvc-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) ~[spring-webmvc-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:648) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) ~[spring-webmvc-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.11.jar:8.5.11]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:123) ~[druid-1.0.26.jar:1.0.26]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105) ~[spring-web-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) ~[spring-web-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:474) [tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624) [tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349) [tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:783) [tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:798) [tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1434) [tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.11.jar:8.5.11]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_131]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_131]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.11.jar:8.5.11]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_131]
IllegalAccessException: Class A can not access a member of class B 的一种原因分析与解决
2016年12月24日 12:30:28 FserSuN 阅读数:4455 标签: java 异常 class 个人分类: Java 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Revivedsun/article/details/53858033 Caused by: java.lang.IllegalAccessException: Class A can not access a member of class B 的一种原因分析与解决
我在使用到一个java fluent api工具时遇到这个问题,出现异常后调用栈如下。
Caused by: java.lang.IllegalAccessException: Class com.fluentinterface.proxy.BuilderProxy can not access a member of class zk.curator.Person with modifiers "public"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296)
at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:288)
at java.lang.reflect.Constructor.newInstance(Constructor.java:413)
at com.fluentinterface.proxy.BuilderProxy.createInstanceFromProperties(BuilderProxy.java:79)
at com.fluentinterface.proxy.BuilderProxy.invoke(BuilderProxy.java:56)
最后抛出了IllegalAccessException异常,这个异常的定义如下。
An IllegalAccessException is thrown when an application tries to reflectively create an instance (other than an array),
set or get a field, or invoke a method, but the currently executing method does not have access to the definition of the specified class,
field, method or constructor.
从异常定义可以看出,由于通过反射的机制创建实例,由于没有权限访问类,域,方法构造器而产生该异常。
通过抛出的异常可以看出,在调用sun.reflect.Reflection.ensureMemberAccess检查访问权限时抛出异常。
if (!verifyMemberAccess(currentClass, memberClass, target, modifiers)) {
throw new IllegalAccessException("Class " + currentClass.getName() +
" can not access a member of class " +
memberClass.getName() +
" with modifiers \"" +
Modifier.toString(modifiers) +
"\"");
}
该方法内部由于调用verifyMemberAccess,且未满足条件时抛出了异常。
public static boolean verifyMemberAccess(Class currentClass,
// Declaring class of field
// or method
Class memberClass,
// May be NULL in case of statics
Object target,
int modifiers)
{
// Verify that currentClass can access a field, method, or
// constructor of memberClass, where that member's access bits are
// "modifiers".
boolean gotIsSameClassPackage = false;
boolean isSameClassPackage = false;
if (currentClass == memberClass) {
// Always succeeds
return true;
}
if (!Modifier.isPublic(getClassAccessFlags(memberClass))) {
isSameClassPackage = isSameClassPackage(currentClass, memberClass);
gotIsSameClassPackage = true;
if (!isSameClassPackage) {
return false;
}
......略
}
可以看到verifyMemberAccess会检查所创建的类是访问描述符是否是public,若不是public,那么检查所创建的类与调用类是否在同一个包下,如果不在同一个包下则返回false。而我在练习使用fluent api 工具时,所定义的类XXX为并不是public,而且和工具类不在一个包下,因此导致IllegalAccessException异常的产生。
class XXX{
}
最后将类修改为public问题解决。可以想到,做这样的检查是为了确保对目标类有权限访问。
ribbon通过RestTemplate调用接口获取List
足不出户能上网就能赚钱,月收入过万!!
国化 · 燨燚
想对作者说点什么? 我来说一句
xd03122049
xd03122049: 博主,你这个问题怎么解决的?就是你虽然用了数组,但是还是会遇到序列化的问题. nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of com.kelan.entity.DataSourceConfig[] out of START_OBJECT token at [Source: java.io.PushbackInputStream@582ea164; line: 1, column: 1]
(1年前#1楼)
Spring Resttemplate post方法踩坑记录 2017年11月27日 18:30:16 liubingyu12345 阅读数:5809 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liubingyu12345/article/details/78647709 Spring Resttemplate post方法踩坑记录
项目中有处地方需要通过http post构造restful请求,且需要携带正确的header域, 自然而然想到了用Spring自带的restTemplate,对应post,put,get,delete它都有对应的封装方法。 由于我用的项目框架是SpringBoot,所以使用restTemplate很简单,在启动类XXXApplication类上注入restTemplate即可,如下代码:
@Inject
private RestTemplateBuilder builder;
@Bean
public RestTemplate restTemplate() {
return builder.build();
}
然后在业务类上注入这个bean即可:
@Inject
private RestTemplate restTemplate;
public void sendPost() {
.........
//xxpojo是个pojo类,post请求中要放在http request body域中
String requestBody = JSONObject.toJSONString(xxpojo);
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(type);
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
HttpEntity<String> httpEntity = new HttpEntity<String>(requestBody, headers);
restTemplate.postForEntity(toUrl, httpEntity, String.class);
.............
}
运行之后,对端服务报body域中的json解析失败,一脸懵逼。各种百度各种调试,中间的艰辛就不记录了(中途还换过java原生的Http Connection,是OK的) 后来换了另一种resttemplate注入来获得restTemplate实例:
RestTemplate restTemplate = new RestTemplate(new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory()));
restTemplate.postForEntity(toUrl, httpEntity, String.class);
然后debug这两者之间的区别,发现第一种注入的restemplate是通过SimpleClientHttpRequestFactory获取实例的,第二种是通过BufferingClientHttpRequestFactory。 百度了下网上说SimpleClientHttpRequestFactory是ClientHttpRequestFactory的装饰器方法, 用来创建ClientHttpRequest。BufferingClientHttpRequestFactory用了JDK原生的方法(java.net包),不依赖于第三方库,例如Appache的Http相关的库。 然鹅 我还是没明白为什么第一种方式json会解析失败,最后在debug resttemplate.doWithRequest代码的时候,第一种方式比第二种多了一个fastjson转换器, 第一种有八个,第二种是七个(我在项目中用了fastJson注入到了HttpMessageConverters中): 这里写图片描述
然后我推断是fastJson的原因,把fastJson注入移除,用第一种方法就好了!!! 还有然后!!第一种方法中,HttpEntity构造方法中,直接传入pojo对象代替原先的json字符串也是可以的,不用JSONObject.toJSONString()方法转!
总结 归根结底的原因其实我还是没找到,一般情况下,如果要用restTemplate发restful post请求,且要携带header域, body中的内容是最好要转成json字符串的,然而~~如果项目中用了fastJson,restTemplate内部会用fastjson去转这个字符串作为http body域内容,这时发过去的body域内容就不对了。
PS:找问题过程中,一直想抓包,试了fiddler,抓不到本地代码运行发出去的post请求,用了wireshark,抓的太底层了,抓 的是tcp/udp层的,目前还在寻找方案中~~
RestTemplate传递对象乱码问题及实例调用 https://blog.csdn.net/xuxie13/article/details/79209549
重点: 重写了 StringHttpMessageConverter 这个类
2018年01月30日 18:59:47 xuxie13 阅读数:3466 最近在优化项目,将里面的交易日志插入部分分离了出来,现在就要将主系统得到的日志发送到日志系统, 来减轻主项目对数据库的压力,现将日志发送给日志系统的方案有三个, 其一为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 org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.util.StreamUtils;
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;
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,
spring cloud 做微服务时关于RestTemplate中的各种请求方法的使用总结 https://blog.csdn.net/u012843361/article/details/79893638
文中提到了一个ParameterizedTypeReference, 别处没涉及
再看中间的3个exchange方法:
可以看到中间的3个方法与前面的3个方法唯一不相同的就是指定返回类型了,前面3个方法都是Class
该类的目的是启用泛型类型的捕获和传递。为了捕获泛型类型并在运行时保留它,您需要创建一个子类如下:
ParameterizedTypeReference<List<String>> typeRef = new ParameterizedTypeReference<List<String>>(){};
顺便说一下ParameterizedTypeReference
ParameterizedTypeReference<List<UserVO>> myBean = new ParameterizedTypeReference<List<UserVO>>() {};
ResponseEntity<List<UserVO>> exchange = restTemplate.exchange("http://www.xxx.com/testSend", HttpMethod.GET, null, myBean, 90,2019);
当要查询一个List类型的bean对象的时候,之前的Class
最后剩下的2个exchange方法:
可以看到最后这2个exchange接口都只传2个参数,第一个都是RequestEntity<?> requestEntity,
第二个参数是Class
看到RequestEntity的几个成员:
private final HttpMethod method;
private final URI url;
private final Type type;
和他的这几个构造方法就知道,其实这里的RequestEntity<?>实际上就是将前面的几个exchange方法中的url、method、responseType等几个参数封装起来了,本质上还是一样的。
至此RestTemplate中的Http请求方法的使用就都介绍完了。 下面将这些方法大概的做一个总结,总结就根据实际需求来分类,分为4类查询,新增、修改、删除: 约定:所有的方法中只对url是String类型的方法做分类和总结,因为一个是请求过程中的url常见的都是String,二是String类型的url可以手动的转在URI. 所以所有的URI为参数的方法都当重复方法,不再做分类和总结。
结:
请求参数中常用的url一般都是String,所以以url参数类型是URI的可以不管,用的少。
可变参数Object... uriVariables和Map<String, ?>
uriVariables里面传的参数都是url上的参数,本质上没有什么区别,重点是url上一定要占位。
请求参数Class
exchange方法可以发多种类型的Http请求,本质上与具体的某一类的请求没有太大差别,
唯一的是exchange方法中有可以参数化响应类型的请求参数:ParameterizedTypeReference
作者:DWT_CCFK 来源:CSDN 原文:https://blog.csdn.net/u012843361/article/details/79893638 版权声明:本文为博主原创文章,转载请附上博文链接!
使用restTemplate处理modelAttribute