如何获取资源方法中带qs质量因子的匹配@Produces内容类型?
获取匹配的内容类型(带源端质量因子)
当你的资源方法通过@Produces指定了带源端质量因子(qs)的媒体类型时,要正确获取实际匹配的类型,需要在构建Variant时手动设置对应质量因子,再调用request.selectVariant(),这样就能和JAX-RS的内容协商逻辑保持一致。
方法一:带质量因子的Variant匹配
@Context private Request request; public String getMatchedContentType() { // 为每个媒体类型创建带对应qs的Variant Variant jsonLdVariant = new Variant( MediaType.valueOf(MEDIA_TYPE_JSON_LD), null, null, 1.0f // 对应@Produces里的qs=1 ); Variant jsonVariant = new Variant( MediaType.APPLICATION_JSON_TYPE, null, null, 0.5f // 对应@Produces里的qs=0.5 ); List<Variant> variants = Arrays.asList(jsonLdVariant, jsonVariant); Variant selectedVariant = request.selectVariant(variants); if (selectedVariant != null) { return selectedVariant.getMediaType().toString(); } // 处理无匹配的情况 return null; }
方法二:基于HttpHeaders的协商结果筛选
如果资源方法已被JAX-RS选中处理请求,也可以通过HttpHeaders结合源端qs规则,筛选出最终匹配的媒体类型:
@Context private HttpHeaders headers; public String getMatchedContentType() { MediaType matchedType = headers.getAcceptableMediaTypes().stream() // 筛选出与Produces声明兼容的类型 .filter(acceptType -> { return acceptType.isCompatible(MediaType.valueOf(MEDIA_TYPE_JSON_LD)) || acceptType.isCompatible(MediaType.APPLICATION_JSON_TYPE); }) // 按JAX-RS协商规则排序:客户端qs × 源端qs,得分高的优先 .sorted((t1, t2) -> { float score1 = t1.getQualityFactor() * getSourceQs(t1); float score2 = t2.getQualityFactor() * getSourceQs(t2); return Float.compare(score2, score1); }) .findFirst() .orElse(null); return matchedType != null ? matchedType.toString() : null; } // 根据媒体类型获取源端设置的qs值 private float getSourceQs(MediaType type) { if (type.isCompatible(MediaType.valueOf(MEDIA_TYPE_JSON_LD))) { return 1.0f; } else if (type.isCompatible(MediaType.APPLICATION_JSON_TYPE)) { return 0.5f; } return 0.0f; }
JAX-RS的内容协商核心逻辑是客户端Accept头的qs值 乘以 源端Produces里的qs值,得分最高的媒体类型会被选中,上述两种方法都遵循了这个规则,能得到准确的匹配结果。
内容的提问来源于stack exchange,提问作者user3687501
相关产品推荐
相关产品推荐

