通过 JSON 中的 RestTemplate POST 请求
Posted
技术标签:
【中文标题】通过 JSON 中的 RestTemplate POST 请求【英文标题】:POST request via RestTemplate in JSON 【发布时间】:2011-05-03 19:46:02 【问题描述】:我没有找到任何示例如何解决我的问题,所以我想向您寻求帮助。我不能简单地使用 JSON 中的 RestTemplate 对象发送 POST 请求
每次我得到:
org.springframework.web.client.HttpClientErrorException: 415 Unsupported Media Type
我是这样使用 RestTemplate 的:
...
restTemplate = new RestTemplate();
List<HttpMessageConverter<?>> list = new ArrayList<HttpMessageConverter<?>>();
list.add(new MappingJacksonHttpMessageConverter());
restTemplate.setMessageConverters(list);
...
Payment payment= new Payment("Aa4bhs");
Payment res = restTemplate.postForObject("http://localhost:8080/aurest/rest/payment", payment, Payment.class);
我的错是什么?
【问题讨论】:
@troyfolger 网址不再有效 谢谢 - 此链接在撰写本文时有效:spring.io/guides/gs/consuming-rest 为了解决上面的特定 OP 问题,您可能缺少具有适当内容类型的 HTTP 标头,请参阅下面 morganw09dev 的答案。 这些问题大多与服务器 API 配置有关。您使用独立客户端(如 Postman )测试服务器 API 并在您的请求中复制相同的标头。至少在我的情况下做到了这一点。 @Johnny B,如果已经回答,请标记答案 【参考方案1】:“415 Unsupported Media Type”错误告诉您服务器不会接受您的 POST 请求。您的请求绝对没问题,是服务器配置错误。
MappingJacksonHttpMessageConverter
会自动将请求内容类型标头设置为application/json
,我猜你的服务器正在拒绝它。不过,您还没有告诉我们有关您的服务器设置的任何信息,因此我无法就此向您提供任何建议。
【讨论】:
【参考方案2】:按照here的规定,我猜你需要为MappingJacksonHttpMessageConverter
添加一个messageConverter
【讨论】:
【参考方案3】:如果您使用的是 Spring 3.0,避免 org.springframework.web.client.HttpClientErrorException: 415 Unsupported Media Type 异常的简单方法是在类路径中包含 jackson jar 文件,并使用mvc:annotation-driven
配置元素。 As specified here.
我一直在努力弄清楚为什么 mvc-ajax 应用程序在没有任何针对 MappingJacksonHttpMessageConverter
的特殊配置的情况下也能正常工作。如果您仔细阅读我上面链接的文章:
在封面之下,Spring MVC 委托给 HttpMessageConverter 到 执行序列化。在这个 在这种情况下,Spring MVC 调用一个 映射JacksonHttpMessageConverter 建立在杰克逊 JSON 处理器上。 此实现已启用 自动当您使用 mvc:annotation-driven 配置 杰克逊的元素出现在你的 类路径。
【讨论】:
【参考方案4】:这项技术对我有用:
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<String>(requestJson, headers);
ResponseEntity<String> response = restTemplate.put(url, entity);
希望对你有帮助
【讨论】:
请解释哪一行应该返回http请求的结果 对我来说没有必要指定任何标题。我使用了带有单个参数的 HttpEntity。 方法.put()
是void
!
使用postForEntity(url, entity, String.class)
代替put(url, entity)
@Kanu,requestJson 是有效的 JSON 字符串还是别的什么?【参考方案5】:
我一直在使用带有 JSONObjects 的 rest 模板,如下所示:
// create request body
JSONObject request = new JSONObject();
request.put("username", name);
request.put("password", password);
// set headers
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<String>(request.toString(), headers);
// send request and parse result
ResponseEntity<String> loginResponse = restTemplate
.exchange(urlString, HttpMethod.POST, entity, String.class);
if (loginResponse.getStatusCode() == HttpStatus.OK)
JSONObject userJson = new JSONObject(loginResponse.getBody());
else if (loginResponse.getStatusCode() == HttpStatus.UNAUTHORIZED)
// nono... bad credentials
【讨论】:
谢谢 - JSONObject toString 方法对我很有用,它帮助我获得了准确的 JSONString。 如何为此开发上述代码: curl -vvv -X POST "localhost:8080/SillyService_SRC/oauth/…" ? @Mikael Lepistö 我如何在服务器端从 json 中检索这些参数?? @KJEjava48 我不明白你的意思......这是响应中的服务器端代码。如果您正在考虑如何解析 json 响应,这取决于您使用的框架。 @MikaelLepistö 我的意思是如何在另一端解析 json 响应,包括如何在 java 中接收响应??您只发布了一端(即服务器端)的代码。【参考方案6】:对我来说,此设置发生错误:
androidAnnotations
Spring Android RestTemplate Module
和...
GsonHttpMessageConverter
Android annotations 有一些问题,这个转换为无参数生成POST
请求。只需参数new Object()
就为我解决了。
【讨论】:
【参考方案7】:我在尝试调试 REST 端点时遇到了这个问题。这是一个使用 Spring 的 RestTemplate 类发出我使用的 POST 请求的基本示例。我花了相当长的时间来拼凑来自不同地方的代码以获得工作版本。
RestTemplate restTemplate = new RestTemplate();
String url = "endpoint url";
String requestJson = "\"queriedQuestion\":\"Is there pain in your hand?\"";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<String>(requestJson,headers);
String answer = restTemplate.postForObject(url, entity, String.class);
System.out.println(answer);
我的休息端点的特定 JSON 解析器在字段名称周围使用了所需的双引号,这就是我在 requestJson 字符串中转义双引号的原因。
【讨论】:
你能帮我解决这个问题吗***.com/questions/42240927/… Spring 能否像使用 RestTemplate 在 Restful API 中那样使用消息转换器自动将 Java 对象转换为 json? 设置媒体类型为APPLICATION_JSON是解决问题的关键。 我使用 HttpEntity我遇到了这个问题,我在客户端使用 Spring 的 RestTemplate,在服务器上使用 Spring Web。两种 API 的错误报告都非常差,因此开发起来非常困难。
经过数小时尝试各种实验后,我发现问题是由于为 POST 正文而不是预期的列表传递空引用引起的。我认为 RestTemplate 无法从空对象确定内容类型,但不会抱怨它。添加正确的标头后,在进入我的服务方法之前,我开始在 Spring 中获得不同的服务器端异常。
解决方法是从客户端传入一个空列表而不是 null。由于默认内容类型用于非空对象,因此不需要标头。
【讨论】:
【参考方案9】:这段代码对我有用;
RestTemplate restTemplate = new RestTemplate();
Payment payment = new Payment("Aa4bhs");
MultiValueMap<String, Object> map = new LinkedMultiValueMap<String, Object>();
map.add("payment", payment);
HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<MultiValueMap<String, Object>>(map, headerObject);
Payment res = restTemplate.postForObject(url, httpEntity, Payment.class);
【讨论】:
我使用了一种非常相似的方法,但它对我不起作用。由于某种原因,我的“地图”等价物没有被转换为 json 或作为出站正文包含,即目标服务没有看到任何有效负载。 是的,如图所示,此解决方案将以application/x-www-form-urlencoded
格式发布。【参考方案10】:
我就是这样做的,效果很好。
HttpHeaders headers = createHttpHeaders(map);
public HttpHeaders createHttpHeaders(Map<String, String> map)
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
for (Entry<String, String> entry : map.entrySet())
headers.add(entry.getKey(),entry.getValue());
return headers;
// 在此处传递标题
String requestJson = " // Construct your JSON here ";
logger.info("Request JSON ="+requestJson);
HttpEntity<String> entity = new HttpEntity<String>(requestJson, headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
logger.info("Result - status ("+ response.getStatusCode() + ") has body: " + response.hasBody());
logger.info("Response ="+response.getBody());
希望对你有帮助
【讨论】:
【参考方案11】:如果你不想处理响应
private RestTemplate restTemplate = new RestTemplate();
restTemplate.postForObject(serviceURL, request, Void.class);
如果您需要响应流程
String result = restTemplate.postForObject(url, entity, String.class);
【讨论】:
【参考方案12】:为什么比你必须努力工作? postForEntity
接受一个简单的 Map
对象作为输入。在 Spring 中为给定的 REST 端点编写测试时,以下内容对我来说很好。我相信这是在 Spring 中发出 JSON POST 请求的最简单方法:
@Test
public void shouldLoginSuccessfully()
// 'restTemplate' below has been @Autowired prior to this
Map map = new HashMap<String, String>();
map.put("username", "bob123");
map.put("password", "myP@ssw0rd");
ResponseEntity<Void> resp = restTemplate.postForEntity(
"http://localhost:8000/login",
map,
Void.class);
assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
【讨论】:
【参考方案13】:如果不想自己映射JSON,可以这样:
RestTemplate restTemplate = new RestTemplate();
restTemplate.setMessageConverters(Arrays.asList(new MappingJackson2HttpMessageConverter()));
ResponseEntity<String> result = restTemplate.postForEntity(uri, yourObject, String.class);
【讨论】:
【参考方案14】:我在 Spring Boot 中尝试如下:
ParameterizedTypeReference<Map<String, Object>> typeRef = new ParameterizedTypeReference<Map<String, Object>>() ;
public Map<String, Object> processResponse(String urlendpoint)
try
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
//reqobj
JSONObject request = new JSONObject();
request.put("username", name);
//Or Hashmap
Map<String, Object> reqbody = new HashMap<>();
reqbody.put("username",username);
Gson gson = new Gson();//mvn plugin to convert map to String
HttpEntity<String> entity = new HttpEntity<>( gson.toJson(reqbody), headers);
ResponseEntity<Map<String, Object>> response = resttemplate.exchange(urlendpoint, HttpMethod.POST, entity, typeRef);//example of post req with json as request payload
if(Integer.parseInt(response.getStatusCode().toString()) == HttpURLConnection.HTTP_OK)
Map<String, Object> responsedetails = response.getBody();
System.out.println(responsedetails);//whole json response as map object
return responsedetails;
catch (Exception e)
// TODO: handle exception
System.err.println(e);
return null;
【讨论】:
【参考方案15】:您可以将请求作为 JSON 对象提出
JSONObject request = new JSONObject();
request.put("name","abc");
ResponseEntity<JSONObject> response =restTemplate.postForEntity(append_url,request,JSONObject.class); `enter code here`
【讨论】:
以上是关于通过 JSON 中的 RestTemplate POST 请求的主要内容,如果未能解决你的问题,请参考以下文章