Sollte ich den Datumstyp in JAX-RS @PathParam verwenden?

9

Dies ist, was ich überlege, auf einem JEE Glassfish-Server mit Jersey zu tun.

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

Ich mag die Idee, Leuten, die diesen RESTful-Webservice nutzen, mitteilen zu können, dass "das Datum hier alles ist, was mit der Date-Klasse in Java funktioniert". Das ist vom Standpunkt aus ziemlich einfach: Sie können sich nur die Datumsspezifikation ansehen und haben bereits ein funktionierendes Modell, mit dem sie testen können.

Das Problem, über das ich mir Sorgen mache, ist, dass JAX-RS dabei nicht sehr schön ist, wenn Date () nicht mag, was es im Konstruktor bekommt. Da Date () einen Fehler auslöst, wenn es nicht analysieren kann, was es gegeben hat (z. B. wenn Sie die Zeichenfolge "heute" anstelle eines echten Datums übergeben), gibt der JEE-Server einen 404-Fehler zurück.

Ist das eine gute Praxis? Gibt es einen besseren Weg, dies zu tun, an den ich nicht denke?

Jazzepi
quelle

Antworten:

8

Klingt nach einer schlechten Idee. Zum einen ist der Date-Konstruktor, auf den Sie sich verlassen würden, seit Java 1.1 zugunsten von DateFormat.parseDate () veraltet, gerade weil unklar ist, wie Zeichenfolgen in Datumsangaben analysiert werden sollen, da die Regeln für verschiedene Orte unterschiedlich sind.

Meine Empfehlung wäre, sich an ein bestimmtes Format zu halten, vorzugsweise das international verstandene JJJJ-MM-TT, und ein DateFormat zu verwenden, um das Datum aus einer Zeichenfolge in Ihrem Dienst zu analysieren, wodurch klar wird, wie der Webdienst verwendet wird, und dies ermöglicht Befolgen Sie die Standardkonvention für die Rückgabe von Fehlermeldungen für Ihre Webdienste, wenn ein Fehler auftritt.

Theodore Murdock
quelle
11

Ich verwende eine benutzerdefinierte Klasse DateParam:

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

Die Klasse ist definiert als:

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;
  }
}

Wenn der Parameter leer ist, erhalten Sie ein Nulldatum. Sie können DateParamundefinierte Datumswerte um ein öffentliches statisches Endfeld erweitern. Dies würde das Testen auf undefinierte Datumsparameter klarer machen.

Ein Nachteil hierbei ist, dass für jedes DateParam eine neue Instanz von SimpleDateFormat erstellt wird. Da SimpleDateFormat jedoch nicht threadsicher ist, können wir es nicht einfach wiederverwenden.

Migu
quelle
3
1+. Java 8 hat einen Thread-Safe eingeführt DateTimeFormatter. Für Java <= 7 würde ich einThreadLocal
Anthony Accioly
3

Wer wird Ihren Service nutzen? Werden sie sich die Mühe machen, die Spezifikation der DateKlasse nachzuschlagen und herauszufinden, welche Art von Zeichenfolgen analysiert werden? Ich würde nicht, selbst wenn ich ein Java-Programmierer wäre, würde ich wissen, wo ich suchen muss ;-)

Ich denke, Sie sollten Ihren Benutzern zuerst mitteilen, wie Ihre URIs aussehen werden, z

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

und suchen Sie dann nach einer Möglichkeit, wie Jersey Ihnen beim Parsen des von Ihnen gewählten Datumsformats hilft. Dies kann bedeuten, dass Sie einen DateParametertyp verwenden und möglicherweise einen regulären Ausdruck in Ihrer @PathAnmerkung angeben, z

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

oder verwenden Sie eine andere Klasse, die ein Datum in Ihrem Format analysieren kann. Der Umgang mit URIs, die nicht mit der Spezifikation übereinstimmen, die Sie Ihren Benutzern geben, ist eine weitere Sache, die Sie unabhängig von einem der oben genannten Punkte behandeln sollten (Rückgabe einer Standardressource? Rückgabe eines 404-Fehlers?).

agnul
quelle