AcceptHeaderNegotiator implements ContentNegotiator { @Override public MediaType bestAllowedContentType(String acceptsHeader, Set<String> allowedTypes) { Function<AcceptFragment<MediaType>, AcceptFragment<MediaType>> serverWeightFunc = createServerWeightFunc(allowedTypes.stream() .map(CodecUtils::parseMediaType) .collect(Collectors.toSet())); return Arrays.stream(ACCEPTS_DELIMITER.split(acceptsHeader)) .map(accept -> parseAcceptFragment(accept, MediaType.class)) .filter(Objects::nonNull) .map(serverWeightFunc) .min(Comparator.comparing(AcceptFragment::getQ, reverseOrder())) .map(af -> af.fragment) .orElse(null); }  double parseQ(String qstr); AcceptFragment<S> parseAcceptFragment(String accept, Class<? extends S> acceptType); @Override MediaType bestAllowedContentType(String acceptsHeader, Set<String> allowedTypes); @Override String bestAllowedCharset(String acceptsHeader, Set<String> available); @Override String bestAllowedEncoding(String acceptsHeader, Set<String> available); @Override String bestAllowedLanguage(String acceptsHeader, Set<String> available);  }
@Test void acceptFragment() { Set<String> allowedTypes = new HashSet<>(Collections.singletonList("text/html")); MediaType mt = neg.bestAllowedContentType("text/plain; q=0.8", allowedTypes); assertThat(mt.getType()).isEqualTo("text"); assertThat(mt.getSubtype()).isEqualTo("plain"); }