Reputation: 59
I have linked [Spring-Boot Rest API] and [Go Rest API] in the following configuration. Although the service of the destination URI exists, I intend to connect using RestTemplate in a communicable environment, but somehow it is a 404 error.
[Client]<--(1)-->[Spring-Boot Rest API]<--(2)-->[Go Rest API]<--(3)-->[DB]
[Client]<---------------------------------(2)-->[Go Rest API]<--(3)-->[DB]
First of all, communication (2) is normal
The Rest service of [Go Rest API] is available from the terminal with the following cURL command.
$ curl http://localhost:18000/ping -X GET
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 120 100 120 0 0 480 0 --:--:-- --:--:-- --:--:-- 591
{"pong":"ok","meta":{"host":"622c72386c52","rid":"","StartTime":"2017-05-31T06:33:37.654710044Z","execute_time":0.0061}}
I would like to have the [Spring-Boot Rest API] on the front side and use the RestTemplate internally to access the above URL. It was coded as follows.
@RequestMapping(value = "/ping/", method = RequestMethod.POST)
public final ResponseEntity<ResPongDto> ping(@RequestBody SalesSituationInquiries input) {
String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
this.logger.info("■■UT:[{}]disposalDate:{} ", methodName,input.getDisposalDate());
// ①To Client Response:ResPongDto
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// ②From Client Request:SalesSituationInquiries
this.logger.info("■■UT:[{}] From: {} To: {}", methodName,TotalSalesUtil.getStrFromByTo(input.getDisposalDate().toString()),input.getDisposalDate().toString());
this.logger.info("■■UT:[{}] URL: {}", methodName,DailyReportsUtil.API_GO_PING_URL);
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
// ③To Go Rest API Request:null
// ④From Go Rest API Response:ResPongDto
ResponseEntity<ResPongDto> resultGoMonth = restTemplate.exchange(
TotalSalesUtil.createTotalSalesUrl(DailyReportsUtil.API_GO_PING_URL, "", "")
, HttpMethod.GET
, new HttpEntity<>(null)
, ResPongDto.class);
this.logger.info("■■UT:[{}] testRestTemplate.exchange(): ", methodName);
result = new ResponseEntity<ResPongDto>(resultGoMonth.getBody(), headers, HttpStatus.CREATED);
return result;
}
(2) via (1) Unfortunately, the result is a 404 error.
2017-05-31 15:35:43.190 [maekawa-PC-main] INFO Exp:[id: tenant_id:] j.c.b.b.a.hogehogeApplication Started hogehogeApplication in 5.61 seconds (JVM running for 10.472)
2017-05-31 15:38:50.700 [maekawa-PC-http-nio-9999-exec-1] WARN Exp:[id: tenant_id:] j.c.b.b.a.i.YamlAuthenticationProcessingMockInterceptor YamlAuthenticationProcessingMockInterceptor:モック機能が動作しています。
2017-05-31 15:38:50.767 [maekawa-PC-http-nio-9999-exec-1] INFO Exp:[id: tenant_id:] j.c.b.b.m.r.a.TotalSalesStatusCommandService ■■UT:[ping]disposalDate:2017-04-03
2017-05-31 15:38:50.770 [maekawa-PC-http-nio-9999-exec-1] INFO Exp:[id: tenant_id:] j.c.b.b.m.r.a.TotalSalesStatusCommandService ■■UT:[ping] From: 2017-04-01 To: 2017-04-03
2017-05-31 15:38:50.770 [maekawa-PC-http-nio-9999-exec-1] INFO Exp:[id: tenant_id:] j.c.b.b.m.r.a.TotalSalesStatusCommandService ■■UT:[ping] URL: http://localhost:18000/ping
2017-05-31 15:38:50.868 [maekawa-PC-http-nio-9999-exec-1] ACS Exp:[id: tenant_id:] url:/api/v1/totalsalesstatus/ping/ status:200 elapsedNanoTime:146217390
2017-05-31 15:38:50.871 [maekawa-PC-http-nio-9999-exec-1] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing
failed; nested exception is org.springframework.web.client.HttpClientErrorException: 404 Not Found] with root cause
org.springframework.web.client.HttpClientErrorException: 404 Not Found
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:700)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:653)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:613)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:531)
at xx.xx.api.TotalSalesStatusCommandService.ping(TotalSalesStatusCommandService.java:90)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:116)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:474)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:783)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:798)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1434)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Note:
(2)curl http://localhost:18000/ping -X GET
(1)curl http://localhost:9999/api/v1/totalsalesstatus/ping/ -X POST -H "Content-Type: application/json" -d '{"hoghoge": "1234", "disposalDate": "2017-04-03"}'
I do not know why they do not communicate with cURL, so please help me.
Upvotes: 0
Views: 15540
Reputation: 1922
I struggled a lot with this exception Even URL is absolutely correct and relative URLs works for POST request. 404 means URL specify in RestTemplate or HttpRequest for GET type method is incorrect due to Query Param or Request Params or Path Params. Reason Query/Path param's value contain special character that converted or interpreted differently. Let Say queryParams is [email protected] which converted into email=test20%xyz41%.com
Solution: Decoding while passing query/path params.
Add Following code at server side [controller code]
ServerSide[Controller]:
import java.net.URLDecoder;
import java.net.URLEncoder;
String encodedEmail = URLDecoder.decode(email, "UTF-8");
It perfectly working and tested code.
Upvotes: 0
Reputation: 29
Try this. I was also getting the same error. The problem is caused by incorrect encoding.
public String getWeather(String cityName) {
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(weatherDataURL)
.queryParam("q", cityName)
.queryParam("APPID", apiKey);
return restTemplate.getForObject(builder.buildAndExpand().toUri(), String.class);
}
Upvotes: 0
Reputation: 2427
Have you tried using getForEntity
instead of exchange
?
ResponseEntity<ResPongDto> resultGoMonth = restTemplate.getForEntity(
TotalSalesUtil.createTotalSalesUrl(DailyReportsUtil.API_GO_PING_URL, "", "")
, ResPongDto.class);
I guess your problem is you are not setting the right headers. You could try adding the accept header to the request.
final HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity entity = new HttpEntity(headers);
ResponseEntity<ResPongDto> resultGoMonth = restTemplate.exchange(
TotalSalesUtil.createTotalSalesUrl(DailyReportsUtil.API_GO_PING_URL, "", ""),
HttpMethod.GET,
entity,
ResPongDto.class);
This code has not been tested. It is just an example.
BTW, I do not know how you are creating the resttemplate object, but you should not update the converters. It should be done at initialisation point only, as resttemplate are not thread safe once they have been created.
Upvotes: 1
Reputation: 3180
Try below code. This consumes application/json as body and produces the json response.
@RequestMapping(value = "/ping", method = RequestMethod.POST, produces = "application/json", consumes = "application/json")
public final ResponseEntity<ResPongDto> ping(@RequestBody SalesSituationInquiries input) {
..
}
Upvotes: 0