JAX-RS @PathParam'da Tarih türünü kullanmalı mıyım?


9

Jersey kullanarak bir JEE Glassfish sunucusunda yapmayı düşünüyorum.

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

Bu RESTful web hizmetini tüketen insanlara "Buradaki tarih, Java'daki Date sınıfıyla çalışan bir şeydir" diyebilme fikrini seviyorum. Bu sadece Date spesifikasyonuna bakabilecekleri açısından oldukça basit ve test edebilecekleri bir çalışma modeline sahip olacaklar.

Endişelendiğim sorun, bunu yaptığımda, Date () yapıcıda aldığını beğenmediğinde JAX-RS'nin çok hoş olmamasıdır. Date (), verilen öğeyi ayrıştıramazsa bir hata atar (gerçek bir tarih yerine "bugün" dizesini geçirir gibi), JEE sunucusu bir 404 hatası döndürür.

Bu iyi bir uygulama mı? Bunu yapmayı düşünmediğim daha iyi bir yol var mı?

Yanıtlar:


8

Kötü bir fikir gibi geliyor. Bir kere, güveneceğiniz Tarih yapıcısı, Java 1.1'den beri DateFormat.parseDate () lehine kullanımdan kaldırılmıştır, çünkü kurallar farklı yerler için farklı olduğu için dizelerin tarihlere nasıl ayrıştırılması gerektiği belirsizdir.

Benim tavsiyem, özellikle uluslararası olarak anlaşılan yyyy-AA-gg ile belirli bir biçime bağlı kalmak ve hizmetinizdeki bir dizeden tarihi ayrıştırmak için bir DateFormat kullanmak ve bu da web hizmetini nasıl tüketeceğinizi netleştirir ve size izin verir. hata iletileri döndürmek için standart kural ne olursa olsun bir şey ters gittiğinde web hizmetleri içindir.


11

Özel bir sınıf kullanıyorum DateParam:

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

Sınıf şu şekilde tanımlanır:

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

Parametre boşsa, boş bir tarih alırsınız. DateParamTanımsız tarih değerleri için herkese açık statik bir son alana kadar genişletebilirsiniz . Bu, tanımlanmamış tarih parametreleri için testi daha net hale getirecektir.

Buradaki bir dezavantaj, her DateParam için yeni bir SimpleDateFormat örneğinin oluşturulmasıdır. Ancak, SimpleDateFormat iş parçacığı için güvenli olmadığından, kolayca yeniden kullanamayız.


3
1+. Java 8 bir iş parçacığı kasası tanıttı DateTimeFormatter. Java <= 7 için, birThreadLocal
Anthony Accioly

3

Hizmetinizi kim kullanacak? DateSınıfın özelliklerini aramaya ve ne tür dizeleri ayrıştıracağını bulmaya zahmet edecekler mi? Java programcısı olsam bile nereye bakmam gerektiğini bilirdim ;-)

Sanırım kullanıcılarınıza önce URI'lerinizin nasıl görüneceğini söylemelisiniz, ör.

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

ve sonra Jersey'nin seçtiğiniz tarih biçimini ayrıştırmada size yardımcı olması için bir yol arayın. Bu, bir Dateparametre türü kullanmak ve @Pathek açıklamalarınızda normal bir ifade belirtmek ( ör.

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

veya biçiminizdeki bir tarihi ayrıştırabilen başka bir sınıf kullanma. Kullanıcılarınıza verdiğiniz spesifikasyona uymayan URI'leri nasıl ele alacağınız, yukarıdakilerden herhangi birini bağımsız olarak nasıl ele alacağınıza karar vermeniz gereken başka bir şeydir (varsayılan bir kaynak döndürün? Bir 404 hatası döndürün?).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.