/* * Don't consider parameter types that are available after conversion. * Message, Message<?> and Channel. */ private boolean isEligibleParameter(MethodParameter methodParameter) { Type parameterType = methodParameter.getGenericParameterType(); if (parameterType.equals(Channel.class) || parameterType.equals(org.springframework.amqp.core.Message.class)) { return false; } if (parameterType instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) parameterType; if (parameterizedType.getRawType().equals(Message.class)) { return !(parameterizedType.getActualTypeArguments()[0] instanceof WildcardType); } } return !parameterType.equals(Message.class); // could be Message without a generic type }
private MethodReturnValueHandler getReturnValueHandler(MethodParameter returnType) { for (MethodReturnValueHandler returnValueHandler : returnValueHandlers) { if (logger.isTraceEnabled()) { logger.trace( "Testing if return value handler [" + returnValueHandler + "] supports [" + returnType.getGenericParameterType() + "]"); } if (returnValueHandler.supportsReturnType(returnType)) { return returnValueHandler; } } return null; }
private Object tryParseAsJson(MethodParameter parameter, String str, Class<?> parameterType) { char c = str.charAt(0); boolean maybeJson = c == '{'; if (maybeJson) return Json.unJson(str, parameterType); boolean maybeJsonArray = c == '['; if (maybeJsonArray) { Type genericParameterType = parameter.getGenericParameterType(); boolean isGeneric = genericParameterType instanceof ParameterizedType; if (isGeneric) { ParameterizedType parameterizedType = (ParameterizedType) genericParameterType; Class<?> argType = (Class) parameterizedType.getActualTypeArguments()[0]; return Json.unJsonArray(str, argType); } } return null; }
private Class<?> getHttpEntityType(MethodParameter methodParam) { Assert.isAssignable(HttpEntity.class, methodParam.getParameterType()); ParameterizedType type = (ParameterizedType) methodParam.getGenericParameterType(); if (type.getActualTypeArguments().length == 1) { Type typeArgument = type.getActualTypeArguments()[0]; if (typeArgument instanceof Class) { return (Class<?>) typeArgument; } else if (typeArgument instanceof GenericArrayType) { Type componentType = ((GenericArrayType) typeArgument).getGenericComponentType(); if (componentType instanceof Class) { // Surely, there should be a nicer way to do this Object array = Array.newInstance((Class<?>) componentType, 0); return array.getClass(); } } } throw new IllegalArgumentException( "HttpEntity parameter (" + methodParam.getParameterName() + ") is not parameterized"); }
/** * Find a registered {@link HandlerMethodReturnValueHandler} that supports the given return type. */ private HandlerMethodReturnValueHandler getReturnValueHandler(MethodParameter returnType) { HandlerMethodReturnValueHandler result = this.returnValueHandlerCache.get(returnType); if (result == null) { for (HandlerMethodReturnValueHandler returnValueHandler : returnValueHandlers) { if (logger.isTraceEnabled()) { logger.trace( "Testing if return value handler [" + returnValueHandler + "] supports [" + returnType.getGenericParameterType() + "]"); } if (returnValueHandler.supportsReturnType(returnType)) { result = returnValueHandler; this.returnValueHandlerCache.put(returnType, returnValueHandler); break; } } } return result; }
private Type determineInferredType() { if (this.method == null) { return null; } Type genericParameterType = null; for (int i = 0; i < this.method.getParameterCount(); i++) { MethodParameter methodParameter = new MethodParameter(this.method, i); /* * We're looking for a single non-annotated parameter, or one annotated with @Payload. * We ignore parameters with type Message because they are not involved with conversion. */ if (isEligibleParameter(methodParameter) && (methodParameter.getParameterAnnotations().length == 0 || methodParameter.hasParameterAnnotation(Payload.class))) { if (genericParameterType == null) { genericParameterType = methodParameter.getGenericParameterType(); if (genericParameterType instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) genericParameterType; if (parameterizedType.getRawType().equals(Message.class)) { genericParameterType = ((ParameterizedType) genericParameterType).getActualTypeArguments()[0]; } } } else { if (MessagingMessageListenerAdapter.this.logger.isDebugEnabled()) { MessagingMessageListenerAdapter.this.logger.debug( "Ambiguous parameters for target payload for method " + this.method + "; no inferred type header added"); } return null; } } } return genericParameterType; }
/** * {@inheritDoc} * * <p>Downcast {@link org.springframework.web.bind.WebDataBinder} to {@link * org.springframework.web.bind.ServletRequestDataBinder} before binding. * * @throws Exception * @see org.springframework.web.servlet.mvc.method.annotation.ServletRequestDataBinderFactory */ protected void bindRequestParameters( ModelAndViewContainer mavContainer, WebDataBinderFactory binderFactory, WebDataBinder binder, NativeWebRequest request, MethodParameter parameter) throws Exception { Map<String, Boolean> hasProcessedPrefixMap = new HashMap<String, Boolean>(); Class<?> targetType = binder.getTarget().getClass(); ServletRequest servletRequest = prepareServletRequest(binder.getTarget(), request, parameter); WebDataBinder simpleBinder = binderFactory.createBinder(request, null, null); if (Collection.class.isAssignableFrom(targetType)) { // bind collection or array Type type = parameter.getGenericParameterType(); Class<?> componentType = Object.class; Collection target = (Collection) binder.getTarget(); List targetList = new ArrayList(target); if (type instanceof ParameterizedType) { componentType = (Class<?>) ((ParameterizedType) type).getActualTypeArguments()[0]; } if (parameter.getParameterType().isArray()) { componentType = parameter.getParameterType().getComponentType(); } for (Object key : servletRequest.getParameterMap().keySet()) { String prefixName = getPrefixName((String) key); // 每个prefix 只处理一次 if (hasProcessedPrefixMap.containsKey(prefixName)) { continue; } else { hasProcessedPrefixMap.put(prefixName, Boolean.TRUE); } if (isSimpleComponent(prefixName)) { // bind simple type Map<String, Object> paramValues = WebUtils.getParametersStartingWith(servletRequest, prefixName); Matcher matcher = INDEX_PATTERN.matcher(prefixName); if (!matcher.matches()) { // 处理如 array=1&array=2的情况 for (Object value : paramValues.values()) { targetList.add(simpleBinder.convertIfNecessary(value, componentType)); } } else { // 处理如 array[0]=1&array[1]=2的情况 int index = Integer.valueOf(matcher.group(1)); if (targetList.size() <= index) { growCollectionIfNecessary(targetList, index); } targetList.set( index, simpleBinder.convertIfNecessary(paramValues.values(), componentType)); } } else { // 处理如 // votes[1].title=votes[1].title&votes[0].title=votes[0].title&votes[0].id=0&votes[1].id=1 Object component = null; // 先查找老的 即已经在集合中的数据(而不是新添加一个) Matcher matcher = INDEX_PATTERN.matcher(prefixName); if (!matcher.matches()) { throw new IllegalArgumentException( "bind collection error, need integer index, key:" + key); } int index = Integer.valueOf(matcher.group(1)); if (targetList.size() <= index) { growCollectionIfNecessary(targetList, index); } Iterator iterator = targetList.iterator(); for (int i = 0; i < index; i++) { iterator.next(); } component = iterator.next(); if (component == null) { component = BeanUtils.instantiate(componentType); } WebDataBinder componentBinder = binderFactory.createBinder(request, component, null); component = componentBinder.getTarget(); if (component != null) { ServletRequestParameterPropertyValues pvs = new ServletRequestParameterPropertyValues(servletRequest, prefixName, ""); componentBinder.bind(pvs); validateIfApplicable(componentBinder, parameter); if (componentBinder.getBindingResult().hasErrors()) { if (isBindExceptionRequired(componentBinder, parameter)) { throw new BindException(componentBinder.getBindingResult()); } } targetList.set(index, component); } } target.clear(); target.addAll(targetList); } } else if (MapWapper.class.isAssignableFrom(targetType)) { Type type = parameter.getGenericParameterType(); Class<?> keyType = Object.class; Class<?> valueType = Object.class; if (type instanceof ParameterizedType) { keyType = (Class<?>) ((ParameterizedType) type).getActualTypeArguments()[0]; valueType = (Class<?>) ((ParameterizedType) type).getActualTypeArguments()[1]; } MapWapper mapWapper = ((MapWapper) binder.getTarget()); Map target = mapWapper.getInnerMap(); if (target == null) { target = new HashMap(); mapWapper.setInnerMap(target); } for (Object key : servletRequest.getParameterMap().keySet()) { String prefixName = getPrefixName((String) key); // 每个prefix 只处理一次 if (hasProcessedPrefixMap.containsKey(prefixName)) { continue; } else { hasProcessedPrefixMap.put(prefixName, Boolean.TRUE); } Object keyValue = simpleBinder.convertIfNecessary(getMapKey(prefixName), keyType); if (isSimpleComponent(prefixName)) { // bind simple type Map<String, Object> paramValues = WebUtils.getParametersStartingWith(servletRequest, prefixName); for (Object value : paramValues.values()) { target.put(keyValue, simpleBinder.convertIfNecessary(value, valueType)); } } else { Object component = target.get(keyValue); if (component == null) { component = BeanUtils.instantiate(valueType); } WebDataBinder componentBinder = binderFactory.createBinder(request, component, null); component = componentBinder.getTarget(); if (component != null) { ServletRequestParameterPropertyValues pvs = new ServletRequestParameterPropertyValues(servletRequest, prefixName, ""); componentBinder.bind(pvs); validateComponent(componentBinder, parameter); target.put(keyValue, component); } } } } else { // bind model ServletRequestDataBinder servletBinder = (ServletRequestDataBinder) binder; servletBinder.bind(servletRequest); } }
public JAXBElement<?> resolveArgument(MessageContext messageContext, MethodParameter parameter) throws JAXBException { ParameterizedType parameterizedType = (ParameterizedType) parameter.getGenericParameterType(); Class<?> clazz = (Class) parameterizedType.getActualTypeArguments()[0]; return unmarshalElementFromRequestPayload(messageContext, clazz); }
@Override protected boolean supportsRequestPayloadParameter(MethodParameter parameter) { Class<?> parameterType = parameter.getParameterType(); Type genericType = parameter.getGenericParameterType(); return JAXBElement.class.equals(parameterType) && genericType instanceof ParameterizedType; }
/** * Generic type of parameter. * * @return generic type */ public java.lang.reflect.Type getGenericParameterType() { return methodParameter.getGenericParameterType(); }