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

Hiyerarşik URI'leri 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ızda seri durumundan çıkarma işlemi için kotlinx.serialization kullanılır.

UriDeepLinkMatcher oluşturmak için bir desen DeepLinkUri ve ilgili anahtarın seri hale getiricisini sağlayın:

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

Desteklenen eşleşme kalıpları

UriDeepLinkMatcher, URI'leri beş bileşenine (şema, yetki, yol, sorgu ve parça) göre eşleştirir. 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 şemayla eşleşmek için şemayı kalıba dahil edin. Bir istisna olarak, bir kalıptaki http şeması hem http hem de https istek URI'leriyle eşleşirken bir kalıptaki https yalnızca https istekleriyle eşleşir.

Kalıp 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

Yetkili eşleştirme

UriDeepLinkMatcher, URI yetkilisi (ana makine ve isteğe bağlı bağlantı noktası) üzerinde büyük/küçük harfe duyarsız tam eşleşme gerçekleştirir. Yetkili alanında yer tutucular veya joker karakterler desteklenmez ve herhangi bir bağımsız değişken çıkarılmaz:

Kalıp 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:

Kalıp 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 ekstra bir segment oluşturur) Yok

Sorgu eşleme

İ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 de yoksayılır.

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

Kalıp 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 kalıbı türleri desteklenir:

Kalıp 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, numaralandırmalara, koleksiyonlara ve özel nesnelere seri durumdan çıkarma işlemini destekler. Serileştirme iki kategoriye ayrılır:

  • Standart serileştirme: Aşağıdaki gibi seri durumdan çıkarma için kotlinx.serialization kullanılır:
    • Temel öğeler (Boolean, Int, Long, Float, Double, Char, Byte, Short) ve String
    • Sıralamalar
    • Set, List veya Array ilkel, dize ya da enum
    • İç içe yerleştirilmiş @Serializable sınıflar (özellikleri tek tek URI yer tutucularına düzleştirilmiş)
  • DeepLinkSerializer ile özel serileştirme: Tek bir String ile özel nesneler, harici türler (ör. java.time.LocalDate) veya özel sınırlı koleksiyonlar arasında dönüştürme yapar.

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 türler ve dizeler

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

Sıralamalar

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

Tekrarlanan sorgu koleksiyonları

Tekrarlanan anahtarlara sahip sorgu parametreleri (ör. ?id=10&id=20), List<T>, Set<T> veya Array<T> olarak otomatik olarak seri hale getirilir. Burada T, temel bir 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 mülk 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şlenir:

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

DeepLinkSerializer<T>, String ile T arasında dönüşüm yapan soyut bir KSerializer<T>'dir:

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:

Tek özel nesneler

Tek bir URI parametresi dizesinden (ör. ?filter=brand:google) bir nesnenin kodunu çözmek için özelliği @Serializable(with = ...) ile açıklama ekleyin:

Tekrarlanan sorgu parametrelerindeki özel nesneler

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

Tek parametrelerde sınırlanmış koleksiyonlar

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

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

UriDeepLinkMatcher, eşleşmeme (null döndürür, böylece diğer eşleştiriciler denenebilir) ve desteklenmeyen yapılandırmalar (bir istisna oluşturur) arasında ayrım yapar.

Uyuşmazlıklar

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

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

Uyuşmazlık olduğunda UriDeepLinkMatcher.match döndürülür null. Böylece, sonraki eşleştiricilerin değerlendirilmesine izin verilir.

Varsayılan değerler, iç içe yerleştirilmiş nesneler ve numaralandırmalarla yapılandırılmış bir anahtar sınıfı ve eşleştiriciyi ele alalım:

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

İstek URI'sı Kod Çözme Sonucu 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 olur) UriMatchResult(MapKey("paris", 12, LayerOptions("dark", MapLayer.STANDARD)))
https://www.example.com/map/paris?zoom=&style=dark Başarı (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" numaralandırmada değil) null

Desteklenmeyen yapılandırmalar

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

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

UriMatchResult karşılaştırma

UriMatchResult örnekleri, aşağıdaki ölçütlere göre sıralanır:

  1. MatchResult türü: UriMatchResult, diğer MatchResult türlerinden daha yüksek sıralanır.
  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şken 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, yakalamayanlara göre daha yüksek sıralanır.
  5. Toplam bağımsız değişken sayısı: Toplam bağımsız değişken sayısı (yol, sorgu, parça) son belirleyici faktördür.

UriDeepLinkMatcher eklentisini ö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 DeepLinkRequest için üst düzey eşleşme giriş noktası. İstek ekstralarını incelemek veya URI eşlemesinden önce özel ön koşullar uygulamak için bunu geçersiz kılın.
  • matchUri: DeepLinkUri, yapılandırılmış kalıpla eşleşir. super.matchUri çağrılmadan önce gelen URI'leri yakalamak ve normalleştirmek (örneğin, dinamik alt alan adlarını veya eski yol biçimlerini yeniden yazmak) için bu işlevi geçersiz kılın.
  • matchArguments: Çıkarılan yol, sorgu ve parça bağımsız değişken haritalarını, sağlanan serializer kullanılarak bir gezinme anahtarı örneğine seri durumdan çıkarır. Anahtar örneklendirilmeden önce dinamik değerler yerleştirmek veya bağımsız değişkenleri dönüştürmek için bu işlevi geçersiz kılın.

Aşağıdaki örnekte, eşleştirme işleminden önce eski URL yolu öneklerini normalleştirmek için alt sınıfların nasıl kullanıldığı UriDeepLinkMatcher gösterilmektedir: