Kalan JAX-RS ile KURU
Aynı yol ve sorgu parametreleri bir kaç gerektiren tüm JAX-RS kaynak işleyicileri, tekrarlanan kod en aza indirmek için çalışıyorum. Temel url her kaynak için şablonu bu gibi görünüyor:
/{id}/resourceName
ve her bir kaynak birden çok subresources vardır:
/{id}/resourceName/subresourceName
Bu yüzden, kaynak/subresource yolları (dahil. sorgu parametreleri) gibi görünebilir
/12345/foo/bar?xyz=0
/12345/foo/baz?xyz=0
/12345/quux/abc?xyz=0
/12345/quux/def?xyz=0
Kaynaklar foo
quux
arasında ortak parçaları @PathParam("id")
@QueryParam("xyz")
. Benolabilirbu gibi sınıflar: kaynak uygulamak
// FooService.java
@Path("/{id}/foo")
public class FooService
{
@PathParam("id") String id;
@QueryParam("xyz") String xyz;
@GET @Path("bar")
public Response getBar() { /* snip */ }
@GET @Path("baz")
public Response getBaz() { /* snip */ }
}
// QuuxService.java
@Path("/{id}/quux")
public class QuxxService
{
@PathParam("id") String id;
@QueryParam("xyz") String xyz;
@GET @Path("abc")
public Response getAbc() { /* snip */ }
@GET @Path("def")
public Response getDef() { /* snip */ }
}
get*
Her bir yönteme parametre enjeksiyon tekrar etmekten hep kaçındım.1Bu iyi bir başlangıç, ama kaynak sınıflar arasında tekrarlanmasını önlemek için mümkün olmak istiyorum. CDI ben de ihtiyacı olan) ile çalışan bir yaklaşım FooService
QuuxService
26 ** olabilir abstract
temel sınıf kullanmak için:
// BaseService.java
public abstract class BaseService
{
// JAX-RS injected fields
@PathParam("id") protected String id;
@QueryParam("xyz") protected String xyz;
// CDI injected fields
@Inject protected SomeUtility util;
}
// FooService.java
@Path("/{id}/foo")
public class FooService extends BaseService
{
@GET @Path("bar")
public Response getBar() { /* snip */ }
@GET @Path("baz")
public Response getBaz() { /* snip */ }
}
// QuuxService.java
@Path("/{id}/quux")
public class QuxxService extends BaseService
{
@GET @Path("abc")
public Response getAbc() { /* snip */ }
@GET @Path("def")
public Response getDef() { /* snip */ }
}
Düzgün çalışır get*
yöntemleri, içinde: util
Bu alan boş değil. Ne yazık ki, JAX-RS enjeksiyon yapardeğil; id
xyz
FooService
get*
yöntemleri null
QuuxService
.
Bu sorun için düzeltme veya geçici çözüm var mı?
Bunu yapmak istediğiniz gibi CDI çalıştığı göz önüne alındığında, @PathParam
s (vb.) enjekte etmek için başarısızlık diye merak ediyorum alt sınıfların içine bir böcek veya JAX-RS spec sadece bir parçası.
Zaten denedim başka bir yaklaşım gerektiği gibi FooService
QuuxService
delegeler için tek bir giriş noktası olarak BaseService
kullanıyor. Bu RESTful Java with JAX-RS subresource belirleyicileri kullanarak açıklandığı gibi temelde.
// BaseService.java
@Path("{id}")
public class BaseService
{
@PathParam("id") protected String id;
@QueryParam("xyz") protected String xyz;
@Inject protected SomeUtility util;
public BaseService () {} // default ctor for JAX-RS
// ctor for manual "injection"
public BaseService(String id, String xyz, SomeUtility util)
{
this.id = id;
this.xyz = xyz;
this.util = util;
}
@Path("foo")
public FooService foo()
{
return new FooService(id, xyz, util); // manual DI is ugly
}
@Path("quux")
public QuuxService quux()
{
return new QuuxService(id, xyz, util); // yep, still ugly
}
}
// FooService.java
public class FooService extends BaseService
{
public FooService(String id, String xyz, SomeUtility util)
{
super(id, xyz, util); // the manual DI ugliness continues
}
@GET @Path("bar")
public Response getBar() { /* snip */ }
@GET @Path("baz")
public Response getBaz() { /* snip */ }
}
// QuuxService.java
public class QuuzService extends BaseService
{
public FooService(String id, String xyz, SomeUtility util)
{
super(id, xyz, util); // the manual DI ugliness continues
}
@GET @Path("abc")
public Response getAbc() { /* snip */ }
@GET @Path("def")
public Response getDef() { /* snip */ }
}
Bu yaklaşımın dezavantajı CDI enjeksiyon ne de JAX-RS enjeksiyon ne subresource sınıfları çalışır. Bunun nedeni oldukça açık2bu ne amademektirel ile alt sınıflar' dağınık ve yapıcı, çirkin ve kolayca beni daha fazla enjeksiyon özelleştirmek izin vermez. içine yeniden enjekte alanlar değil." Örnek: 45 ** bir örnek FooService
ama QuuxService
. içine istediğimi söyle Açıkça BaseService
, CDI enjeksiyon sınıfları başlatmasını olduğum için işe yaramaz, çirkinlik devam etti.
tl;dr sürekli JAX-RS işleyici sınıfları kaynak alanları arasında enjekte önlemek için doğru yolu Nedir?
Ve neden CDI bu ile hiçbir sorunları varken alanları JAX-RS ile enjekte miras, değil mi?
1 düzenleyin
@Tarlog, yönü biraz sorularımın cevabını buldum sanırım
Neden miras alanları JAX-RS ile enjekte değil mi?
Eğer alt veya uygulama yöntemi olan, herhangi bir JAX-RS ek açıklamalar o zamantümsüper sınıfın metodu açıklama yok sayılır.
Bu karar için gerçek bir sebebi var eminim, ama ne yazık ki bu gerçeği, bu özel kullanım durumda bana karşı çalışıyor. Hala herhangi bir olası geçici çözümler ilgileniyorum.
new FooService()
çok kapsayıcı/JAX-RS uygulaması arıyorum çünkü.
CEVAP
İşte kullandığım bir çözüm
İle BaseService için bir kurucu tanımlamak 've' xyz kullanımı'. ıd
// BaseService.java
public abstract class BaseService
{
// JAX-RS injected fields
protected String id;
protected String xyz;
public BaseService (String id, String xyz) {
this.id = id;
this.xyz = zyx;
}
}
Enjekte ile: tüm alt sınıflar üzerinde yapıcı tekrarlayın
// FooService.java
@Path("/{id}/foo")
public class FooService extends BaseService
{
public FooService (@PathParam("id") String id, @QueryParam("xyz") String xyz) {
super(id, xyz);
}
@GET @Path("bar")
public Response getBar() { /* snip */ }
@GET @Path("baz")
public Response getBaz() { /* snip */ }
}
Nasıl Görünümü ile düzene kalan boşluğ...
KURU Ruby Hash Değişken ile Başlatma...
Genişletmek kalan genişliği almak div...
Geri KALAN güvenlik kimlik doğrulama d...
Kullanım SİLMEK POST KOYMAK neden API ...