2017-10-17 5 views
0

Je développe une API REST basée sur HAL avec démarrage Spring. J'ai besoin d'un point de terminaison dans mon contrôleur, qui envoie un fichier au client. Il y a quelques exemples sur SO, mais il ne fonctionne pas à cause de l'exception suivante:API REST basée sur HAL avec point de terminaison de fichier de téléchargement

Resolved exception caused by Handler execution: 
    org.springframework.http.converter.HttpMessageNotWritableException: Could not write 
    content: No serializer found for class java.io.ByteArrayInputStream and no properties 
    discovered to create BeanSerializer (to avoid exception, disable 
    SerializationFeature.FAIL_ON_EMPTY_BEANS) through reference chain: 
    org.springframework.core.io.ByteArrayResource["inputStream"]); 
    nested exception is com.fasterxml.jackson.databind.JsonMappingException: 
    No serializer found for class java.io.ByteArrayInputStream 
    and no properties discovered to create BeanSerializer (to avoid exception, 
    disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: 
    org.springframework.core.io.ByteArrayResource["inputStream"]) 

Mon application Spring:

@EnableHypermediaSupport(type = HAL) 
@SpringBootApplication 
public class MyServer { 
    public static String CURIE_NAMESPACE = "myNS"; 

    public @Bean 
    CurieProvider curieProvider() { 
     return new DefaultCurieProvider(CURIE_NAMESPACE, new UriTemplate("/docs/html5/{rel}.html")); 
    } 

    @Bean 
    public HttpMessageConverters customConverters() { 
     ByteArrayHttpMessageConverter arrayHttpMessageConverter = new ByteArrayHttpMessageConverter(); 
     return new HttpMessageConverters(arrayHttpMessageConverter); 
    } 

    public static void main(String[] args) { 
     SpringApplication.run(MyServer.class, args); 
    } 
} 

Ma classe de contrôleur ressemble à ceci:

@BasePathAwareController 
@Slf4j 
@RequiredArgsConstructor(onConstructor = @__(@Autowired)) 
public class MyController implements ResourceProcessor<RepositoryLinksResource> { 
    public static final String ENDPOINT_URL = "/myResource"; 
    ... 

    @RequestMapping(value = ENDPOINT_URL + "/download", method = RequestMethod.GET) 
    public ResponseEntity<ByteArrayResource> downloadAttachment(){ 
     ... 
     // get from my service the resource 
     MyClass myResource = myService.getResource(); 

     String filename = myResource.getFilename(); 
     String contentType = myResource.getContentType(); 

     try (InputStream myStream = myResource.getStream()) { 
      HttpHeaders respHeaders = new HttpHeaders(); 
      respHeaders.setContentType(MediaType.valueOf(contentType)); 
      respHeaders.setContentDispositionFormData("attachment", filename); 

      byte[] bytes = IOUtils.toByteArray(myStream); 
      ByteArrayResource byteResource = new ByteArrayResource(bytes); 

      return ResponseEntity.ok() 
        .headers(respHeaders) 
        .contentType(MediaType.parseMediaType(contentType)) 
        .body(byteResource); 
     } catch (Exception e) { 
     ... 
     } 
    } 
} 

J'ajoute le bean convertisseur personnalisé comme indiqué dans mon code d'application. Mais je pense qu'en raison de cette isssue @EnableHypermediaSupport is not compatible with Spring Boot's Jackson2ObjectMapperBuilder #333 il ne fonctionne pas !?

Version printemps-boot: 1.5.2.RELEASE

Version printemps-hateoas: 0.23.0.RELEASE

Toutes les idées?

Répondre

0

Vous avez un décalage entre votre convertisseur de message et votre type de contenu. Utilisez un ResourceHttpMessageConverter ou modifiez votre type de retour à ResponseEntity < octet []>.

+0

Rien de vos suggestions fonctionnent ... Mais merci. – Oni1