簡體   English   中英

如何在 FilterRegistrationBean 中獲取 @PathVariable? 彈簧靴

[英]How can I get @PathVariable inside FilterRegistrationBean? Spring Boot

我請求的路徑是:

localhost:8080/companies/12/accounts/35

我的 Rest Controller 包含此功能,我想在 Filter 中獲取 companyId 和 accountId。

@RequestMapping(value = "/companies/{companyId}/accounts/{accountId}", method = RequestMethod.PUT)
public Response editCompanyAccount(@PathVariable("companyId") long companyId, @PathVariable("accountId") long accountId,
@RequestBody @Validated CompanyAccountDto companyAccountDto,
                                       HttpServletRequest req) throws ErrorException, InvalidKeySpecException, NoSuchAlgorithmException

是否有任何功能可用於在過濾器內接收此信息?

Map pathVariables = (Map) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);  
String companyId = (String)pathVariables.get("companyId"); 
String accountId= (String)pathVariables.get("accountId");

如果您指的是 Spring Web 過濾器鏈,則必須手動解析 servlet 請求中提供的 URL。 這是因為過濾器在實際控制器獲取請求之前執行,然后執行映射。

更適合在 Spring 過濾器(攔截器)中執行此操作。要存儲檢索到的值以便稍后在控制器或服務部分中使用它,請考慮使用具有 Scope 請求的 Spring bean(請求范圍為單個 HTTP 請求)。 下面是攔截器代碼示例:

@Component
public class RequestInterceptor implements Filter {

    private final RequestData requestData;

    public RequestInterceptor(RequestInfo requestInfo) {

        this.requestInfo = requestInfo;
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
            FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        //Get authorization
        var authorization = request.getHeader(HttpHeaders.AUTHORIZATION);

        //Get some path variables
        var pathVariables = request.getHttpServletMapping().getMatchValue();
        var partyId = pathVariables.substring(0, pathVariables.indexOf('/'));

        //Store in the scoped bean
        requestInfo.setPartyId(partyId);

        filterChain.doFilter(servletRequest, servletResponse);
    }
}

為了安全訪問RequestData bean 中的存儲值,我建議始終使用 ThreadLocal 構造來保存托管值:

@Component
@Scope(value = "request", proxyMode =  ScopedProxyMode.TARGET_CLASS)
public class RequestData {

    private final ThreadLocal<String> partyId = new ThreadLocal<>();

    public String getPartyId() {

        return partyId.get();
    }

    public void setPartyId(String partyId) {

        this.partyId.set(partyId);
    }
}

通過添加攔截器它會起作用。 問題的完整代碼: https : //stackoverflow.com/a/65503332/2131816

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM