web-dev-qa-db-fra.com

Spring @RestController ne renvoyant pas de réponse en texte brut

J'expérimente avec le nouveau Spring 4.0 @RestController pour renvoyer une réponse texte simple d'un contrôleur:

@RestController
@RequestMapping(value = "/heartbeat")
public class HeartbeatController {

    private static final Logger logger = LoggerFactory.getLogger(HeartbeatController.class);

    @RequestMapping
    public String heartbeat() {
        logger.info("Received heartbeat!");
        return "I'm Alive!";
    }

    @RequestMapping(value = "/test", produces = MediaType.TEXT_PLAIN_VALUE)
    public String heartbeat2() {
        logger.info("Received heartbeat!");
        return "I'm Alive!";
    }
}

Quand j'accède à/battement de coeur puis je reviens:

"I'm Alive!"

Le résultat inclut les guillemets, ce à quoi je ne m'attendais pas.

Lorsque j'accède à/battement de coeur/test, je reçois une réponse vide, mais je m'attends à ce que je sois vivant! texte.

UPDATE

curl -i http://myserver.com/rest/heartbeat

HTTP/1.1 200 OK Type de contenu: application/json; charset = UTF-8 Serveur: Développement/1.0 Date: mardi, 17 décembre 2013 18:59:08 GMT Contrôle de cache: no-cache Expire: ven, 01 janv. 1990 Longueur du contenu 00:00:00 GMT: 12

"Je suis vivant!"

curl -i -H "Accepter: application/json" http://myserver.com/rest/heartbeat HTTP/1.1 200 OK Type de contenu: application/json; charset = UTF-8 Serveur: Développement/1.0 Date: mar 17 déc 2013 19:01:12 GMT Contrôle de cache: no-cache Expire le: vendredi 1 janvier 1990 00:00:00 GMT Contenu-Longueur: 12

"Je suis vivant!"

curl -i http://myserver.com/rest/heartbeat/test

HTTP/1.1 406 Not Acceptable Serveur: Développement/1.0 Date: Mar, 17 Dec 2013 19:00:13 GMT Contrôle de cache: no-cache Expire le: Ven, 01 Jan 1990 00:00:00 GMT Contenu-Length: 0

curl -i -H "Accepter: text/plain" http://myserver.com/rest/heartbeat/test

HTTP/1.1 406 Not Acceptable Serveur: Développement/1.0 Date: Mar, 17 Dec 2013 19:02:06 GMT Cache-Control: no-cache Expire le: Ven, 01 Jan 1990 00:00:00 GMT Contenu-Length: 0

11
Marcel Overdijk

J'ai découvert qu'il me manquait le StringHttpMessageConverter dans le configureMessageConverters de mon WebConfig. Je configurais les convertisseurs de messages pour contrôler le ObjectMapper de Jackson.

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
    mappingJackson2HttpMessageConverter.setPrettyPrint(SystemProperty.environment.value() == Development);
    mappingJackson2HttpMessageConverter.setObjectMapper(objectMapper());
    converters.add(mappingJackson2HttpMessageConverter);
    converters.add(new StringHttpMessageConverter()); // THIS WAS MISSING
}
17
Marcel Overdijk

@RestController est une annotation pratique qui signifie que vous n'avez plus besoin de spécifier une annotation @ResponseBody sur vos méthodes.

Mais cela signifiera que votre type de réponse est défini par défaut sur JSON et qu'il est donc placé entre guillemets pour être correctement formé.

4
englishteeth

@RestController combine @Controller et @ResponseBody sur votre classe de contrôleur, sous la forme indiqué dans la documentation .

Lorsque vous annotez une méthode/un contrôleur avec @ResponseBody, Spring vous assiste dans la négociation de contenu en utilisant l'en-tête de requête HTTP Accept et l'attribut produces sur votre annotation.

Dans ton cas:

  • Vous obtenez une réponse application/json pour votre action de pulsation, car votre client HTTP demande probablement ce type de contenu et Spring a négocié le contenu.
  • Vous obtenez un HTTP 406 pour votre action hearbeat2, car la négociation de contenu a échoué. Vous avez spécifié text/plain en tant que produit Content-Type sur votre contrôleur, alors que votre client HTTP ne répertorie probablement que application/json dans son en-tête de demande Accept.

Update : J'ai utilisé exactement les mêmes requêtes curl mais je n'obtiens pas les mêmes résultats. Peut-être qu'un filtre ou un proxy-cache HTTP modifie les en-têtes HTTP?

Le format par défaut est text/plain:

➜ curl -v http://localhost:8080/heartbeat
> GET /heartbeat HTTP/1.1
> User-Agent: curl/7.30.0
> Host: localhost:8080
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Content-Type: text/plain;charset=ISO-8859-1
< Content-Length: 13
< Date: Wed, 18 Dec 2013 13:34:12 GMT
<
Hello, World!%

Et avec un attribut produces text/plain:

➜ curl -H "Accept: text/plain" -v http://localhost:8080/heartbeat/test
> GET /heartbeat/test HTTP/1.1
> User-Agent: curl/7.30.0
> Host: localhost:8080
> Accept: text/plain
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Content-Type: text/plain
< Content-Length: 13
< Date: Wed, 18 Dec 2013 13:39:07 GMT
<
Hello, World!%

Cet exemple d'application fait la même chose et obtient de bons résultats.

2
Brian Clozel

Cela fonctionne pour moi:

  1. ajoutez ceci dans maven

    com.fasterxml.jackson.core jackson-databind 2.4.4

  2. assurez-vous que <mvc:annotation-driven /> est configuré au printemps

0
cn123h

Cette solution a fonctionné pour moi. Veuillez vérifier les points suivants.

  1. Assurez-vous que votre DTO est sérialisable et comporte des champs, des getters et des setters sérialisables
  2. Vérifiez les dépendances pour Jackson. Tu aurais dû
    • com.fasterxml.jackson.core: jackson-core: 2.4.1
    • com.fasterxml.jackson.core: jackson-databind: 2.4.1
    • com.fasterxml.jackson.core: jackson-annotations: 2.4.1
    • com.fasterxml.jackson.datatype: jackson-datatype-joda: 2.4.1
    • com.fasterxml.jackson.datatype: jackson-datatype-jsr310: 2.4.1
  3. Correction de l'annotation RequesMapping:

    @RequestMapping(value = "/test", consumes = "*/*")

  4. Vérifiez que vous avez la directive <mvc:annotation-driven />

0
Fırat KÜÇÜK