9

Questa è la mia messa a punto:404 durante l'utilizzo di primavera nuvola FeignClients

Primo servizio (FlightIntegrationApplication), che invoca secondo servizio (BaggageServiceApplication) utilizzando FeignClients API e Eureka.

progetto su GitHub: https://github.com/IdanFridman/BootNetflixExample

Primo servizio:

@SpringBootApplication 
@EnableCircuitBreaker 
@EnableDiscoveryClient 
@ComponentScan("com.bootnetflix") 
public class FlightIntegrationApplication { 

    public static void main(String[] args) { 
     new SpringApplicationBuilder(FlightIntegrationApplication.class).run(args); 
    } 

} 

in uno dei controller:

@RequestMapping("/flights/baggage/list/{id}") 
    public String getBaggageListByFlightId(@PathVariable("id") String id) { 
     return flightIntegrationService.getBaggageListById(id); 
    } 

FlightIntegrationService:

public String getBaggageListById(String id) { 
     URI uri = registryService.getServiceUrl("baggage-service", "http://localhost:8081/baggage-service"); 
     String url = uri.toString() + "/baggage/list/" + id; 
     LOG.info("GetBaggageList from URL: {}", url); 

     ResponseEntity<String> resultStr = restTemplate.getForEntity(url, String.class); 
     LOG.info("GetProduct http-status: {}", resultStr.getStatusCode()); 
     LOG.info("GetProduct body: {}", resultStr.getBody()); 
     return resultStr.getBody(); 

    } 

RegistryService:

@Named 
public class RegistryService { 

    private static final Logger LOG = LoggerFactory.getLogger(RegistryService.class); 


    @Autowired 
    LoadBalancerClient loadBalancer; 

    public URI getServiceUrl(String serviceId, String fallbackUri) { 
     URI uri; 
     try { 
      ServiceInstance instance = loadBalancer.choose(serviceId); 
      uri = instance.getUri(); 
      LOG.debug("Resolved serviceId '{}' to URL '{}'.", serviceId, uri); 

     } catch (RuntimeException e) { 
      // Eureka not available, use fallback 
      uri = URI.create(fallbackUri); 
      LOG.error("Failed to resolve serviceId '{}'. Fallback to URL '{}'.", serviceId, uri); 
     } 

     return uri; 
    } 

} 

E questo è il secondo servizio (bagaglio-service):

BaggageServiceApplication:

@Configuration 
@ComponentScan("com.bootnetflix") 
@EnableAutoConfiguration 
@EnableEurekaClient 
@EnableFeignClients 
public class BaggageServiceApplication { 


    public static void main(String[] args) { 
     new SpringApplicationBuilder(BaggageServiceApplication.class).run(args); 
    } 

} 

BaggageService:

@FeignClient("baggage-service") 
public interface BaggageService { 

    @RequestMapping(method = RequestMethod.GET, value = "/baggage/list/{flight_id}") 
    List<String> getBaggageListByFlightId(@PathVariable("flight_id") String flightId); 


} 

BaggageServiceImpl:

@Named 
public class BaggageServiceImpl implements BaggageService{ 

.... 

    @Override 
    public List<String> getBaggageListByFlightId(String flightId) { 
     return Arrays.asList("2,3,4"); 
    } 

} 

Quando invocando il controllore resto del servizio di integrazione volo ottengo:

2015-07-22 17:25:40.682 INFO 11308 --- [ XNIO-2 task-3] c.b.f.service.FlightIntegrationService : GetBaggageList from URL: http://X230-Ext_IdanF:62007/baggage/list/4 
2015-07-22 17:25:43.953 ERROR 11308 --- [ XNIO-2 task-3] io.undertow.request      : UT005023: Exception handling request to /flights/baggage/list/4 

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.web.client.HttpClientErrorException: 404 Not Found 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978) 

Qualche idea?

Grazie, raggio.

risposta

3

Il tuo codice guarda indietro a me.

Il cliente fingere per il servizio dei bagagli devono essere dichiarate al servizio di volo e il servizio del bagaglio dovrebbe avere un controller che risponde sull'URL si mappa nel client di servizio del bagaglio, si dovrebbe non implementare l'interfaccia annotato con @FeignClient .

L'impostazione che hai ora non avrà alcun controller di ascolto sulla /bagaglio/list/{flightId} nel servizio bagagli e nessun cliente Feign in servizio di volo - il punto di Feign è chiamare metodi su un'interfaccia invece di gestire manualmente gli URL, Spring Cloud si occupa della creazione automatica dell'istanza dell'implementazione dell'interfaccia e utilizzerà Eureka per la scoperta.

Prova questo (o modificare in modo che si inserisce il tuo vero e proprio App World):

Flight Service:

FlightIntegrationService.java:

@Component 
public class FlightIntegrationService { 

    @Autowired 
    BaggageService baggageService; 

    public String getBaggageListById(String id) { 
     return baggageService.getBaggageListByFlightId(id); 
    } 
} 

BaggageService.java:

@FeignClient("baggage-service") 
public interface BaggageService { 

    @RequestMapping(method = RequestMethod.GET, value = "/baggage/list/{flight_id}") 
    List<String> getBaggageListByFlightId(@PathVariable("flight_id") String flightId); 
} 

Servizio bagagli:

BaggageController.java:

@RestController 
public class BaggageController { 

    @RequestMapping("/baggage/list/{flightId}") 
    public List<String> getBaggageListByFlightId(@PathVariable String flightId) { 
     return Arrays.asList("2,3,4"); 
    } 
} 

Rimuovere BaggageService.java e BaggageServiceImpl.java dal Servizio Bagagli

+0

Non dovrebbe il 'BaggageController' implementare il' BaggageService'? – Spacemonkey

+0

Non necessariamente: a volte si desidera ottenere gli oggetti richiesta o risposta nel controller o gestire più metodi di interfaccia con lo stesso metodo di controllo. Un buon esempio sono i parametri di query in cui è possibile avere valori predefiniti per i parametri mancanti in un metodo di controller, ma sono necessari più metodi di interfaccia se si desidera evitare di chiamarlo con un gruppo di 'null's. – Raniz

1

registryService.getServiceUrl ("bagaglio-service", ... sostituirlo con registryService.getServiceUrl ("bagaglio-service")

assicurarsi che corrisponde al nome giusto

rimuovere la parte localhost

oppure solo usare la parte http://local

funzionava solo per noi, se avete solo il nome del servizio elencati nella eureka cruscotto, non entrambi

+1

Non capisco. hai scritto la stessa linea. – rayman

+0

Il localhost menziona solo in faillback-url non nel principale – rayman