【问题标题】:415 Unsupported Media Type (org.springframework.web.client.HttpClientErrorException)415 不支持的媒体类型(org.springframework.web.client.HttpClientErrorException)
【发布时间】:2017-06-30 10:02:35
【问题描述】:

我是 Web 服务的新手。我正在开发一个应用程序,我在客户端使用 AnhularJs1.x,它将数据发送到 Spring Rest Controller。

应用程序的架构是基于微服务的。我能够从 Angular 接收处于同一战争中的前端休息控制器的数据。

我正在从这个控制器调用一个服务,该服务在内部调用另一个与数据库交互的微服务。

当我将前端控制器接收到的数据发送到另一个微服务时,我得到 415 Unsupported Media Type (org.springframework.web.client.HttpClientErrorException)

下面是我的前端控制器,它与 angularJS 处于同一场战争中

@RequestMapping(value = "/servicearticles",  method = RequestMethod.POST,        produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ServiceArticle> saveData(@RequestBody      List<ServiceArticle> serviceArticleList){
    System.out.println("In savedata");
    System.out.println(serviceArticleList.toString());


    try {
        if(null != serviceArticleList && serviceArticleList.size() >0){
            serviceArticleAdminService.insertData(serviceArticleList);
        }else{
            logger.error("File is empty. No data to save");
        }

我能够在这个控制器中获取数据: [ServiceArticle [articleId=17070, productCode=1000, productName=Business Parcel zone , zone=1], ServiceArticle [articleId=17071, productCode=1001, productName=Business Parcel zone , zone=4], ServiceArticle [articleId=17070, productCode =1012, productName=Business Parcel zone , zone=5], ServiceArticle [articleId=17070, productCode=1000, productName=Business Parcel zone , zone=1], ServiceArticle [articleId=17070, productCode=1000, productName=Business Parcel zone , 区域=2]]

当我从我的 serviceImpl 类调用不同的微服务时,我得到了不受支持的媒体类型错误

serviceImpl 类的代码

private final String URI = "http://localhost:8082/admin/import/servicearticles";

@Override
public void insertData(List<ServiceArticle> serviceArticles) {
    logger.error("Inside insertData() in service");

    RestTemplate restTemplate = new RestTemplate();

    try {
            restTemplate.postForObject(URI, serviceArticles, ServiceArticle.class);
    } catch (ResourceAccessException e) {
        logger.error("ServiceArticleAdmin Service Unavailable.");

下面是映射到这个调用的不同微服务中控制器的代码

@RequestMapping(value = "/import/servicearticles", method =    RequestMethod.POST, consumes= MediaType.APPLICATION_JSON_VALUE , produces = MediaType.APPLICATION_JSON_VALUE)
 public ResponseEntity<ServiceArticle> addAll(@RequestBody List<ServiceArticle> serviceArticles) {

    List<ServiceArticle> serviceArticlesAdded = serviceArticleAdminService.addAll(serviceArticles);

    return new ResponseEntity(serviceArticlesAdded, HttpStatus.OK);
}

我在 pom.xml 中添加了以下依赖项

   <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.8.6</version>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.dataformat</groupId>
        <artifactId>jackson-dataformat-xml</artifactId>
        <version>2.8.6</version>
    </dependency>

我的 servlet-context.xml 中有以下 bean 定义

<bean
    class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <property name="messageConverters">
        <list>
            <ref bean="jsonMessageConverter" />
        </list>
    </property>
</bean>

<!-- To convert JSON to Object and vice versa -->
<bean id="jsonMessageConverter"
    class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
</bean>

请帮我弄清楚我在哪里犯了错误。 有什么方法可以在调用时将响应类型设置为 application/json restTemplate.postForObject 方法

我使用 REST 客户端插件进行了验证,它在那里工作,但不是通过我的 Java 代码。请帮忙。

【问题讨论】:

    标签: java spring rest spring-mvc


    【解决方案1】:

    似乎缺少Content-Type: application/json 标头。 您的方法还返回文章列表,而不是单个文章,因此postForObject 方法中的第三个参数不正确。

    以下代码应该可以完成这项工作:

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    
    HttpEntity<List<ServiceArticle>> request = new HttpEntity<>(serviceArticles, headers);
    
    ResponseEntity<List<ServiceArticle>> response = 
        restTemplate.exchange(URI, HttpMethod.POST, request,
            new ParameterizedTypeReference<List<ServiceArticle>>() { });
    

    【讨论】:

    • 谢谢@Eien 的回答,我用这段代码试过了,我得到了 org.springframework.web.client.HttpServerErrorException: 500 Server Error
    • 是的,它是在调用 restTemplate.exchange() 时出现的,它映射到您提到的 URI
    • 堆栈跟踪:在 org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:700) 的 org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:94) org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:653) 在 org.springframework.web.client.RestTemplate.execute(RestTemplate.java:613) 在 org.springframework.web.client.RestTemplate.exchange( RestTemplate.java:531) 在 no.bring.priceengine.servicearticle.service.impl.ServiceArticleAdminServiceImpl.insertData(ServiceArticleAdminServiceImpl.java:65)
    • 检查您从代码中调用的微服务的日志。似乎错误来自那里。
    • 控制永远不会进入那个微服务代码。这是应该在 restTemplate.exchange() @RequestMapping(value = "/import/servicearticles", method = RequestMethod.POST, consumes= MediaType.APPLICATION_JSON_VALUE ,produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity addAll 上调用的方法(@RequestBody List serviceArticles) { List serviceArticlesAdded = serviceArticleAdminService.addAll(serviceArticles);返回新的 ResponseEntity(serviceArticlesAdded, HttpStatus.OK); }
    【解决方案2】:
    @RestController
    @RequestMapping("/db")
    public class EmployeeDataServerResource {
    
        @Autowired
        EmployeeInterface ei;
    
        @PostMapping("/add")
        public EmployeeTable addEmployee(@Valid @RequestBody EmployeeTable      employeeTable) {
    
             ei.save(employeeTable);
             return employeeTable;
        }
    }
    

    这是我的restController方法

    public String onSave() {    
        try {
        EmployeeTable et = new EmployeeTable();
        et.setFirstName(firstName.getValue());
        et.setLastName(lastName.getValue());
        et.setEmail(email.getValue());
        et.setBirthdate(birthDate.getValue());
        et.setNumber(number.getValue());
        et.setPassword(pswd.getValue());
        et.setGender(rgroup.getValue());
        et.setCountry(select.getValue());
        et.setHobbiesLst(hobbies);
    
        String uri = "http://localhost:8090/db/add"; 
                  
        HttpHeaders headers=new HttpHeaders();
        headers.set("Content-Type", "application/json");
        HttpEntity requestEntity=new HttpEntity(et, headers);
    
        ResponseEntity<EmployeeTable> addedRes = restTemplate.exchange(uri, HttpMethod.POST,requestEntity,EmployeeTable.class);
        return ""+addedRes.getStatusCodeValue();
          
        }catch (Exception e) {
            System.out.println(""+e.toString());
            return e.toString();
        }   
    }
    

    这是为了使用 restController 在数据库中添加新员工。 它对我有用... 谢谢

    【讨论】:

      【解决方案3】:

      这段代码可以解决你的两个问题:

      @RequestMapping(value = "/postnotewithclient",method = RequestMethod.POST)
      public String postNote(@RequestBody  Note notes)
      {
          HttpHeaders headers = new HttpHeaders();
          headers.setContentType(MediaType.APPLICATION_JSON);
          headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
          HttpEntity<Note> entity = new  HttpEntity<Note>(notes,headers);
          return restTemplate.exchange("http://localhost:8080/api/notes", HttpMethod.POST, entity, String.class).getBody();
      
      }
      

      【讨论】:

        【解决方案4】:

        在我的情况下,发布请求一切正常,但仍然报告了不受支持的异常。在对代码进行了一些调整之后,真正的问题浮出水面,那是因为我的一个领域有 Custom Deserializer

        调试提示: 确保您的 REST API 运行良好。首先尝试以字符串形式接收请求,然后尝试使用对象映射器将该字符串转换为所需对象。

        以上提示不应该用于生产就绪代码。希望这可以帮助某人

        干杯!

        【讨论】:

          猜你喜欢
          • 2017-10-31
          • 1970-01-01
          • 2014-05-10
          • 2019-05-01
          • 2017-07-05
          • 2016-11-26
          • 2015-08-21
          相关资源
          最近更新 更多