Response Bean对象没有get方法导致无法返回参数

          在编码过程中,返回的参数bean中忘记了实现get方法,导致该参数的值未返回给客户端。

例子如下:

@RestController
public class HelloController {

    @GetMapping("testGet")
    public HelloWordResp hello() {
        HelloWordResp helloWordResp = new HelloWordResp("a1", "a2");
        return helloWordResp;
    }
}
public class HelloWordResp {

    private String aa1;

    private String aa2;


    public HelloWordResp(String aa1, String aa2) {
        this.aa1 = aa1;
        this.aa2 = aa2;
    }

    public String getAa1() {
        return aa1;
    }

    public void setAa1(String aa1) {
        this.aa1 = aa1;
    }
}

        调接口后,返回的结果如下:

{
    "aa1": "a1"
}

        可以看到,只返回了aa1,并没有返回aa2.

源码解析

protected <T> void writeWithMessageConverters(T value, MethodParameter returnType,
			ServletServerHttpRequest inputMessage, ServletServerHttpResponse outputMessage)
			throws IOException, HttpMediaTypeNotAcceptableException, HttpMessageNotWritableException {

		Object outputValue;
		Class<?> valueType;
		Type declaredType;

		if (value instanceof CharSequence) {
			outputValue = value.toString();
			valueType = String.class;
			declaredType = String.class;
		}
		else {
			outputValue = value;
			valueType = getReturnValueType(outputValue, returnType);
			declaredType = getGenericType(returnType);
		}

		HttpServletRequest request = inputMessage.getServletRequest();
		List<MediaType> requestedMediaTypes = getAcceptableMediaTypes(request);
		List<MediaType> producibleMediaTypes = getProducibleMediaTypes(request, valueType, declaredType);

		if (outputValue != null && producibleMediaTypes.isEmpty()) {
			throw new IllegalArgumentException("No converter found for return value of type: " + valueType);
		}

		Set<MediaType> compatibleMediaTypes = new LinkedHashSet<MediaType>();
		for (MediaType requestedType : requestedMediaTypes) {
			for (MediaType producibleType : producibleMediaTypes) {
				if (requestedType.isCompatibleWith(producibleType)) {
					compatibleMediaTypes.add(getMostSpecificMediaType(requestedType, producibleType));
				}
			}
		}
		if (compatibleMediaTypes.isEmpty()) {
			if (outputValue != null) {
				throw new HttpMediaTypeNotAcceptableException(producibleMediaTypes);
			}
			return;
		}

		List<MediaType> mediaTypes = new ArrayList<MediaType>(compatibleMediaTypes);
		MediaType.sortBySpecificityAndQuality(mediaTypes);

//如果是json形式的返回格式,这里会解析出selectedMediaType为application/json
		MediaType selectedMediaType = null;
		for (MediaType mediaType : mediaTypes) {
			if (mediaType.isConcrete()) {
				selectedMediaType = mediaType;
				break;
			}
			else if (mediaType.equals(MediaType.ALL) || mediaType.equals(MEDIA_TYPE_APPLICATION)) {
				selectedMediaType = MediaType.APPLICATION_OCTET_STREAM;
				break;
			}
		}

		if (selectedMediaType != null) {
			selectedMediaType = selectedMediaType.removeQualityValue();
			for (HttpMessageConverter<?> messageConverter : this.messageConverters) {
				if (messageConverter instanceof GenericHttpMessageConverter) {
//关键在这里,会有MappingJackson2HttpMessageConverter对象进行处理
					if (((GenericHttpMessageConverter) messageConverter).canWrite(
							declaredType, valueType, selectedMediaType)) {
						outputValue = (T) getAdvice().beforeBodyWrite(outputValue, returnType, selectedMediaType,
								(Class<? extends HttpMessageConverter<?>>) messageConverter.getClass(),
								inputMessage, outputMessage);
						if (outputValue != null) {
							addContentDispositionHeader(inputMessage, outputMessage);
							((GenericHttpMessageConverter) messageConverter).write(
									outputValue, declaredType, selectedMediaType, outputMessage);
							if (logger.isDebugEnabled()) {
								logger.debug("Written [" + outputValue + "] as \"" + selectedMediaType +
										"\" using [" + messageConverter + "]");
							}
						}
						return;
					}
				}
				else if (messageConverter.canWrite(valueType, selectedMediaType)) {
					outputValue = (T) getAdvice().beforeBodyWrite(outputValue, returnType, selectedMediaType,
							(Class<? extends HttpMessageConverter<?>>) messageConverter.getClass(),
							inputMessage, outputMessage);
					if (outputValue != null) {
						addContentDispositionHeader(inputMessage, outputMessage);
						((HttpMessageConverter) messageConverter).write(outputValue, selectedMediaType, outputMessage);
						if (logger.isDebugEnabled()) {
							logger.debug("Written [" + outputValue + "] as \"" + selectedMediaType +
									"\" using [" + messageConverter + "]");
						}
					}
					return;
				}
			}
		}

		if (outputValue != null) {
			throw new HttpMediaTypeNotAcceptableException(this.allSupportedMediaTypes);
		}
	}

 MappingJackson2HttpMessageConverter的继承关系图如下:

 这里会调用其父类AbstractGenericHttpMessageConverter的write方法

会调用ObjectWriter的writeValue方法

调用DefaultSerializerProvider

props中会存储get方法,在序列化的时候会使用到。

如果bean中没有get方法,那么会抛异常

java.lang.IllegalArgumentException: No converter found for return value of type

后续再分析抛该异常的原因。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现这个功能,你需要使用Java Gateway提供的拦截器(Interceptor)和HttpServletRequest对象。 首先,你需要创建一个拦截器类,实现Java Gateway提供的Interceptor接口,并重写其preHandle方法。在preHandle方法中,你可以获取到HttpServletRequest对象,进而修改请求参数。 以下是一个简单的示例代码: ``` import java.util.*; import javax.servlet.http.*; import org.springframework.web.servlet.handler.*; public class PostParamInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 判断请求方法是否为POST if ("POST".equalsIgnoreCase(request.getMethod())) { // 获取原始请求参数 Map<String, String[]> paramMap = request.getParameterMap(); // 新增请求参数 paramMap.put("newParam", new String[] {"value"}); // 创建一个包装器,用于修改请求参数 HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper(request) { @Override public Map<String, String[]> getParameterMap() { return paramMap; } @Override public String[] getParameterValues(String name) { return paramMap.get(name); } @Override public String getParameter(String name) { String[] values = paramMap.get(name); if (values != null && values.length > 0) { return values[0]; } return null; } }; // 替换原始的HttpServletRequest对象 request = requestWrapper; } return true; } } ``` 上面的代码中,我们判断请求方法是否为POST,如果是POST,则获取原始请求参数,并新增一个请求参数(key为"newParam",value为"value")。然后,我们创建一个HttpServletRequestWrapper对象,并重写其getParameterMap、getParameterValues和getParameter方法,使其返回我们修改过的请求参数。最后,我们用修改过的HttpServletRequestWrapper对象替换原始的HttpServletRequest对象。 接下来,你需要在Java Gateway的配置文件中注册这个拦截器。假设你使用的是Spring框架,你可以在配置文件中添加以下代码: ``` <mvc:interceptors> <bean class="com.example.PostParamInterceptor"/> </mvc:interceptors> ``` 上面的代码中,我们在<mvc:interceptors>标签中注册了PostParamInterceptor拦截器。 这样,当有请求进入Java Gateway时,如果请求方法为POST,PostParamInterceptor拦截器就会被触发,执行我们添加参数的逻辑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值