记一次Spring3.0 返回Map<Long,List<Item>> 类型结果出现 castClassException:Long to String 错误

版本:Spring3.0 、java 1.6

@RequestMapping(/get)   
 public Map<Long, List<Item>> getPrepareTradeItemMap(UserKey key, Long[] ids) throws Exception {}

上面的方法没有使用@responseBody注解去转json格式,项目自定义了一个ReturnHandler实现

HandlerMethodReturnValueHandler,来对所有controller层返回的结果进行处理

代码如下:

public class FeReturnValueHandler implements HandlerMethodReturnValueHandler {
    @Override
    public boolean supportsReturnType(MethodParameter methodParameter) {
        Annotation annotations = methodParameter.getDeclaringClass().getAnnotation(FeAnnotations.class);
        return annotations != null;
    }

    @Override
    public void handleReturnValue(Object object, MethodParameter parameter, ModelAndViewContainer container, NativeWebRequest webRequest) throws Exception {
        HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
        HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
        boolean isRedirect = false;
        if (object instanceof String) {
            String viewName = (String) object;
            if (viewName.startsWith("redirect:")) {
                isRedirect = true;
                container.setViewName(viewName);
                container.setRedirectModelScenario(true);
            }
        }

        if (!isRedirect) {
            JsonResponse jsonResponse = new JsonResponse();
            jsonResponse.setData(object);
            HttpUtil.write(request, response, jsonResponse);
        }

    }
}

 但是吧、这个 Map<Long, List<Item>> 的返回类型,好巧不巧,被MapMethodProcessor先拦截了,然后进入到了MapMethodProcessor的实现类里面

下图是实现HandlerMethodReturnValueHandler接口的一些方法:

 然后我们去看看MapMethodProcessor的实现类:

public class MapMethodProcessor implements HandlerMethodArgumentResolver, HandlerMethodReturnValueHandler {
    public MapMethodProcessor() {
    }

    public boolean supportsParameter(MethodParameter parameter) {
        return Map.class.isAssignableFrom(parameter.getParameterType());
    }

    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        return mavContainer.getModel();
    }

    public boolean supportsReturnType(MethodParameter returnType) {
        return Map.class.isAssignableFrom(returnType.getParameterType());
    }

    public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
        if (returnValue != null) {
            if (returnValue instanceof Map) {
                mavContainer.addAllAttributes((Map)returnValue);
            } else {
                throw new UnsupportedOperationException("Unexpected return type: " + returnType.getParameterType().getName() + " in method: " + returnType.getMethod());
            }
        }
    }
}

 

 在这里我们找到凶手了,凶手就是红色框框框出来的Map类型,在

mavContainer.addAllAttributes((Map)returnValue);方法中,指定了returnValue的接受类型:<String,?>,而我们从controller返回的是Map<Long, List<Item>> 类型,所以就发生的castException异常, Long to String

这里有一点要说明:是否进去handleReturnValue()方法是根据supportsReturnType()的boolean结果来决定的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值