简体   繁体   English

如何在 FilterRegistrationBean 中获取 @PathVariable? 弹簧靴

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

My requested path is:我请求的路径是:

localhost:8080/companies/12/accounts/35

My Rest Controller contains this function and I want to get companyId and accountId inside Filter.我的 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

Is there any function that can be used in order to receive this information inside filter?是否有任何功能可用于在过滤器内接收此信息?

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

If you are referring to the Spring web filter chain, you will have to manually parse the URL provided in the servlet request.如果您指的是 Spring Web 过滤器链,则必须手动解析 servlet 请求中提供的 URL。 This is due to the fact that filters are executed before the actual controller gets hold of the request, which then performs the mapping.这是因为过滤器在实际控制器获取请求之前执行,然后执行映射。

It's more suitable to do that inside a Spring Filter(an interceptor).To store the retrieved value in order to use it later in the controller or service part, consider using a Spring bean with the Scope request(request scope creates a bean instance for a single HTTP request).更适合在 Spring 过滤器(拦截器)中执行此操作。要存储检索到的值以便稍后在控制器或服务部分中使用它,请考虑使用具有 Scope 请求的 Spring bean(请求范围为单个 HTTP 请求)。 Below the interceptor code example:下面是拦截器代码示例:

@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);
    }
}

For safe access of the storing value in the RequestData bean, I advise to always use a ThreadLocal construct to hold the managed value:为了安全访问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);
    }
}

by adding Interceptor it would work.通过添加拦截器它会起作用。 complete code to the problem : https://stackoverflow.com/a/65503332/2131816问题的完整代码: https : //stackoverflow.com/a/65503332/2131816

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM