2015-01-04 2 views
2

Прежде всего, у меня есть две службы весеннего REST: Служба A и Служба B. Сервис A необходимо будет использовать некоторые методы, выставленные Служба B. Оба, A и B, весна @RestController.Spring Framework & RestTemplate: не в состоянии потреблять услугу REST

Сервис А имеет POST метод:

@RequestMapping(value = "/mediumcandy/linkreachable", method = RequestMethod.POST) 
    public ResponseEntity<ShortURL> shortenerIfReachable(@RequestParam("url") String url, 
      @RequestParam(value = "sponsor", required = false) String sponsor, 
      @RequestParam(value = "brand", required = false) String brand, 
      HttpServletRequest request) { 
     ShortURL su = null; 

     /************************************************************* 
     * CONSUMING REST Service 
     *************************************************************/ 
     Map<String, String> vars = new HashMap<String, String>(); 
     vars.put("url", url); 

     RestTemplate restTemplate = new RestTemplate(); 
     su = restTemplate.postForObject("http://SERVICE_URI_HERE/linkreachable", null, ShortURL.class, vars); 
     /****************************************************************/ 

     if (su != null) { 
      HttpHeaders h = new HttpHeaders(); 
      h.setLocation(su.getUri()); 
      return new ResponseEntity<>(su, h, HttpStatus.CREATED); 
     } else { 
      return new ResponseEntity<>(HttpStatus.BAD_REQUEST); 
     } 
    } 

, и POST методом в Service B вызывается Service A использованием Spring RestTemplate заключается в следующем:

@RequestMapping(value = "/linkreachable", method = RequestMethod.POST) 
public ShortURL shortenerIfReachable(@RequestParam("url") String url, 
     @RequestParam(value = "sponsor", required = false) String sponsor, 
     @RequestParam(value = "brand", required = false) String brand, 
     HttpServletRequest request) { 
    ShortURL su = null; 
    boolean isReachableUrl = ping(url); 

    if (isReachableUrl){ 
     su = createAndSaveIfValid(url, sponsor, brand, UUID 
       .randomUUID().toString(), extractIP(request)); 
     System.out.println("URL REACHABLE!"); 
    } 

    return su; 
} 

The RestTemplate meth спосо postForObject() в Service A дает мне неприятности, всегда бросали HttpClientErrorException: 400 Bad Request:

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw 
exception [Request processing failed; nested exception is org.springframework.web.client.H 
ttpClientErrorException: 400 Bad Request] with root cause 

org.springframework.web.client.HttpClientErrorException: 400 Bad Request 
     at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultR 
esponseErrorHandler.java:91) 
     at org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.ja 
va:615) 
     at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:573) 
     at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:537) 
     at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:339 
) 
     at urlshortener2014.mediumcandy.web.MediumCandyController.shortenerIfReachable(Med 
iumCandyController.java:39) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.ja 
va:43) 
     at java.lang.reflect.Method.invoke(Method.java:601) 
     at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(Invocabl 
eHandlerMethod.java:221) 
     at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(
InvocableHandlerMethod.java:137) 
     at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMe 
thod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) 
     at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdap 
ter.invokeHandleMethod(RequestMappingHandlerAdapter.java:777) 
     at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdap 
ter.handleInternal(RequestMappingHandlerAdapter.java:706) 
     at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(
AbstractHandlerMethodAdapter.java:85) 
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:94 
... etc 

Я следовал некоторые Spring Учебники строить свою службу, а также проверили Spring Framework API-документацию, но я не имею был способен заставить его работать.

+0

Не могли бы вы опубликовать web.xml и, пожалуйста, подтвердите, что, когда вы тестируете услугу B отдельно (не звоните в службу A), она работает так, как ожидалось? – liorsolomon

+0

@liorsolomon да, обслуживание B индивидуально работает нормально. Я не использую web.xml, поскольку я не развертываю внешний экземпляр. Я сделал это так, как это объясняется здесь: https://spring.io/guides/gs/rest-service/ – charliebrownie

+0

@liorsolomon вот репортаж проекта: https://github.com/charliemc/UrlShortener2014/tree/ разработчик/mediumCandy/src/main/java/urlshortener2014/mediumcandy 'MediumCandyController' - ** Сервис A ** и' UrlShortenerControllerWithLogs' - это ** Сервис B ** – charliebrownie

ответ

1

Использование Spring HATEOAS чтобы решить эту проблему! Учитывая ServiceA и ServiceB в ServiceA использовать Spring HATEOAS для получения выполнения URL из контроллера/метода «ServiceB` следующим образом:

import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; 
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn; 
... 
String restURI = linkTo(methodOn(ServiceB.class). 
    shortenerIfReachable(null, null, null, null)).toString(); 
RestTemplate restTemplate = new RestTemplate(); 
su = restTemplate.postForObject(restURI, null, ShortURL.class, vars); 
+0

У меня возникают проблемы с 'methodOn()': компилятор говорит, что это * undefined fot type ** Class *** – charliebrownie

+0

Не могли бы вы выслать полный код? –

+0

Конечно, вот оно: http://codetidy.com/5975/ – charliebrownie

0

Попробуйте следующий URL: curl --data "url=http://www.stackoverflow.com" http://localhost:8080/linkreachable

+0

Этот способ хорошо работает, но так же и не используется ** Сервис A **. Мне нужно вызвать этот метод '/ linkreachable' в ** Service B ** из ** Service A ** 'method'/mediumcandy/linkreachable' (я знаю, это может показаться немного глупым, потому что результат такой же, но я должен сделать это таким образом). – charliebrownie

+0

просто представьте себе ** Сервис A ** - это клиент Java, который использует REST API (** Service B **), вот что мне нужно. – charliebrownie

2

@Francisco вы были почти там

import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; 
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn; 
... 
String restURI = linkTo(methodOn(UrlShortenerControllerWithLogs.class). 
       shortenerIfReachable(url, null, null, null)).toString(); 

RestTemplate restTemplate = new RestTemplate(); 

su = restTemplate.postForObject(restURI, null, ShortURL.class); 

Вы должны передайте параметр url при вызове shortenerIfReachable , и я также удалил vars из вызова postForObject.

+0

У меня все еще возникают проблемы с этим методом: 'methodOn()' Компилятор продолжает говорить, что это * undefined fot type Класс * – charliebrownie

+0

О, простите! Я полностью полагал, что Eclipse IDE автоматически выполняет эти импортные операции. Проверено, и теперь ** отлично работает **! – charliebrownie

Смежные вопросы