je configure mon messageconverter comme alors de Jackson
class Foo{int x; int y}
et dans le contrôleur
@ResponseBody
public Foo method(){
return new Foo(3,4)
}
à partir de là, je compte renvoyer une chaîne JSON {x: '3', y: '4'} à partir du serveur sans autre configuration. mais obtenir une réponse d'erreur 404 à ma demande ajax
Si la méthode est annotée avec @ResponseBody, le type de retour est écrit dans le corps HTTP de la réponse. La valeur de retour sera convertie en type d'argument de méthode déclaré à l'aide de HttpMessageConverters.
Ai-je tort ? ou devrais-je convertir moi-même l'objet de réponse en chaîne Json moi-même à l'aide d'un sérialiseur, puis en renvoyant cette chaîne en tant que réponse (je pourrais faire les réponses correctement) ou dois-je effectuer d'autres configurations? comme ajouter des annotations pour la classe Foo
voici mon conf.xml
<bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jacksonMessageConverter"/>
</list>
</property>
Vous avez besoin des éléments suivants:
<mvc:annotation-driven />
dans spring.xml
org.codehaus.jackson:jackson-mapper-asl
) dans classpath.Utilisez comme suit:
@RequestMapping(method = { RequestMethod.GET, RequestMethod.POST })
public @ResponseBody Foo method(@Valid Request request, BindingResult result){
return new Foo(3,4)
}
Cela fonctionne pour moi.
S'il vous plaît noter que
@ResponseBody
est appliqué pour renvoyer le type, pas pour la définition de la méthode.@RequestMapping
pour que Spring la détecte.L'interface de MessageConverter http://static.springsource.org/spring/docs/3.0.x/javadoc-api/ définit une méthode getSupportedMediaTypes (), qui dans le cas de MappingJacksonMessageCoverter renvoie application/json
public MappingJacksonHttpMessageConverter() {
super(new MediaType("application", "json", DEFAULT_CHARSET));
}
Je suppose qu'un en-tête demande: application/json est manquant.
Cela a fonctionné pour moi:
@RequestMapping(value = "{p_LocationId}.json", method = RequestMethod.GET)
protected void getLocationAsJson(@PathVariable("p_LocationId") Integer p_LocationId,
@RequestParam("cid") Integer p_CustomerId, HttpServletResponse response) {
MappingJacksonHttpMessageConverter jsonConverter =
new MappingJacksonHttpMessageConverter();
Location requestedLocation = new Location(p_LocationId);
MediaType jsonMimeType = MediaType.APPLICATION_JSON;
if (jsonConverter.canWrite(requestedLocation.getClass(), jsonMimeType)) {
try {
jsonConverter.write(requestedLocation, jsonMimeType,
new ServletServerHttpResponse(response));
} catch (IOException m_Ioe) {
// TODO: announce this exception somehow
} catch (HttpMessageNotWritableException p_Nwe) {
// TODO: announce this exception somehow
}
}
}
Notez que la méthode ne retourne rien: MappingJacksonHttpMessageConverter#write()
fait la magie.
Une erreur HTTP 404 signifie simplement que la ressource est introuvable. Cela peut avoir 2 causes:
Pour résoudre le problème 1, assurez-vous que vous utilisez ou fournissez l'URL de demande correcte (sensible à la casse!). Pour résoudre le problème 2, recherchez les erreurs de démarrage dans les journaux de démarrage du serveur et corrigez-les en conséquence.
Tout cela va au-delà du code et des informations affichés à ce jour.
J'ai trouvé que j'avais également besoin de jackson-core-asl.jar, pas seulement jackson-mapper-asl.jar
En plus des réponses ici ..
si vous utilisez jquery côté client, cela a fonctionné pour moi:
Java:
@RequestMapping(value = "/ajax/search/sync")
public ModelAndView sync(@RequestBody Foo json) {
Jquery (vous devez inclure le fichier json2.js de Douglas Crockford pour pouvoir utiliser la fonction JSON.stringify):
$.ajax({
type: "post",
url: "sync", //your valid url
contentType: "application/json", //this is required for spring 3 - ajax to work (at least for me)
data: JSON.stringify(jsonobject), //json object or array of json objects
success: function(result) {
//do nothing
},
error: function(){
alert('failure');
}
});
Ceci est juste une hypothèse, mais par défaut, Jackson ne détecte que les champs publics (et les accesseurs publics; mais tous les paramètres indépendamment de la visibilité). Il est possible de configurer cela (avec la version 1.5 ) pour détecter automatiquement les champs privés si cela est souhaité (voir ici pour plus de détails).
Je suppose que 404 n’est pas lié à votre HttpMessageConverter. J'avais le même problème 404 et la raison était que j'avais oublié que seules les demandes correspondant à<url-pattern>
étaient envoyées à DispatcherServlet (j'ai changé le mappage de demande de * .do à * .json). Peut-être que c'est aussi ton cas.