2015-04-22 2 views
0

Когда я использую FeignClient это установив Content-Type в application/x-www-form-urlencoded вместо application/json;charset=UTF-8.весна/Эврика/Feign - FeignClient установки Content-Type заголовка для приложения/х-WWW-форм-urlencoded

Если я использую RestTemplate для отправки того же сообщения, заголовок сообщения Content-Type правильно установлен в application/json;charset=UTF-8.

Идентифицированы как FeignClient, так и RestTemplate, и я обнаружил эту проблему, отлаживая сообщение HTTP, полученное сервером.

Контроллер на стороне сервера выглядит следующим образом:

@RestController 
@RequestMapping("/site/alarm") 
public class SiteAlarmController { 
    @RequestMapping(method = RequestMethod.POST) 
    @ResponseBody 
    public ResponseEntity<RaiseAlarmResponseDto> raiseAlarm(@RequestBody RaiseSiteAlarmRequestDto requestDto) { 
     ... 
    } 

Мой FeignClient интерфейс в службе, которая вызывает тревогу выглядит следующим образом:

@FeignClient("alarm-service") 
public interface AlarmFeignService { 
    @RequestMapping(method = RequestMethod.POST, value = "/site/alarm") 
    RaiseAlarmResponseDto raiseAlarm(@RequestBody RaiseSiteAlarmRequestDto requestDto); 
} 

Заголовки HTTP сообщений от FeignClient являются :

Accept: */* 
Cache-Control: no-cache 
Pragma: no-cache 
User-Agent: Java/1.7.0_60 
Host: smit005s-MacBook-Pro.local:9120 
Connection: keep-alive 
Content-Type: application/x-www-form-urlencoded 
Content-Length: 323 

Служба аварийной сигнализации «Т нравится Content-Type и выдает следующее исключение:

2015-04-22 12:12:28.580 thread="qtp1774842986-25" class="org.eclipse.jetty.servlet.ServletHandler" level="WARN" 
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is feign.FeignException: status 415 reading AlarmFeignService#raiseAlarm(RaiseSiteAlarmRequestDto); content: 
{"timestamp":1429701148576,"status":415,"error":"Unsupported Media Type","exception":"org.springframework.web.HttpMediaTypeNotSupportedException","message":"Unsupported Media Type","path":"/site/alarm"} 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978) ~[spring-webmvc-4.1.5.RELEASE.jar:4.1.5.RELEASE] 
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857) ~[spring-webmvc-4.1.5.RELEASE.jar:4.1.5.RELEASE] 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:618) ~[tomcat-embed-core-8.0.20.jar:8.0.20] 
    ... 
    ... /* commented rest of stack out */ 
    ... 

Если изменить на стороне клиента код, чтобы использовать RestTemplate следующим образом:

@Service 
public class AlarmService { 
    @Autowired 
    private RestTemplate restTemplate; 
... 
    public void send(RaiseSiteAlarmRequestDto alarm) { 
     RaiseAlarmResponseDto result = restTemplate.postForObject("http://alarm-service/site/alarm", 
      raiseSiteAlarmRequestDto, RaiseAlarmResponseDto.class); 
    } 
} 

Он работает с RestTemplate, то alarm-service получает сообщение и успешно его обрабатывает. Заголовки сообщений, отправленных RestTemplate являются:

Accept: application/json, application/*+json 
Content-Type: application/json;charset=UTF-8 
Cache-Control: no-cache 
Pragma: no-cache 
User-Agent: Java/1.7.0_60 
Host: smit005s-MacBook-Pro.local:9120 
Connection: keep-alive 
Content-Length: 323 
+0

Вы пытались перехватить 'ResponseEntity ' вашего контроллера, чтобы проверить, помешало ли это вмешательству в работу с клиентом? Моя другая догадка заключается в том, что Feign не может десериализовать ваш объект 'RaiseAlarmResponseDto'. – jebeaudet

+0

'@ RequestBody' в' @ FeignClient' ничего не делает. Можете ли вы сделать успешный звонок без притворства, но с эврика? – spencergibb

+0

Спасибо @spencergibb, что было хорошим предложением. Изменение его на RestTemplate работает, и он открывает сервис через Eureka.Когда я отправляю отладку на стороне получателя, я вижу, что клиент feign отправляет его с заголовком 'Content-Type', установленным неверно на' application/x-www-form-urlencoded'. В то время как 'RestTemplate' устанавливает' Content-Type' в 'application/json; charset = UTF-8'. Я обновлю вопрос. – user1232555

ответ

7

Ответ был сделать, как @spencergibb предполагает; используйте директиву consumes в аннотации @RequestMapping на интерфейсе FeignClient. Это также имеет пример Spring/Netflix documentaition.

Так, например, декларация @FeignClient интерфейса в клиенте теперь:

@FeignClient("alarm-service") 
public interface AlarmFeignService { 
    @RequestMapping(method = RequestMethod.POST, value = "/site/alarm", consumes = "application/json")) 
    RaiseAlarmResponseDto raiseAlarm(RaiseSiteAlarmRequestDto requestDto); 
} 

Примечание это необходимо только на стороне клиента и на стороне сервера контроллера не требуется, чтобы это изменение.

Было бы неплохо, если бы это было сделано по умолчанию на @FeignClient, а затем оно соответствовало бы RestTemplate и серверному контроллеру @RequestMapping аннотации. Возможно, это можно сделать в следующем выпуске spring-cloud.

+0

Это не работает для приложения/x-www-form-urlencoded, вы получите: feign.codec.EncodeException: Не удалось написать запрос: не найдено подходящего HttpMessageConverter для типа запроса [com. *. Pojos.OAuthLoginPojo] и типа содержимого [ применение/х-WWW-форм-urlencoded] –

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