2013-03-28 25 views
13

Sto tentando di inviare una rappresentazione JSON di una mappa nel mio controller come parametro POST.Passaggio di JSON Map in Spring MVC Controller

@RequestMapping(value = "/search.do", method = RequestMethod.GET, consumes = { "application/json" }) 
public @ResponseBody Results search(@RequestParam("filters") HashMap<String,String> filters, HttpServletRequest request) { 
     //do stuff 
} 

ho scoperto che @RequestParam sarebbe solo gettare un errore 500, così ho provato ad utilizzare @ModelAttribute invece.

@RequestMapping(value = "/search.do", method = RequestMethod.GET, consumes = { "application/json" }) 
public @ResponseBody Results search(@ModelAttribute("filters") HashMap<String,String> filters, HttpServletRequest request) { 
     //do stuff 
} 

Questo rispondeva correttamente alle richieste, ma ho realizzato che la Mappa era vuota. Con la successiva sperimentazione, ho scoperto che qualsiasi oggetto (non solo HashMap) sarebbe stato istanziato, ma nessun campo sarebbe stato riempito. Io ho Jackson sul mio classpath, e i miei controller risponderanno con JSON. Tuttavia, sembrerebbe che la mia attuale configurazione non permetta a Spring di leggere JSON tramite un parametro GET/POST.

Come si passano le rappresentazioni JSON di oggetti da una richiesta AJAX lato client a un controller Spring come parametro di richiesta e si ottiene un oggetto Java?

EDIT aggiungendo il mio rilevanti configurazione di Spring

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> 
    <property name="mediaTypes"> 
     <map> 
     <entry key="html" value="text/html" /> 
     <entry key="json" value="application/json" /> 
     </map> 
    </property> 
    <property name="viewResolvers"> 
     <list> 
     <bean class="org.springframework.web.servlet.view.UrlBasedViewResolver"> 
      <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> 
      <property name="prefix" value="/WEB-INF/jsp/" /> 
      <property name="suffix" value=".jsp" /> 
     </bean> 
     </list> 
    </property> 
    <property name="defaultViews"> 
     <list> 
     <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"> 
      <property name="prefixJson" value="true" /> 
     </bean> 
     </list> 
    </property> 
    </bean> 
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> 
    <property name="messageConverters"> 
     <list> 
     <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/> 
     </list> 
    </property> 
    </bean> 

Su suggerimento di un commentatore, ho provato @RequestBody. Questo funzionerà, a condizione che le stringhe JSON siano citate con le virgolette .

@RequestMapping(value = "/search.do", method = RequestMethod.POST, consumes = { "application/json" }) 
public @ResponseBody Results<T> search(@RequestBody HashMap<String,String> filters, HttpServletRequest request) { 
     //do stuff 
} 

Questo fa risolvere il mio problema immediato, ma io sono ancora curioso di sapere come ou potrebbero passare più oggetti JSON tramite una chiamata AJAX.

+0

Hai il bean MappingJacksonJsonView sul tuo spring-context.xml? –

+0

Come stai postando i dati, come parte di un modulo, ajax request? – clav

+0

Controlla l'annotazione '@ RequestBody'. –

risposta

4

Questo risolve il mio problema immediato, ma sono ancora curioso di sapere come si potrebbe passare in più oggetti JSON tramite una chiamata AJAX.

Il modo migliore per farlo è disporre di un oggetto wrapper che contenga i due (o più) oggetti che si desidera passare. È quindi costruire l'oggetto JSON come un array di due oggetti cioè

[ 
    { 
    "name" : "object1", 
    "prop1" : "foo", 
    "prop2" : "bar" 
    }, 
    { 
    "name" : "object2", 
    "prop1" : "hello", 
    "prop2" : "world" 
    } 
] 

Poi nel metodo di controllo si riceve il corpo della richiesta come un unico oggetto ed estrarre i due oggetti contenuti. cioè:

@RequestMapping(value="/handlePost", method = RequestMethod.POST, consumes = {  "application/json" }) 
public void doPost(@RequestBody WrapperObject wrapperObj) { 
    Object obj1 = wrapperObj.getObj1; 
    Object obj2 = wrapperObj.getObj2; 

    //Do what you want with the objects... 


} 

L'oggetto wrapper sarebbe simile ...

public class WrapperObject {  
private Object obj1; 
private Object obj2; 

public Object getObj1() { 
    return obj1; 
} 
public void setObj1(Object obj1) { 
    this.obj1 = obj1; 
} 
public Object getObj2() { 
    return obj2; 
} 
public void setObj2(Object obj2) { 
    this.obj2 = obj2; 
} 

} 
+0

Grazie per la risposta RequestBody. Avevo una mappa nella mia richiesta, ma sarebbe sempre vuota, rendendo anche la risposta vuota. Ora RequestBody davanti alla mappa lo ha risolto! – Aliya

1

È possibile utilizzare la libreria Jackson convertire da JSON a Map.

@ web-context.xml

<bean id="messageAdapter" class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> 
    <property name="messageConverters"> 
     <list> 
      <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" /> 
     </list> 
    </property> 
</bean> 

@maven dipendenze:

<dependency> 
    <groupId>org.codehaus.jackson</groupId> 
    <artifactId>jackson-core-lgpl</artifactId> 
    <version>1.9.13</version> 
</dependency> 
<dependency> 
    <groupId>org.codehaus.jackson</groupId> 
    <artifactId>jackson-mapper-lgpl</artifactId> 
    <version>1.9.13</version> 
</dependency> 

@Controller

@RequestMapping(value = "/method", method = RequestMethod.DELETE) 
public String method(
       @RequestBody Map<String, Object> obj){ 

@Request (ad esempiojquery Ajax)

$.ajax({"type": "DELETE", 
     "contentType": "application/json;", 
     "url": "/method", 
     "data": JSON.stringify({"key": "Ricardo"}), 
     "dataType": "json";} 
}); 

È molto più semplice con Python Frameworks o Play! ufff

+2

Jackson 1.9.x è in modalità di manutenzione; Suggerirei invece Jackson 2.3.x. –

0

Non stai ottenendo correttamente JSON.

fare così ....

/* 
* Mapping for Demographics And Profiling Question Filter 
*/ 
@RequestMapping (value = "/generalFilter") 
public void ageFilteration(@RequestParam Map <String,String> filterParams,HttpServletRequest request,HttpServletResponse response) throws IOException 
{ 
    // System.out.println("Geographies in Controller :"+ filterParams.get("geographies")); 
    List<FeasibilityBean> feasibilityList = feasibilityDao.getGeneralFeasibilityList(filterParams,request); 
    // System.out.println(" General Filter List Size:"+feasibilityList.size()); 
    response.getWriter().print(new Gson().toJsonTree(feasibilityList,new TypeToken<List<FeasibilityBean>>(){}.getType())); 
} 

}

Js Codice

var ages='',ageCond='',genders='',genderCond=''; 

    $.ajax({ 
     type: "POST", 
     url : url, 
     data : {ages:ages,ageCond:ageCond,genders:genders,genderCond:genderCond}, 
     beforeSend: function() { 
      $(thisVar).find('i').addClass('fa-spin'); 
     }, 
     success : function(feasibilityJson){ 

     }, 
     error : function(data) { 
      alert(data + "error"); 
     }, 
     complete:function(){ 
      $(thisVar).find('i').removeClass('fa-spin'); 
     } 
    }); 

o si desidera associare fagioli con JSON ....

https://stackoverflow.com/a/21689084/5150781 https://stackoverflow.com/a/37958883/5150781

0

ho passato l'oggetto Map per Java utilizzando sottostante Codice:

codice JavaScript:

var values = { 
        "object1" : JSON.stringify(object1), 
        "object2" : JSON.stringify(object2) 
      }; 
var response = $http.post(url,data); 

codice lato server:

@RequestMapping(value = "/deleteData",method = RequestMethod.POST,consumes = MediaType.APPLICATION_JSON_VALUE) 
    @ResponseBody 
    public Result deleteData(@RequestBody HashMap<String, Object> dataHashMap) { 
    Object1 object1= (Object1) JsonConvertor.jsonToObject((String) dataHashMap.get("object1"), Object1.class); 
     Object2 object2= (Object2) JsonConvertor.jsonToObject((String) dataHashMap.get("object2"), Object2.class); 
} 

JsonConvertor Classe:

public class JsonConvertor { 
    public static <T> Object jsonToObject(String json, Class<T> clazz) { 
    if (json == null) 
     throw new IllegalArgumentException("null cannot be converted to Object"); 
    Gson gson = new GsonBuilder().disableHtmlEscaping().setDateFormat("dd-MMM-yyyy").create(); 
    return gson.fromJson(json, clazz); 
    } 
} 
+0

Hai dimenticato di dire cosa sia 'JsonConvertor'. – kryger

+0

Modificato la soluzione come suggerito –

0
@RequestMapping(method = RequestMethod.POST) 
    public HttpEntity<Resource<Customize>> customize(@RequestBody String customizeRequest) throws IOException { 
     Map<String, String> map = mapper.readValue(customizeRequest, new TypeReference<Map<String,String>>(){}); 
     log.info("JSONX: " + customizeRequest); 
     Long projectId_L = Long.parseLong(map.get("projectId")); 
     [...] 
Problemi correlati