2017-11-30 9 views
2

, um vorbei einen sauberen und intelligenten Code zu schreiben, ich frage mich, was kann ich tun, um mein eigentliches Stück Code zu verbessern:Der beste Weg Parameter restTemplate.getForObject

public JSONObject getCustomer(final String customerId) { 
    if (customerId == null || customerId.equals("")) { 
     return null; 
    } else { 
     final RestTemplate restTemplate = new RestTemplate(); 
     final String result = restTemplate.getForObject("http://localhost:6061/customers/" + customerId, 
       String.class); 
     return new JSONObject(result); 
    } 
} 

Vor allem, I didn‘ Ich mag die Art und Weise, wie ich die URL erstellt habe, und auch nicht den Wert von customerId.

Ich mag etwas haben, wie JPA, wo ich einige Informationen geben einen Parameter frage, nur klar zu sein (in Pseudo-Code):

public JSONObject getCustomer(final String customerId) { 
    final RestTemplate restTemplate = new RestTemplate(); 
    final Query query = restTemplate.query("http://localhost:6061/customers/:customerId"); 

    query.addParameter("customerId", customerId); 
    JSONObject result = query.getForObject(); 

    return result; 
} 

Wenn dann customerIdnull oder einige weißen Räume seien oder nicht vorhanden, ich möchte, dass das Ergebnis null wäre. Gibt es eine Möglichkeit, dies mit einer Standardbibliothek zu tun?

Dank

Antwort

1

Zunächst einmal würde ich das else Zweig entfernen und den Zustand Refactoring:

public JSONObject getCustomer(final String customerId) { 
    if (isNull(customerId) || customerId.trim().isEmpty()) { 
     return null; 
    } 
    ... 
} 

Zweitens, wenn Sie eine Reihe von URI Variablen haben, Spring guys recommend mit einem Map<String, String>:

final String templateURL = "http://localhost:6061/customers/{customerId}"; 
final Map<String, String> variables = new HashMap<>(); 

variables.put("customerId", customerId); 
... 

template.getForObject(templateURL, String.class, variables); 

Dritte , die Methode sollte keine RestTemplate Instanz selbst erstellen. Ich würde es vorziehen, die bereits abgestimmten Objekt in eine Instanz Feld Injektion:

getTemplate().getForObject(templateURL, String.class, variables); 

Schließlich möchte ich nennen die result sinnvoller:

final String customerRepresentation = ...; 

Einige Anmerkungen:

  1. getCustomer gibt tatsächlich eine JSONObject, keine Customer zurück.
  2. templateURL Hardcode die Basis-URL sowie die URL zu Kunden.
  3. Die Methode macht eine Menge Arbeit (übernimmt zu viel Verantwortung) - Argument Validierung, URL-Konstruktion, eine Anfrage. Versuchen Sie, diese Verantwortlichkeiten auf die entsprechenden Methoden aufzuteilen.
+1

Dies ist: 'template.getForObject (templateURL, String.class, Variablen);' ist, was ich gesucht habe ... danke – Alessandro

1

Erstens würde ich eher DTO Objekte verwenden, um die Antwortdaten zu halten und sie zu manipulieren, anstatt eine String-Darstellung der Nutzlast verwendet wird. Du kannst es also so ändern. Hier kümmert sich Jackson um die Serialisierung und Deserialisierung Ihrer Daten.

CustomerDTO customerDTO = restTemplate 
        .getForEntity("http://localhost:6061/customers/{customerId}", CustomerDTO.class, customerId).getBody(); 

Sie können javax.validators wie @Min, @NotEmpty usw. an Ihrem Controller für die leeren Werte überprüfen verwenden. Ein Beispiel ist unten angegeben.

@RequestMapping(value = someURL, params = {"id"}) 
public SomeResponse doSomething(@PathVariable(value = "id") @Size(min=1) String id) 

Dies wirft ein ValidationException mit einer entsprechenden Fehlermeldung, die von Ihnen angepasst werden kann. Sie müssen dann einen Fehlerbehandlungsaspekt haben, der die Fehlermeldung in ErrorDTO Objekt setzt und den Statuscode entsprechend festlegen.