J'ai un contrôleur Spring MVC qui renvoie une chaîne JSON et j'aimerais définir le type MIME sur application/json. Comment puis je faire ça?
@RequestMapping(method=RequestMethod.GET, value="foo/bar")
@ResponseBody
public String fooBar(){
return myService.getJson();
}
Les objets métier étant déjà disponibles sous forme de chaînes JSON, utiliser MappingJacksonJsonView
n'est pas la solution pour moi. @ResponseBody
est parfait, mais comment puis-je définir le type MIME?
J'envisagerais de refactoriser le service pour qu'il retourne votre objet de domaine plutôt que les chaînes JSON et laisse Spring gérer la sérialisation (via le MappingJacksonHttpMessageConverter
au fur et à mesure que vous écrivez). À compter du printemps 3.1, la mise en œuvre semble assez soignée:
@RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE,
method = RequestMethod.GET
value = "/foo/bar")
@ResponseBody
public Bar fooBar(){
return myService.getBar();
}
Commentaires:
Premièrement le <mvc:annotation-driven />
ou la @EnableWebMvc
doit être ajouté à la configuration de votre application.
Ensuite, l'attribut produit de la @RequestMapping
annotation permet de spécifier le type de contenu de la réponse. Par conséquent, il doit être défini sur MediaType.APPLICATION_JSON_VALUE (ou "application/json"
).
Enfin, Jackson doit être ajouté pour que toute sérialisation et dé-sérialisation entre Java et JSON soit gérée automatiquement par Spring (la dépendance de Jackson est détectée par Spring et le MappingJacksonHttpMessageConverter
être sous le capot).
Utilisez ResponseEntity
au lieu de ResponseBody
. De cette façon, vous avez accès aux en-têtes de réponse et vous pouvez définir le type de contenu approprié. Selon le Spring docs :
Le
HttpEntity
est similaire à@RequestBody
et@ResponseBody
. Outre l'accès au corps de la demande et de la réponse,HttpEntity
(et à la sous-classe propre à la réponseResponseEntity
) permet également d'accéder aux en-têtes de requête et de réponse.
Le code ressemblera à ceci:
@RequestMapping(method=RequestMethod.GET, value="/fooBar")
public ResponseEntity<String> fooBar2() {
String json = "jsonResponse";
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setContentType(MediaType.APPLICATION_JSON);
return new ResponseEntity<String>(json, responseHeaders, HttpStatus.CREATED);
}
Vous ne pourrez peut-être pas le faire avec @ResponseBody, mais quelque chose comme ceci devrait fonctionner:
package xxx;
import Java.io.ByteArrayOutputStream;
import Java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class FooBar {
@RequestMapping(value="foo/bar", method = RequestMethod.GET)
public void fooBar(HttpServletResponse response) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(myService.getJson().getBytes());
response.setContentType("application/json");
response.setContentLength(out.size());
response.getOutputStream().write(out.toByteArray());
response.getOutputStream().flush();
}
}
Je ne pense pas que ce soit possible. Il semble y avoir une Jira ouverte pour cela:
SPR-6702: Définition explicite de la réponse Content-Type dans @ResponseBody
Registre org.springframework.http.converter.json.MappingJacksonHttpMessageConverter
en tant que convertisseur de message et renvoie l'objet directement à partir de la méthode.
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="webBindingInitializer">
<bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer"/>
</property>
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
</list>
</property>
</bean>
et le contrôleur:
@RequestMapping(method=RequestMethod.GET, value="foo/bar")
public @ResponseBody Object fooBar(){
return myService.getActualObject();
}
Cela nécessite la dépendance org.springframework:spring-webmvc
.
Je ne pense pas que vous puissiez le faire, à part response.setContentType(..)