@Override @SuppressWarnings({"unchecked", "rawtypes"}) public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception { if (returnValue instanceof Map){ mavContainer.addAllAttributes((Map) returnValue); } else if (returnValue != null) { // should not happen throw new UnsupportedOperationException("Unexpected return type: " + returnType.getParameterType().getName() + " in method: " + returnType.getMethod()); } }
@Override protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) { PathVariable ann = parameter.getParameterAnnotation(PathVariable.class); Assert.state(ann != null, "No PathVariable annotation"); return new PathVariableNamedValueInfo(ann); }
/** * Return a {@link ResolvableType} for the specified {@link Method} return type. * @param method the source for the method return type * @return a {@link ResolvableType} for the specified method return * @see #forMethodReturnType(Method, Class) */ public static ResolvableType forMethodReturnType(Method method) { Assert.notNull(method, "Method must not be null"); return forMethodParameter(new MethodParameter(method, -1)); }
private String getParameterName(MethodParameter param) { String paramName = param.getParameterName(); return (paramName != null ? paramName : "Arg " + param.getParameterIndex()); }
@Override public boolean supportsParameter(MethodParameter parameter) { return (parameter.hasParameterAnnotation(RequestHeader.class) && !Map.class.isAssignableFrom(parameter.nestedIfOptional().getNestedParameterType())); }
@Override public boolean supportsParameter(MethodParameter parameter) { return (parameter.hasParameterAnnotation(RequestHeader.class) && Map.class.isAssignableFrom(parameter.getParameterType())); }
@Override protected Object resolveNamedValue(String name, MethodParameter parameter, ServerWebExchange exchange) { Object value = exchange.getAttribute(name); ReactiveAdapter toAdapter = getAdapterRegistry().getAdapter(parameter.getParameterType()); if (toAdapter != null) { if (value == null) { Assert.isTrue(toAdapter.supportsEmpty(), () -> "No request attribute '" + name + "' and target type " + parameter.getGenericParameterType() + " doesn't support empty values."); return toAdapter.fromPublisher(Mono.empty()); } if (parameter.getParameterType().isAssignableFrom(value.getClass())) { return value; } ReactiveAdapter fromAdapter = getAdapterRegistry().getAdapter(value.getClass()); Assert.isTrue(fromAdapter != null, () -> getClass().getSimpleName() + " doesn't support " + "reactive type wrapper: " + parameter.getGenericParameterType()); return toAdapter.fromPublisher(fromAdapter.toPublisher(value)); } return value; }
/** * Return the type of the value to be written to the response. Typically this is * a simple check via getClass on the value but if the value is null, then the * return type needs to be examined possibly including generic type determination * (e.g. {@code ResponseEntity<T>}). */ protected Class<?> getReturnValueType(@Nullable Object value, MethodParameter returnType) { return (value != null ? value.getClass() : returnType.getParameterType()); }
@Nullable private Type getHttpEntityType(MethodParameter parameter) { Assert.isAssignable(HttpEntity.class, parameter.getParameterType()); Type parameterType = parameter.getGenericParameterType(); if (parameterType instanceof ParameterizedType) { ParameterizedType type = (ParameterizedType) parameterType; if (type.getActualTypeArguments().length != 1) { throw new IllegalArgumentException("Expected single generic parameter on '" + parameter.getParameterName() + "' in method " + parameter.getMethod()); } return type.getActualTypeArguments()[0]; } else if (parameterType instanceof Class) { return Object.class; } else { return null; } }
@Override @Nullable public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception { Assert.state(mavContainer != null, "Errors/BindingResult argument only supported on regular handler methods"); ModelMap model = mavContainer.getModel(); String lastKey = CollectionUtils.lastElement(model.keySet()); if (lastKey != null && lastKey.startsWith(BindingResult.MODEL_KEY_PREFIX)) { return model.get(lastKey); } throw new IllegalStateException( "An Errors/BindingResult argument is expected to be declared immediately after " + "the model attribute, the @RequestBody or the @RequestPart arguments " + "to which they apply: " + parameter.getMethod()); }
@Override public ListenableFuture<?> toListenableFuture(Object returnValue, MethodParameter returnType) { ReactiveAdapter adapter = this.adapterRegistry.getAdapter(returnType.getParameterType(), returnValue); Assert.state(adapter != null, () -> "No ReactiveAdapter found for " + returnType.getParameterType()); return new MonoToListenableFutureAdapter<>(Mono.from(adapter.toPublisher(returnValue))); }
@Override @Nullable public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws IOException, HttpMediaTypeNotSupportedException { ServletServerHttpRequest inputMessage = createInputMessage(webRequest); Type paramType = getHttpEntityType(parameter); if (paramType == null) { throw new IllegalArgumentException("HttpEntity parameter '" + parameter.getParameterName() + "' in method " + parameter.getMethod() + " is not parameterized"); } Object body = readWithMessageConverters(webRequest, parameter, paramType); if (RequestEntity.class == parameter.getParameterType()) { return new RequestEntity<>(body, inputMessage.getHeaders(), inputMessage.getMethod(), inputMessage.getURI()); } else { return new HttpEntity<>(body, inputMessage.getHeaders()); } }
@Override public boolean supportsParameter(MethodParameter parameter) { RequestParam requestParam = parameter.getParameterAnnotation(RequestParam.class); return (requestParam != null && Map.class.isAssignableFrom(parameter.getParameterType()) && !StringUtils.hasText(requestParam.name())); }
@Nullable private MethodParameter resolveReadMethodParameter() { if (getReadMethod() == null) { return null; } return resolveParameterType(new MethodParameter(getReadMethod(), -1)); }
private String getPartName(MethodParameter methodParam, @Nullable RequestPart requestPart) { String partName = (requestPart != null ? requestPart.name() : ""); if (partName.isEmpty()) { partName = methodParam.getParameterName(); if (partName == null) { throw new IllegalArgumentException("Request part name for argument type [" + methodParam.getNestedParameterType().getName() + "] not specified, and parameter name information not found in class file either."); } } return partName; }
/** * Constructor for a 500 error with a {@link MethodParameter} and an optional cause. */ public ServerErrorException(String reason, MethodParameter parameter, @Nullable Throwable cause) { super(HttpStatus.INTERNAL_SERVER_ERROR, reason, cause); this.handlerMethod = parameter.getMethod(); this.parameter = parameter; }
/** * Return the parameter annotation of the given type, if available. * @param annotationType the annotation type to look for * @return the annotation object, or {@code null} if not found */ @SuppressWarnings("unchecked") @Nullable public <A extends Annotation> A getParameterAnnotation(Class<A> annotationType) { Annotation[] anns = getParameterAnnotations(); for (Annotation ann : anns) { if (annotationType.isInstance(ann)) { return (A) ann; } } return null; }
/** * Retrieve a field/parameter annotation of the given type, if any. * @param annotationType the annotation type to retrieve * @return the annotation instance, or {@code null} if none found * @since 4.3.9 */ @Nullable public <A extends Annotation> A getAnnotation(Class<A> annotationType) { return (this.field != null ? this.field.getAnnotation(annotationType) : obtainMethodParameter().getParameterAnnotation(annotationType)); }
/** * Determine the name of the wrapped parameter/field. * @return the declared name (never {@code null}) */ @Nullable public String getDependencyName() { return (this.field != null ? this.field.getName() : obtainMethodParameter().getParameterName()); }
private static boolean isAsyncVoidReturnType(MethodParameter returnType, @Nullable ReactiveAdapter adapter) { if (adapter != null && adapter.supportsEmpty()) { if (adapter.isNoValue()) { return true; } Type parameterType = returnType.getGenericParameterType(); if (parameterType instanceof ParameterizedType) { ParameterizedType type = (ParameterizedType) parameterType; if (type.getActualTypeArguments().length == 1) { return Void.class.equals(type.getActualTypeArguments()[0]); } } } return false; }