简体   繁体   中英

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.

@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. 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). 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:

@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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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