我正在開發一個 Spring Boot 應用程式,我想在一些特定的 URL 中應用一些過濾器,為此我正在實作Filter介面(下面的代碼)并使用FilterRegistrationBean我有方法setUrlPatterns來定義使用過濾器的端點。我從頭開始創建了一個示例應用程式,并為 設定了過濾器/hello,但過濾器并未應用于/hello/.
這使得有必要將行從 更改
filterRegistrationBean.setUrlPatterns(List.of("/hello"));
為
filterRegistrationBean.setUrlPatterns(List.of("/hello", "/hello/"));。它解決了我的問題,但我不想復制路徑只包含尾部斜杠。
有沒有更好的方法來做到這一點而不是寫List.of("/hello", "/hello/")?
代碼:
import javax.servlet.*;
import java.io.IOException;
public class LogFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("-----------------FILTER-----------------");
chain.doFilter(request, response);
}
// ... other methods
}
import com.example.demo.config.filters.LogFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
@Configuration
public class WebConfig {
@Bean
public FilterRegistrationBean<LogFilter> logFilter() {
var filterRegistrationBean = new FilterRegistrationBean<>(new LogFilter());
filterRegistrationBean.setUrlPatterns(List.of("/hello"));
return filterRegistrationBean;
}
}
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController()
@RequestMapping("/hello")
public class HelloController {
@GetMapping
public String hello() {
return "Hello";
}
}
研究:
- 還有另一種定義過濾器的方法,啟用
@ServletComponentScan,創建一個實作Filter并用 注釋的類@WebFilter(urlPatterns = {"/hello"}),但結果是一樣的。 - 我可以使用
/hello/*,它會考慮帶和不帶斜杠的路徑,但我不想將過濾器應用于其他所有內容,例如/hello/abc/,我只想完全為/hello(和/hello/)應用過濾器。
我在嵌入式 Tomcat 上進行了除錯,我發現ApplicationFilterFactory使用一些邏輯來決定何時在路徑中應用過濾器,它看起來重復,路徑是唯一的解決方案,但在這個例子中我只使用一個路徑,假設您有 20..30 條路徑用于此過濾器,一旦復制以包含尾部斜杠,它就會變為 40..60,所以我正在嘗試為此找到另一個解決方案(我不確定是否有其他解決方案因此ApplicationFilterFactory在嵌入式 tomcat 上實作)。
uj5u.com熱心網友回復:
見這里 :
setUrlPatterns
public void setUrlPatterns(Collection<String> urlPatterns)設定過濾器將注冊的 URL 模式。這將替換任何先前指定的 URL 模式。...
此方法的變體(具有更精確的檔案):
addUrlPatterns
public void addUrlPatterns(String... urlPatterns)添加Servlet 規范中定義的URL 模式,過濾器將針對該模式注冊。
...(搜索;):
- => Servlet 規范
- =>(最新)3.1.final:
12.2 映射規范
在 Web 應用程式部署描述符中,以下語法用于定義映射:
- 以字符開頭
/并以/*后綴結尾的字串用于路徑映射。- 以
*.前綴開頭的字串用作擴展映射。- 該空字串(
"")是恰好映射到一個特殊的URL模式 應用程式背景關系,即形式的請求http://host:port/<contextroot>/。在這種情況下,路徑資訊是/,servlet 路徑和背景關系路徑是空字串 ("")。- 僅
/包含字符的字串表示應用程式的“默認”servlet。在這種情況下,servlet 路徑是請求 URI 減去背景關系路徑,路徑資訊為空。- 所有其他字串僅用于精確匹配。
如果有效的 web.xml(在合并來自片段和注釋的資訊之后)包含任何映射到多個 servlet 的 url-patterns,那么部署必須失敗。
所以對于你的核心問題:
有沒有更好的方法來代替撰寫 List.of("/hello", "/hello/") ?
不(,抱歉),不適用于 Servlet <=3.1。根據此規范"hello", "hello/"將是兩個完全匹配。(而且List.of(few, ..., items)“非常酷”/最新/不可變!;))
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/362783.html
上一篇:單擊時切換元素
