2016-07-07 10 views
2

Wie verwende ich RestTemplate, um ein Objekt als Parameter zu übergeben? Zum Beispiel, sagen, dass ich die folgenden Dienste mit Frühlings-Boot aufgestellt hatte:Spring RestTemplate - Übergabe von Objektparametern in GET

@RequestMapping(value = "/get1", method = RequestMethod.GET) 
public ResponseEntity<String> get1(@RequestParam(value = "parm") String parm) { 

    String response = "You entered " + parm; 
    return new ResponseEntity<String>(response, HttpStatus.OK); 
} 

@RequestMapping(value = "/get2", method = RequestMethod.GET) 
public ResponseEntity<String> get2(@RequestParam(value = "parm") MyObj parm) { 

    String response = "You entered " + parm.getValue(); 
    return new ResponseEntity<String>(response, HttpStatus.OK); 
} 

Wenn ein Client aufrufen wollte, den ersten Dienst könnten sie die folgende verwenden:

//This works fine 
RestTemplate restTemplate = new RestTemplate(); 
String response = restTemplate.getForObject("http://localhost:8080/get1?parm={parm}", String.class, "Test input 1"); 

Aber wenn ein Client wollten den zweiten Dienst rufen sie erhalten einen 500-Fehler mit dem folgenden:

//This doesn't work 
MyObj myObj = new MyObj("Test input 2"); 
RestTemplate restTemplate = new RestTemplate(); 
String response = restTemplate.getForObject("http://localhost:8080/get2?parm={parm}", String.class, myObj); 

die MyObj Klasse sieht wie folgt aus:

Ich nehme an, dass das Problem ist, dass das myObj nicht ordnungsgemäß als Parameter eingerichtet wird. Wie gehe ich dabei vor?

Vielen Dank im Voraus.

Antwort

3

Wenn Sie ein komplexes Objekt (wie MyObj) als @RequestParam verwenden, versucht Spring, eine Zeichenfolge in dieses komplexe Objekt zu konvertieren. In diesem Fall, weil MyObj nur ein einziges String Feld mit dem Namen inputValue hat, verwendet es automatisch den Wert, den Sie Ihrem Abfrageparameter übergeben, um die Eigenschaft in Ihrem Objekt zu füllen.

Zum Beispiel, wenn Sie anrufen: http://localhost:8080/get2?parm=foobar erhalten Sie eine MyObj wo inputValue wird "foobar" sein.

Wenn Sie RestTemplate sollten Sie keinen Fehler, aber anstatt wird es versuchen, new MyObj("Test input 2") in eine Zeichenfolge zu konvertieren, die toString()-Methode und die Antwort wird sein:

Sie com.example eingegeben .MyObj @ 63a815e8


Dies ist wahrscheinlich nicht das, was Sie wollen. Im Allgemeinen möchten Sie keine komplexen Objekte als Anforderungsparameter übergeben. Sie können @RequestBody mit RequestMethod.POST und restTemplate.postForEntity() verwenden, um Ihre MyObj als JSON ordnungsgemäß zu übergeben. Dies wird passieren Ihr Objekt als JSON richtig

MyObj myObj = new MyObj("Test input 2"); 
RestTemplate restTemplate = new RestTemplate(); 
String response = restTemplate.postForEntity("http://localhost:8080/get2", myObj, String.class).getBody(); 

:

ändern Controller wie folgt aus:

@RequestMapping(value = "/get2", method = RequestMethod.POST) 
public ResponseEntity<String> get2(@RequestBody MyObj parm) { 

    String response = "You entered " + parm.getInputValue(); 
    return new ResponseEntity<>(response, HttpStatus.OK); 
} 

Und es RestTemplate wie diese verwenden nennen.

+0

Funktioniert perfekt. Vielen Dank! –

+0

Große Antwort! Tatsächlich, viele popele (wenn nicht alle :)) Marshal/Unmarsch-Objekte immer als JSON. Ich frage mich immer, warum nicht eine Schnittstelle sowohl auf Client- als auch auf Serverseite implementiert wird? Solange Sie Ihren Dienst für die Welt nicht öffnen, glaube ich, es macht es perfekt ... – hublo

+0

@hublo Das ist, was ich oft bei Projekten tun, könnte der REST-Client auf der Verbraucherseite die gleiche Schnittstelle wie der REST-Dienst implementieren auf der anderen Seite. – g00glen00b

-1

Ich vermute diese: String response = restTemplate.getForObject ("http://localhost:8080/get2?parm= {Parm}", String.class, myObj)

sollte als

String Antwort ändern = restTemplate.getForObject ("http://localhost:8080/get2?parm= {parm}", MyObj.class, myObj)

+0

Nein, der zweite Parameter ('String.class') wird verwendet, um den ** Rückgabetyp ** der Antwort zu beschreiben. Die Antwort in '/ get1' und'/get2' ist ein 'String', es ist der Anforderungsparameter, der sich ändert. – g00glen00b

0

Sie müssen Wert von e übergeben Ach URI-Parameter nach responseType. Problem ist, dass RestTemplate nicht wissen, wie Sie Ihr Objekt URI-Parameter zuordnen. Sie haben ausdrücklich entsprechende myObj Methode aufzurufen den Ist-Wert abzurufen:

String response = restTemplate.getForObject(
    "http://localhost:8080/get2?parm={parm}", String.class, 
    myObj.getInputValue()); 

Unterschrift des getForObject Methode, die Sie nennen, ist: public <T> T getForObject(String url, Class<T> responseType, Object... urlVariables) throws ….

wo urlVariables ist Array von URI Variable Werte den URI zu erweitern mit.