如何在FilterRegistrationBean中获取@PathVariable?春季启动

时间:2016-04-20 09:41:53

标签: java spring

我要求的路径是:

localhost:8080/companies/12/accounts/35

My 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

是否有任何函数可用于在过滤器内接收此信息?

4 个答案:

答案 0 :(得分:2)

如果您指的是Spring Web过滤器链,则必须手动解析servlet请求中提供的URL。这是因为过滤器在实际控制器获取请求之前执行,然后执行映射。

答案 1 :(得分:1)

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

答案 2 :(得分:0)

在Spring过滤器(拦截器)中执行此操作更合适。要存储检索到的值以便以后在控制器或服务部分中使用它,请考虑将Spring bean与Scope请求一起使用(请求范围创建一个单个HTTP请求的bean实例)。 在拦截器代码示例下面:

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

答案 3 :(得分:0)

通过添加拦截器它会起作用。问题的完整代码:https://stackoverflow.com/a/65503332/2131816