/** * {@inheritDoc} * @throws HttpMediaTypeNotAcceptableException if the 'Accept' header cannot be parsed. */ @Override public List<MediaType> resolveMediaTypes(NativeWebRequest webRequest) throws HttpMediaTypeNotAcceptableException { String acceptHeader = webRequest.getHeader(ACCEPT_HEADER); try { if (StringUtils.hasText(acceptHeader)) { List<MediaType> mediaTypes = MediaType.parseMediaTypes(acceptHeader); MediaType.sortBySpecificityAndQuality(mediaTypes); return mediaTypes; } } catch (InvalidMediaTypeException ex) { throw new HttpMediaTypeNotAcceptableException( "Could not parse accept header [" + acceptHeader + "]: " + ex.getMessage()); } return Collections.emptyList(); }
public void checkContentType(String contentType) { try { MediaType media = MediaType.parseMediaType(contentType); // TODO improve the logic here if (media.getSubtype() != null && !media.getSubtype().contains("xml") && !media.getSubtype().contains("fhir") && !media.getSubtype().contains("json") && !media.getSubtype().contains("plain")) { log.info("Unsupported media type: " + contentType); throw new InvalidRequestException("Unsupported media type: sub " + contentType); } else { if (!contentType.contains("xml") && !contentType.contains("json")) { log.info("Unsupported media type: " + contentType); throw new InvalidRequestException("Unsupported media type: content " + contentType); } } } catch (InvalidMediaTypeException e) { log.info("Unsupported media type: " + contentType); throw new InvalidRequestException("Unsupported media type: mime " + contentType); } }
/** * {@inheritDoc} * @throws HttpMediaTypeNotAcceptableException if the 'Accept' header * cannot be parsed. */ @Override public List<MediaType> resolveMediaTypes(NativeWebRequest request) throws HttpMediaTypeNotAcceptableException { String header = request.getHeader(HttpHeaders.ACCEPT); if (!StringUtils.hasText(header)) { return Collections.emptyList(); } try { List<MediaType> mediaTypes = MediaType.parseMediaTypes(header); MediaType.sortBySpecificityAndQuality(mediaTypes); return mediaTypes; } catch (InvalidMediaTypeException ex) { throw new HttpMediaTypeNotAcceptableException( "Could not parse 'Accept' header [" + header + "]: " + ex.getMessage()); } }
@Override public boolean shouldFilter() { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); String contentType = request.getContentType(); // Don't use this filter on GET method if (contentType == null) { return false; } // Only use this filter for form data and only for multipart data in a // DispatcherServlet handler try { MediaType mediaType = MediaType.valueOf(contentType); return MediaType.APPLICATION_FORM_URLENCODED.includes(mediaType) || (isDispatcherServletRequest(request) && MediaType.MULTIPART_FORM_DATA.includes(mediaType)); } catch (InvalidMediaTypeException ex) { return false; } }
/** * Check if the given {@code String} is a JSON MIME. * @param mediaType the input MediaType * @return boolean true if the MediaType represents JSON, false otherwise */ public boolean isJsonMime(String mediaType) { try { return isJsonMime(MediaType.parseMediaType(mediaType)); } catch (InvalidMediaTypeException e) { } return false; }
private MediaType parseMediaType(String contentType) { try { return MediaType.parseMediaType(contentType); } catch (InvalidMediaTypeException ex) { throw new ContentTypeInvalidException(); } }
@Override protected boolean matchMediaType(HttpServletRequest request) throws HttpMediaTypeNotSupportedException { try { MediaType contentType = StringUtils.hasLength(request.getContentType()) ? MediaType.parseMediaType(request.getContentType()) : MediaType.APPLICATION_OCTET_STREAM; return getMediaType().includes(contentType); } catch (InvalidMediaTypeException ex) { throw new HttpMediaTypeNotSupportedException( "Can't parse Content-Type [" + request.getContentType() + "]: " + ex.getMessage()); } }
/** * Indicates whether the media type (content type) of the * given HTTP request is compatible with the given media type. * * @param request the HTTP response. * @param mediaType the media type. */ public static boolean isCompatibleWith( HttpServletResponse response, MediaType mediaType ) { try { String contentType = response.getContentType(); return contentType != null && MediaType.parseMediaType( contentType ).isCompatibleWith( mediaType ); } catch ( InvalidMediaTypeException ex ) { return false; } }
private boolean contentTypeAllowed(String contentType) { MediaType mediaType; try { mediaType = MediaType.parseMediaType(contentType); } catch (InvalidMediaTypeException e) { log.warn("Couldn't parse media type {}", contentType, e); return false; } for (MediaType el : attachmentTypesAllowed) { if (el.includes(mediaType)) { return true; } } return false; }
/** * Searches {@link org.springframework.web.bind.annotation.RequestMapping RequestMapping} * annotation on the given method argument and extracts * If RequestMapping annotation is not found, NoRequestMappingFoundException is thrown. * {@link org.springframework.http.HttpMethod HttpMethod} type equivalent to * {@link org.springframework.web.bind.annotation.RequestMethod RequestMethod} type * * @param element AnnotatedElement object to be examined. * @return Mapping object */ Mapping extractMapping(AnnotatedElement element) { Annotation annotation = findMappingAnnotation(element); String[] urls; RequestMethod requestMethod; String consumes; if (annotation instanceof RequestMapping) { RequestMapping requestMapping = (RequestMapping) annotation; requestMethod = requestMapping.method().length == 0 ? RequestMethod.GET : requestMapping.method()[0]; urls = requestMapping.value(); consumes = StringHelper.getFirstOrEmpty(requestMapping.consumes()); } else if (annotation instanceof GetMapping) { requestMethod = RequestMethod.GET; urls = ((GetMapping) annotation).value(); consumes = StringHelper.getFirstOrEmpty(((GetMapping) annotation).consumes()); } else if (annotation instanceof PostMapping) { requestMethod = RequestMethod.POST; urls = ((PostMapping) annotation).value(); consumes = StringHelper.getFirstOrEmpty(((PostMapping) annotation).consumes()); } else if (annotation instanceof PutMapping) { requestMethod = RequestMethod.PUT; urls = ((PutMapping) annotation).value(); consumes = StringHelper.getFirstOrEmpty(((PutMapping) annotation).consumes()); } else if (annotation instanceof DeleteMapping) { requestMethod = RequestMethod.DELETE; urls = ((DeleteMapping) annotation).value(); consumes = StringHelper.getFirstOrEmpty(((DeleteMapping) annotation).consumes()); } else if (annotation instanceof PatchMapping) { requestMethod = RequestMethod.PATCH; urls = ((PatchMapping) annotation).value(); consumes = StringHelper.getFirstOrEmpty(((PatchMapping) annotation).consumes()); } else { throw new NoRequestMappingFoundException(element); } HttpMethod httpMethod = HttpMethod.resolve(requestMethod.name()); String url = StringHelper.getFirstOrEmpty(urls); MediaType mediaType; try { mediaType = MediaType.valueOf(consumes); } catch (InvalidMediaTypeException exception) { mediaType = MediaType.APPLICATION_JSON_UTF8; } return new Mapping(httpMethod, url, mediaType); }
/** * Iterate all RequestMappingInfos once again, look if any match by URL at * least and raise exceptions accordingly. * @throws HttpRequestMethodNotSupportedException if there are matches by URL * but not by HTTP method * @throws HttpMediaTypeNotAcceptableException if there are matches by URL * but not by consumable/producible media types */ @Override protected HandlerMethod handleNoMatch(Set<RequestMappingInfo> requestMappingInfos, String lookupPath, HttpServletRequest request) throws ServletException { Set<String> allowedMethods = new LinkedHashSet<String>(4); Set<RequestMappingInfo> patternMatches = new HashSet<RequestMappingInfo>(); Set<RequestMappingInfo> patternAndMethodMatches = new HashSet<RequestMappingInfo>(); for (RequestMappingInfo info : requestMappingInfos) { if (info.getPatternsCondition().getMatchingCondition(request) != null) { patternMatches.add(info); if (info.getMethodsCondition().getMatchingCondition(request) != null) { patternAndMethodMatches.add(info); } else { for (RequestMethod method : info.getMethodsCondition().getMethods()) { allowedMethods.add(method.name()); } } } } if (patternMatches.isEmpty()) { return null; } else if (patternAndMethodMatches.isEmpty() && !allowedMethods.isEmpty()) { throw new HttpRequestMethodNotSupportedException(request.getMethod(), allowedMethods); } Set<MediaType> consumableMediaTypes; Set<MediaType> producibleMediaTypes; List<String[]> paramConditions; if (patternAndMethodMatches.isEmpty()) { consumableMediaTypes = getConsumableMediaTypes(request, patternMatches); producibleMediaTypes = getProducibleMediaTypes(request, patternMatches); paramConditions = getRequestParams(request, patternMatches); } else { consumableMediaTypes = getConsumableMediaTypes(request, patternAndMethodMatches); producibleMediaTypes = getProducibleMediaTypes(request, patternAndMethodMatches); paramConditions = getRequestParams(request, patternAndMethodMatches); } if (!consumableMediaTypes.isEmpty()) { MediaType contentType = null; if (StringUtils.hasLength(request.getContentType())) { try { contentType = MediaType.parseMediaType(request.getContentType()); } catch (InvalidMediaTypeException ex) { throw new HttpMediaTypeNotSupportedException(ex.getMessage()); } } throw new HttpMediaTypeNotSupportedException(contentType, new ArrayList<MediaType>(consumableMediaTypes)); } else if (!producibleMediaTypes.isEmpty()) { throw new HttpMediaTypeNotAcceptableException(new ArrayList<MediaType>(producibleMediaTypes)); } else if (!CollectionUtils.isEmpty(paramConditions)) { throw new UnsatisfiedServletRequestParameterException(paramConditions, request.getParameterMap()); } else { return null; } }
/** * Creates the method argument value of the expected parameter type by reading * from the given HttpInputMessage. * * @param <T> the expected type of the argument value to be created * @param inputMessage the HTTP input message representing the current request * @param methodParam the method argument * @param targetType the type of object to create, not necessarily the same as * the method parameter type (e.g. for {@code HttpEntity<String>} method * parameter the target type is String) * @return the created method argument value * @throws IOException if the reading from the request fails * @throws HttpMediaTypeNotSupportedException if no suitable message converter is found */ @SuppressWarnings("unchecked") protected <T> Object readWithMessageConverters(HttpInputMessage inputMessage, MethodParameter methodParam, Type targetType) throws IOException, HttpMediaTypeNotSupportedException { MediaType contentType; try { contentType = inputMessage.getHeaders().getContentType(); } catch (InvalidMediaTypeException ex) { throw new HttpMediaTypeNotSupportedException(ex.getMessage()); } if (contentType == null) { contentType = MediaType.APPLICATION_OCTET_STREAM; } Class<?> contextClass = methodParam.getDeclaringClass(); Map<TypeVariable, Type> map = GenericTypeResolver.getTypeVariableMap(contextClass); Class<T> targetClass = (Class<T>) GenericTypeResolver.resolveType(targetType, map); for (HttpMessageConverter<?> converter : this.messageConverters) { if (converter instanceof GenericHttpMessageConverter) { GenericHttpMessageConverter genericConverter = (GenericHttpMessageConverter) converter; if (genericConverter.canRead(targetType, contextClass, contentType)) { if (logger.isDebugEnabled()) { logger.debug("Reading [" + targetType + "] as \"" + contentType + "\" using [" + converter + "]"); } return genericConverter.read(targetType, contextClass, inputMessage); } } if (targetClass != null) { if (converter.canRead(targetClass, contentType)) { if (logger.isDebugEnabled()) { logger.debug("Reading [" + targetClass.getName() + "] as \"" + contentType + "\" using [" + converter + "]"); } return ((HttpMessageConverter<T>) converter).read(targetClass, inputMessage); } } } throw new HttpMediaTypeNotSupportedException(contentType, allSupportedMediaTypes); }