Java Spring MVC - 从另一个休息服务内部调用一个休息服务
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34503547/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring MVC - Calling a rest service from inside another rest service
提问by Rob
I'm currently having a really weird issue with calling one REST service from inside another one and I could really use a hand in working out what I'm doing wrong.
我目前在从另一个服务内部调用一个 REST 服务时遇到了一个非常奇怪的问题,我真的可以帮助解决我做错了什么。
So first off, a bit of context:
所以首先,一些上下文:
I have a webapp which calls off to a REST service to create a user account (for the sake of this explanation, the endpoint is localhost:8080/register). Earlier in the user journey I've called a different service to create the user's login credentials localhost:8090/signup
but I need to check a few things in the call to /register so inside the call I'm calling out to a different endpoint on 8090 to get this information (localhost:8090/availability
). Long story short, the webapp calls localhost:8080/register which in turn calls localhost:8090/availability
.
我有一个 webapp,它调用一个 REST 服务来创建一个用户帐户(为了这个解释,端点是 localhost:8080/register)。在用户旅程的早期,我调用了一个不同的服务来创建用户的登录凭据,localhost:8090/signup
但我需要检查 /register 调用中的一些内容,所以在调用中我调用 8090 上的不同端点来获取此信息信息 ( localhost:8090/availability
)。长话短说,webapp 调用 localhost:8080/register,后者又调用localhost:8090/availability
.
When I call the availability endpoint directly, from either a REST client or the webapp itself, everything works as expected, but for some strange reason, when I call it from inside the call to the register endpoint I get a HTTP415. Anyone have any insight into what's going wrong?
当我直接从 REST 客户端或 web 应用程序本身调用可用性端点时,一切都按预期工作,但出于某种奇怪的原因,当我从对注册端点的调用内部调用它时,我得到一个 HTTP415。任何人都知道出了什么问题?
The register controller looks like this:
寄存器控制器如下所示:
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.OK)
public UserModel createUser(@RequestBody UserModel userModel) throws InvalidSignupException {
// a load of business logic that validates the user model
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Boolean> response = restTemplate.postForEntity("http://localhost:8090/availability",
userModel.getUsername(), Boolean.class);
System.out.println(response.getBody());
// a load more business logic
return userModel;
}
And the availability controller looks like this:
可用性控制器如下所示:
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.OK)
public Boolean isUsernameAvailable(@RequestBody String username) {
// a load of business logic that returns a boolean
return Boolean.TRUE;
}
Full disclosure - in practice, what I've shown as the contents of createUser() are actually several calls up the call stack, using the same class as I use to call the services from the webapp (which works perfectly well in that context), and I'm not actually just returning true in isUsernameAvailable (because that would be silly) but this is the simplest version of the code that replicates the issue.
完全公开 - 在实践中,我所展示的 createUser() 内容实际上是调用堆栈的几次调用,使用的类与我用来从 webapp 调用服务的类相同(在该上下文中运行良好) ,而且我实际上并不只是在 isUsernameAvailable 中返回 true (因为这很愚蠢),但这是复制问题的代码的最简单版本。
My current assumption is that I'm doing something that I'm going to kick myself over when I see it but I've been staring at this code too long to be able to see it any more.
我目前的假设是,当我看到它时,我正在做一些我会踢自己的事情,但我已经盯着这段代码太久了,无法再看到它。
EditVikdor's comment below solved this problem for me. I changed the createUser method to:
下面编辑Vikdor 的评论为我解决了这个问题。我将 createUser 方法更改为:
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.OK)
public UserModel createUser(@RequestBody UserModel userModel) throws InvalidSignupException {
// a load of business logic that validates the user model
RestTemplate restTemplate = new RestTemplate();
restTemplate.setMessageConverters(Arrays.asList(new MappingHymanson2HttpMessageConverter()));
ResponseEntity<Boolean> response = restTemplate.postForEntity("http://localhost:8090/availability",
userModel.getUsername(), Boolean.class);
System.out.println(response.getBody());
// a load more business logic
return userModel;
}
回答by ketan vijayvargiya
A HTTP415means Unsupported Media Type. What that means is that isUsernameAvailable
expects input in JSON format, but that isn't what it is getting.
一个HTTP415表示不支持的媒体类型。这意味着isUsernameAvailable
需要 JSON 格式的输入,但这不是它得到的。
Try explicitly adding Content-Type: application/json
header to your HTTP request by doing the following:
尝试Content-Type: application/json
通过执行以下操作向您的 HTTP 请求显式添加标头:
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<String>(requestJson,headers);
restTemplate.put(uRL, entity);
回答by Aastha Jain
Use RestTemplate.exchange mentioned below :
使用下面提到的 RestTemplate.exchange :
ResponseEntity responseEntity=RestTemplate.exchange(endPointURL, HttpMethod.GET/POST/PUT/DELETE, HttpEntity/headers, uriVariables)
ResponseEntity responseEntity=RestTemplate.exchange(endPointURL, HttpMethod.GET/POST/PUT/DELETE, HttpEntity/headers, uriVariables)
endpointURL-- SOAP End point URL ,that the REST service has to consume.
endpointURL- SOAP端点URL,REST 服务必须使用它。
HTTPMethod-- Method Type such as GET ,PUT ,POST ,DELETE etc.
HTTPMethod- 方法类型,例如 GET 、PUT 、POST 、DELETE 等。
HTTPEntity-- Soap requires for mandatory sender/headers/{a}.Make sure that you set your header name and value as key-Valye pair in HTTP headers.
HTTPEntity-- Soap 需要强制的 sender/headers/{a}。确保您在 HTTP 标头中将标头名称和值设置为 key-Valye 对。
uriVariables-- (Object... urivariables) such as String.class ,Integer.class
uriVariables-- (Object... urivariables) 如 String.class ,Integer.class
You should also put the connectTimeout,isSSLDisabled,responseCachedin the constructor while generating request to restTemplate.
您还应该在生成对 restTemplate 的请求时将connectTimeout、isSSLDisabled、responseCached放在构造函数中。