2016-05-05 12 views
1

Ich habe eine REST-Komponente im Frühjahr. Vereinfacht sieht es so aus:Codierte Komma in URL wird als Liste im Frühjahr gelesen

@RequestMapping(value = "/route", method = RequestMethod.GET) 
public Object thisIsTheMethod(RequestParam(value = "value", required = false) List<String> values) { 
    return OtherClass.doTheThing(values); 
} 

Dies wird verwendet, um eine Liste von Strings beliebiger Länge zu konsumieren. Man könnte es eine Reihe von Möglichkeiten zur Verfügung:

localhost:8080/route?value=this&value=that 

ODER

localhost:8080/route?value=this,that 

Lassen Sie uns jetzt sagen, dass ich in einen String übergeben wollen, die ein Komma enthält: value,1. Wie würde ich das machen? Das Ersetzen des Kommas durch% 2C führt zu einer Liste von 2 Werten ("Wert", "1"). Wenn Sie etwas in Anführungszeichen setzen oder in Anführungszeichen setzen, treten ähnliche Probleme auf. Es sieht so aus, als ob es funktioniert, wenn ich mehrere Parameter habe und das Muster mit mehreren Werten verwende, aber nicht, wenn ich das durch Komma getrennte Muster verwende.

+1

nicht versucht, aber ich denke, sollte die folgende arbeiten. Definieren Sie ein Domänenobjekt, das Ihre Anforderungsobjekte modelliert (Wert in diesem Fall). Erstellen Sie eine Liste dieser Objekte als JSON, Base64 kodieren Sie sie und senden Sie die GET-Anfrage. Ändern Sie auf der Spring-Seite den Class-Typ des Request Param als eine Liste Ihrer Domain-Objekte. – Andonaeus

+2

@Andonaeus: So liegt der Wahnsinn. Das heißt, ich habe darüber nachgedacht, seit ich diesen speziellen Abschnitt dieses Projekts begonnen habe. – DrGodCarl

+0

Sehr ähnlich, aber auch ungelöst: http://stackoverflow.com/q/33484711/2954288 – Harald

Antwort

0

EDIT: Ich bin mir nicht sicher, warum ich die Erstellung eines Domain-Objekts und die Schwierigkeiten der Codierung und Decodierung der gesamten Liste stört. Es ist genauso gut, dass Sie einfach Base64 jeden Parameter codieren und jeden Parameter beim Einlesen entscheiden können.

Laut meinem Kommentar war ich in der Lage, eine Lösung zu implementieren. Ich bin nicht besonders zufrieden mit der Implementierung, aber es macht die Arbeit erledigt. Ich wiederhole, dass es mit ziemlicher Sicherheit eine bessere Lösung gibt, die in Bezug auf die Domänenobjekte und das Marshalling und die Unmarshalling der Werte einem expliziteren Ansatz folgen kann.

die Liste der Werte Angenommen wird als JSON-Liste der Wert formatiert Objekte wie:

[{"value":"test,1"},{"value": "test,2"}] 

Die Base64-Codierung ist:

W3sidmFsdWUiOiJ0ZXN0LDEifSx7InZhbHVlIjogInRlc3QsMiJ9XQ== 

Mein Controller-Setup ist wie:

@RequestMapping(value = "/test", method = RequestMethod.GET) 
@ResponseBody 
public String test(@RequestParam(value = "values", required = true) String values) throws JsonParseException, JsonMappingException, IOException{ 

    byte[] bValues = Base64.getDecoder().decode(values.getBytes()); 
    String json = new String(bValues); 
    ObjectMapper mapper = new ObjectMapper(); 
    List<Value> myObjects = mapper.readValue(json, new TypeReference<List<Value>>(){}); 
    StringBuilder result = new StringBuilder(); 

    int i = 1; 
    for (Value value : myObjects){ 
     result.append("value "); 
     result.append(" "); 
     result.append(i++); 
     result.append(": "); 
     result.append(value.getValue()); 
     result.append("<br>"); 
    } 

    result.setLength(result.length() - 1); 
    return result.length() > 0 ? result.toString() : "Test"; 
} 

public static void main(String[] args) { 
    SpringApplication.run(UatproxyApplication.class, args); 
} 

Die Wertsklasse lautet:

public class Value implements Serializable{ 

private static final long serialVersionUID = -7342446805363029057L; 

private String value; 

public Value(){ 

} 

public String getValue() { 
    return value; 
} 

public void setValue(String value) { 
    this.value = value; 
} 

}

Die Anfrage ist:

/test?values=W3sidmFsdWUiOiJ0ZXN0LDEifSx7InZhbHVlIjogInRlc3QsMiJ9XQ== 

Und die Antwort ist:

value 1: test,1 
value 2: test,2