Devo usare il tipo di data in JAX-RS @PathParam?


9

Questo è quello che sto pensando di fare su un server JEE Glassfish usando Jersey.

@GET
@Path("/{name}/{date}")
public String getMessages(@PathParam("name") String name, @PathParam("date") Date date)

Mi piace l'idea di poter dire alle persone che consumano questo servizio web RESTful che "La data qui è tutto ciò che funziona con la classe Date in Java". È piuttosto semplice dal punto di vista del fatto che possono semplicemente guardare le specifiche della data e avranno già un modello funzionante con cui possono testare.

Il problema di cui sono preoccupato è che quando lo faccio, JAX-RS non è molto carino quando Date () non piace ciò che ottiene nel costruttore. Dato che Date () genera un errore se non è in grado di analizzare ciò che viene fornito (come se si passa la stringa "oggi" anziché una data reale), il server JEE restituisce un errore 404.

È una buona pratica? C'è un modo migliore per farlo che non sto pensando?

Risposte:


8

Sembra una cattiva idea. Per prima cosa, il costruttore Date su cui fare affidamento è stato deprecato da Java 1.1 a favore di DateFormat.parseDate (), proprio perché non è chiaro come le stringhe debbano essere analizzate in date, poiché le regole sono diverse per le diverse località.

La mia raccomandazione sarebbe quella di attenersi a un formato specifico, preferibilmente il yyyy-MM-dd compreso a livello internazionale, e utilizzare un DateFormat per analizzare la data da una stringa all'interno del servizio, il che chiarisce come utilizzare il servizio Web e ti consente seguire qualunque sia la convenzione standard per la restituzione dei messaggi di errore per i tuoi servizi web quando qualcosa va storto.


11

Sto usando una classe personalizzata DateParam:

@GET
@Path("/{name}/{date}")
public String getMessages(@PathParam("name") String name, @PathParam("date") DateParam date)
  Date date = date.getDate();

La classe è definita come:

public class DateParam {
  private final Date date;

  public DateParam(String dateStr) throws WebApplicationException {
    if (isEmpty(dateStr)) {
      this.date = null;
      return;
    }
    final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    try {
      this.date = dateFormat.parse(dateStr);
    } catch (ParseException e) {
      throw new WebApplicationException(Response.status(Status.BAD_REQUEST)
        .entity("Couldn't parse date string: " + e.getMessage())
        .build());
    }
  }

  public Date getDate() {
    return date;
  }
}

Se il parametro è vuoto, otterrai una data nulla. È possibile estendere DateParamda un campo finale statico pubblico per valori di data non definiti. Ciò renderebbe più chiaro il test per parametri di data non definiti.

Uno svantaggio qui è che per ogni DateParam, viene creata una nuova istanza di SimpleDateFormat. Tuttavia, poiché SimpleDateFormat non è thread-safe, non possiamo riutilizzarlo facilmente.


3
1+. Java 8 ha introdotto un thread sicuro DateTimeFormatter. Per Java <= 7, ThreadLocal
userei

3

Chi utilizzerà il tuo servizio? Si preoccuperanno di cercare le specifiche della Dateclasse e capire che tipo di stringhe analizzerà? Non lo farei, anche se essendo un programmatore Java saprei dove cercare ;-)

Penso che dovresti prima dire ai tuoi utenti come appariranno i tuoi URI, ad es

.../your-resource-name/yyyy-MM-dd

e quindi cercare un modo per far sì che Jersey ti aiuti ad analizzare il formato data che hai scelto. Ciò potrebbe significare l'utilizzo di un Datetipo di parametro e forse la specifica di un'espressione regolare nella tua @Pathannotazione, ad esempio

@Path(/{name}/{date: [0-9][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9]/)

o usando qualche altra classe in grado di analizzare una data nel tuo formato. Come gestire gli URI che non corrispondono alle specifiche fornite ai tuoi utenti è ancora un'altra cosa che dovresti decidere come gestire indipendentemente da quanto sopra (restituire una risorsa predefinita? Restituire un errore 404?).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.