URI derin bağlantılarını eşleştirme

Hiyerarşik URI'ları kalıplarla eşleştirmek ve bağımsız değişkenleri ayıklamak için UriDeepLinkMatcher kullanın. Eşleşen bağımsız değişkenleri anahtar sınıflarınıza seri durumdan çıkarmak için kotlinx.serialization kullanılır.

UriDeepLinkMatcher oluşturmak için bir kalıp DeepLinkUri ve ilgili anahtar için serileştirici sağlayın:

Hiyerarşik olmayan URI'ler veya özel şemalar (ör. tel:) için Özel derin bağlantı eşleştiriciler oluşturma başlıklı makaleyi inceleyin.

Desteklenen eşleşme kalıpları

UriDeepLinkMatcher, URI'ları beş bileşenine göre eşleştirir: şema, yetki, yol, sorgu ve parça. Aşağıdaki bölümlerde, her bileşen için desteklenen kalıp söz dizimi, bağımsız değişken yer tutucuları ve eşleşme kuralları açıklanmaktadır.

Şema eşleştirme

URI kalıbında şema yoksa hem http hem de https eşleştirilir. Belirli bir şemayı eşleştirmek için şemayı kalıba dahil edin. İstisna olarak, bir kalıptaki http şeması hem http hem de https istek URI'leriyle eşleşirken kalıptaki https yalnızca https istekleriyle eşleşir.

Desen URI'si İstek URI'sı Eşleşme
www.example.com https://www.example.com ✅
www.example.com http://www.example.com ✅
http://www.example.com http://www.example.com ✅
http://www.example.com https://www.example.com ✅
https://www.example.com http://www.example.com ❌
myapp://www.example.com myapp://www.example.com ✅

Yetki eşleştirme

UriDeepLinkMatcher, URI yetkilisi (ana makine ve isteğe bağlı bağlantı noktası) üzerinde büyük/küçük harfe duyarlı olmayan tam eşleme gerçekleştirir. Yetki bölümünde yer tutucular veya joker karakterler desteklenmez ve bağımsız değişkenler ayıklanmaz:

Desen URI'si İstek URI'sı Eşleşme
example.com https://example.com ✅
example.com https://EXAMPLE.COM ✅
example.com https://sub.example.com ❌
example.com https://www.example.com ❌
example.com https://example.com:8080 ❌
example.com:8080 https://example.com:8080 ✅
example.com:8080 https://example.com ❌

Yol eşleştirme

Aşağıdaki yol kalıpları desteklenir:

Desen URI'si İstek URI'sı Eşleşme Ayıklanan Bağımsız Değişkenler
www.example.com/users https://www.example.com/users ✅ Yok
www.example.com/users/{id} https://www.example.com/users/123 ✅ id: "123"
www.example.com/users/{first}-{last} https://www.example.com/users/john-doe ✅ first: "john", last: "doe"
www.example.com/users/{id}/profile https://www.example.com/users//profile ✅ id: "" (Boş dize)
www.example.com/users/user_{id} https://www.example.com/users/user_123 ✅ id: "123"
www.example.com/users/{userId}/posts/{postId} https://www.example.com/users/123/posts/456 ✅ userId: "123", postId: "456"
www.example.com/users/.* https://www.example.com/users/john-doe ✅ Yok
www.example.com/users https://www.example.com/users/ ❌ (Sondaki eğik çizgi fazladan bir segment oluşturur) Yok

Sorgu eşleştirme

İstek URI'sindeki sorgu parametresi sırasının, kalıp URI'sindeki sırayla eşleşmesi gerekmez. Ayrıca, istek URI'sinde bulunan ancak kalıp URI'sinde bulunmayan parametreler yoksayılır.

Aşağıdaki sorgu parametresi kalıpları desteklenir:

Desen URI'si İstek URI'sı Ayıklanan Bağımsız Değişkenler
www.example.com/users?name={name} https://www.example.com/users?name=john name: "john"
www.example.com/users?name={name} https://www.example.com/users?name= name: "" (Boş dize)
www.example.com/users?{rawQuery} https://www.example.com/users?anything&else rawQuery: ["anything", "else"]
www.example.com/users?type=user_{id} https://www.example.com/users?type=user_123 id: "123"
www.example.com/users?name={first}_{last} https://www.example.com/users?name=john_doe first: "john", last: "doe"
www.example.com/users?list={list} https://www.example.com/users?list=10&list=20 list: ["10", "20"]
www.example.com/users?name={name}&{other} https://www.example.com/users?name=john&tab=info name: "john", other: ["tab=info"]
www.example.com/users?type=user_.* https://www.example.com/users?type=user_admin type: "admin"

Parça eşleştirme

Aşağıdaki parça deseni türleri desteklenir:

Desen URI'si İstek URI'sı Ayıklanan Bağımsız Değişkenler
www.example.com/#section1 https://www.example.com/#section1 Yok
www.example.com/#section_{id} https://www.example.com/#section_123 id: "123"
www.example.com/#section_.* https://www.example.com/#section_123 Yok

Desteklenen veri türleri

UriDeepLinkMatcher, URI bağımsız değişkenlerinin temel türlere, enum'lara, koleksiyonlara ve özel nesnelere dönüştürülmesini destekler. Serileştirme iki kategoriye ayrılır:

  • Standart serileştirme: Şuna seri hale getirmek için kotlinx.serialization kullanır:
    • Temel öğeler (Boolean, Int, Long, Float, Double, Char, Byte, Short) ve String
    • Sıralamalar
    • Temel öğeler, dizeler veya enum'lardan oluşan Set, List veya Array
    • İç içe yerleştirilmiş @Serializable sınıfları (özellikleri ayrı URI yer tutucularına düzleştirilir)
  • DeepLinkSerializer ile özel serileştirme: Tek bir String ile özel nesneler, harici türler (ör. java.time.LocalDate) veya özel olarak sınırlandırılmış koleksiyonlar arasında dönüşüm gerçekleştirir.

Standart serileştirme

UriDeepLinkMatcher, özel serileştirici uygulamaları gerektirmeden standart türler ve düzleştirilmiş yapılar için kullanıma hazırdır.

Temel öğeler ve dizeler

UriDeepLinkMatcher, temel türlerin (Boolean, Int, Long, Float, Double, Char, Byte, Short) ve String kodunu otomatik olarak çözer:

Sıralamalar

Enum değerleri, enum öğesi adlarıyla büyük/küçük harfe duyarlı olarak eşleştirilir:

Tekrarlanan sorgu koleksiyonları

Yinelenen anahtarlar (ör. ?id=10&id=20) içeren sorgu parametreleri otomatik olarak List<T>, Set<T> veya Array<T> şeklinde seri durumdan çıkarılır. Burada T, temel tür, String veya enum'dur:

İç içe yerleştirilmiş @Serializable sınıfları

Bir NavKey, türü başka bir @Serializable sınıfı olan bir özellik içerdiğinde UriDeepLinkMatcher, özelliklerini düzleştirir. Böylece iç içe yerleştirilmiş sınıfın her özelliği, aynı ada sahip ayrı bir URI parametresiyle doğrudan eşleşir:

Özel nesneleri (ör. Filter(key = "brand", value = "pixel")), harici türleri (ör. java.time.LocalDate) veya özel sınırlanmış dizeleri (ör. virgülle ayrılmış değerler) seri durumdan çıkarmak için DeepLinkSerializer<T> sınıfını genişletin.

DeepLinkSerializer<T>, String ve T arasında dönüşüm yapan soyut bir KSerializer<T> sınıfıdır:

abstract class DeepLinkSerializer<T : Any> : KSerializer<T> {
    abstract val serialName: String
    abstract fun deserialize(value: String): T
    abstract fun serialize(value: T): String
}

Örneğin, aşağıdaki snippet'lerde kullanılan Filter ve FilterSerializer tanımlarını ele alalım:

Tekli özel nesneler

Bir nesnenin kodunu tek bir URI parametre dizesinden (ör. ?filter=brand:google) çözmek için mülke @Serializable(with = ...) ile ek açıklama ekleyin:

Yinelenen sorgu parametrelerindeki özel nesneler

Yinelenen sorgu parametrelerini özel nesne koleksiyonu (List<T>, Set<T> veya Array<T>) olarak seri durumdan çıkarmak için öğe türü T için DeepLinkSerializer<T> uygulayın ve özelliğin tür bağımsız değişkenine @Serializable(with = ...) ile ek açıklama ekleyin:

Tek parametrelerde sınırlanmış koleksiyonlar

Virgülle ayrılmış veya özel sınırlayıcılarla ayrılmış değerleri (ör. ?ids=1,2,3) bir koleksiyona ayrıştırmak için tüm koleksiyon türü için DeepLinkSerializer uygulayın ve özelliği @Serializable(with = ...) ile ek açıklama ekleyin:

Bağımsız değişken doğrulama ve eşleşen sonuçlar

UriDeepLinkMatcher, uyumsuzluklar (diğer eşleştiricilerin denenebilmesi için null döndürür) ve desteklenmeyen yapılandırmalar (istisna oluşturur) arasında ayrım yapar.

Uyuşmazlıklar

Gelen bir istek URI'si, kalıp veya tür şartlarını karşılamadığında uyuşmazlık oluşur:

  • Gerekli parametreler eksik: Varsayılan değerleri olmayan ve karşılık gelen URI parametreleri istek URI'sinde bulunmayan, null değer alabilen anahtar özellikler.
  • Tür ayrıştırma hataları: Beklenen özellik türüne (ör. Int özelliği için "abc") ayrıştırılamayan, ayıklanmış bağımsız değişken değerleri.

Uyuşmazlık olduğunda UriDeepLinkMatcher.match, null değerini döndürür ve sonraki eşleştiricilerin değerlendirilmesine olanak tanır.

Varsayılan değerler, iç içe yerleştirilmiş nesneler ve enum'larla yapılandırılmış bir anahtar sınıfı ve eşleştirici düşünün:

Aşağıdaki tabloda, çeşitli istek URI'leri için eşleşen sonuçlar gösterilmektedir:

İstek URI'sı Sonuçları Yorumlama Maç Sonucu
https://www.example.com/map/paris?zoom=15&style=dark&layer=SATELLITE Başarılı (Tüm parametreler sağlandı) UriMatchResult(MapKey("paris", 15, LayerOptions("dark", MapLayer.SATELLITE)))
https://www.example.com/map/paris?style=dark Başarılı (zoom varsayılan olarak 12, layer ise STANDARD değerine ayarlanır) UriMatchResult(MapKey("paris", 12, LayerOptions("dark", MapLayer.STANDARD)))
https://www.example.com/map/paris?zoom=&style=dark Başarılı (Boş isteğe bağlı sorgu parametresi varsayılan 12 değerini kullanır) UriMatchResult(MapKey("paris", 12, LayerOptions("dark", MapLayer.STANDARD)))
https://www.example.com/map?style=dark Uyuşmazlık (Gerekli location parametresi eksik) null
https://www.example.com/map/paris?zoom=close&style=dark Uyuşmazlık ("close", Int değil) null
https://www.example.com/map/paris?style=dark&layer=HYBRID Uyuşmazlık ("HYBRID", enum'da yok) null

Desteklenmeyen yapılandırmalar

Anahtar sınıfınız desteklenmeyen veri türleri içeriyorsa UriDeepLinkMatcher, eşleştirme sırasında null döndürmek yerine bir istisna oluşturur.

  • Haritalar ve çok boyutlu koleksiyonlar: UriDeepLinkMatcher yalnızca temel öğeler, dizeler, enum'lar veya DeepLinkSerializer ile ek açıklama eklenmiş özel türlerin tek boyutlu koleksiyonlarını destekler. Map türleri IllegalArgumentException hatası verirken iç içe yerleştirilmiş koleksiyonlar (ör. List<List<String>>) SerializationException hatası verir.
  • Ek açıklama eklenmemiş özel nesne koleksiyonları: Özel türlerin koleksiyonları (ör. List<Filter>), öğe türüne DeepLinkSerializer ile ek açıklama eklenmediği sürece SerializationException hatası verir.
  • Düzleştirilmemiş iç içe yerleştirilmiş sınıflar: İç içe yerleştirilmiş @Serializable sınıflar, DeepLinkSerializer olmadan tek bir yer tutucuyla (ör. ?user={user}) eşlenemez.

UriMatchResult karşılaştırma

UriMatchResult örnekleri, aşağıdaki ölçütler kullanılarak sıralanır:

  1. MatchResult türü: UriMatchResult, diğer MatchResult türlerinden daha yüksek sıralamaya sahiptir.
  2. Tam yol: Tam yol eşleşmeleri, yer tutucu veya joker karakter eşleşmelerinden daha üst sıralarda yer alır.
  3. Yol bağımsız değişkeni sayısı: Daha fazla yol bağımsız değişkeni içeren eşleşmeler daha üst sıralarda yer alır.
  4. Bağımsız değişkenlerin varlığı: Bağımsız değişkenleri yakalayan eşleşmeler, yakalamayanlardan daha yüksek sıralamaya sahiptir.
  5. Toplam bağımsız değişken sayısı: Toplam bağımsız değişken sayısı (yol, sorgu, parça) son eşitlik bozucudur.

UriDeepLinkMatcher kadranını özelleştir

UriDeepLinkMatcher, URI eşleştirme ve bağımsız değişken çıkarma davranışını özelleştirmek için alt sınıf oluşturabileceğiniz bir open sınıfıdır:

  • matchRequest: Gelen bir DeepLinkRequest için üst düzey eşleşen giriş noktası. İstek eklerini incelemek veya URI eşleşmesinden önce özel ön koşullar uygulamak için bunu geçersiz kılın.
  • matchUri: DeepLinkUri değerini yapılandırılmış kalıpla eşleştirir. super.matchUri çağrılmadan önce gelen URI'ları yakalamak ve normalleştirmek (ör. dinamik alt alan adlarını veya eski yol biçimlerini yeniden yazmak) için bu yöntemi geçersiz kılın.
  • matchArguments: Sağlanan serializer değerini kullanarak ayıklanan yol, sorgu ve parça bağımsız değişken eşlemelerini bir gezinme anahtarı örneğine dönüştürür. Anahtar örneklendirmeden önce dinamik değerler eklemek veya bağımsız değişkenleri dönüştürmek için bu ayarı geçersiz kılın.

Aşağıdaki örnekte, eşleştirmeden önce eski URL yolu ön eklerini normalleştirmek için UriDeepLinkMatcher alt sınıfının nasıl oluşturulacağı gösterilmektedir: