Bağlam yolu olmadan istek URI'si nasıl alınır?


127

Yöntem request.getRequestURI () bağlam yolu ile URI döndürür.

Bir uygulamanın temel URL'si ise Örneğin, http://localhost:8080/myapp/(yani bağlam yolu myapp ) ve dediğim request.getRequestURI()için http://localhost:8080/myapp/secure/users, bu dönecektir /myapp/secure/users.

Yalnızca bu kısmı /secure/users, yani bağlam yolu olmayan URI'yi almanın bir yolu var mı?


Yanıtlar:


158

Bir önek deseninde eşlenen bir ön denetleyici sunucu uygulamasının içindeyseniz, yalnızca kullanabilirsiniz HttpServletRequest#getPathInfo().

String pathInfo = request.getPathInfo();
// ...

Örneğinizdeki sunucu uygulamasının eşlendiğini varsayarsak, /securebu, /userstipik bir ön denetleyici sunucu uygulamasında yalnızca ilgili bilgi olacak olan geri dönecektir .

Ancak sunucu uygulaması bir son ek modelinde eşlenmişse (ancak URL örnekleriniz bunun böyle olduğunu göstermez) veya gerçekten bir filtrenin içindeyseniz (çağrılacak sunucu uygulaması henüz belirlenmediğinde, bu nedenle getPathInfo()dönebilir null), o zaman en iyi bahsiniz, istek URI'sini normal Stringyöntemi kullanarak bağlam yolunun uzunluğuna göre kendiniz alt dizelerdir :

HttpServletRequest request = (HttpServletRequest) req;
String path = request.getRequestURI().substring(request.getContextPath().length());
// ...

Bunun yerine kullanmanın bir nedeni var mı getServletPath()? Bir filtre yazıyorum ve bunun getPathInfo()döndüğünü fark ettim null, ancak getServletPath()bağlam eksi yolu döndürüyor (istek dağıtıcısına iletmek için uygun).
Jason C

@JasonC: Yanıtlandığı gibi, getPathInfo()ön denetleyici sunucu uygulaması bir önek modelinde eşlenmezse null döndürür.
BalusC

Evet. Demek istediğim: getServletPath yerine getPathInfo'yu tercih etmenizin bir nedeni var mı? Buradaki diğer yüksek puanlı cevapların birçoğu getServletPath'i de kullanmıyor, bu da beni bundan şüphelendiriyor ve bu yüzden merak ediyorum. Üzerinde çalıştığım bir servlet projem var ve becerilerimi biraz değiştirmeye çalışıyorum.
Jason C

1
@JasonC: JSF veya Spring MVC gibi sunucu uygulaması tabanlı bir MVC çerçevesine sahip olduğunuzda sunucu uygulaması yolu değişebilir. Daha sonra, MVC çerçevesinin dahili yolunu (örneğin /foo.xhtmlyerine /foo.jsf) temsil edecek ve gerçek istek URI'sini (son kullanıcının tarayıcının adres çubuğunda göreceği gibi) göstermeyecektir. Orijinal sunucu uygulaması yolu böyle bir durumda anahtarla istek özniteliği olarak çözülebilir RequestDispatcher.FORWARD_SERVLET_PATH. Herhangi bir şekilde, soru açıkça istek URI'sini sorar (tarayıcının adres çubuğunda olduğu gibi), bu nedenle yanıt buna dayanır.
BalusC

74
request.getRequestURI().substring(request.getContextPath().length())

Müthiş! Bu tam olarak aradığım şey.
usta

4
+1 Bence bu, getPathInfo'nun boş ve diğer gariplikler olabileceği gerçeğinden dolayı getPathInfo'dan daha iyi bir cevap. Çeşitli Spring kodu getContextPath yapar ve getPathInfo yerine yaptığınız gibi URI'den kaldırır.
Adam Gent

32

Bahar ile şunları yapabilirsiniz:

String path = new UrlPathHelper().getPathWithinApplication(request);

1
Elbette, örneğin bir sınıf üyesi değişkeni olarak UrlPathHelper örneğini tutmak mantıklı olacaktır ...
James

Gerçek istek eşleme url'sini nasıl alabiliriz? Lütfen buradan rehberlik edin: stackoverflow.com/questions/60446807/…
Pra_A

14

getPathInfo () bazen boş döndürür. Belgelerde HttpServletRequest

Fazladan yol bilgisi yoksa bu yöntem null döndürür.

Filtrede bağlam yolu olmadan dosyaya giden yolu almalıyım ve getPathInfo () beni boş döndürüyor. Bu yüzden başka bir yöntem kullanıyorum: httpRequest.getServletPath ()

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    HttpServletResponse httpResponse = (HttpServletResponse) response;

    String newPath = parsePathToFile(httpRequest.getServletPath());
    ...

}

8

Bir Filter içinde request.getPathInfo () kullanırsanız, her zaman boş görünüyorsunuz (en azından jetty ile).

Bu kısa, geçersiz hata + yanıtı, düşündüğüm soruna işaret ediyor:

https://issues.apache.org/bugzilla/show_bug.cgi?id=28323

Sunucu uygulaması isteği almadan önce filtrelerin çalıştığından şüpheleniyorum. Bir kapsayıcı hatası veya tanımlayamadığım beklenen davranış olabilir.

ContextPath yine de mevcuttur, bu nedenle fforws çözümü filtrelerde bile çalışır. Elle yapmak zorunda kalmaktan hoşlanmıyorum ama uygulama bozuk veya


5

Bunu yapmanın bir yolu, servelet bağlam yolunu istek URI'sinden dinlendirmektir.

String p = request.getRequestURI();
String cp = getServletContext().getContextPath();

if (p.startsWith(cp)) {
  String.err.println(p.substring(cp.length());
}

Burada okuyun .


-1

Belki de '/ uygulamam'ı kaldırmak için bölme yöntemini kullanabilirsiniz, örneğin:

string[] uris=request.getRequestURI().split("/");
string uri="/"+uri[1]+"/"+uris[2];

3
Uygulamamı kök olarak dağıtırsam ve temel URL'si localhost: 8080 olursa bu sorun yaratacaktır . Bu durumda request.getRequestURI () "/ secure / user" döndürür ve bölme yönteminiz burada soruna neden olur. Kod, konuşlandırmaya bağlı olmamalıdır.
usta
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.