SpringMVC使用了@ResponseBody报406错误的问题(1)

    昨天在编写一个程序的时候,使用@ResponseBody,以此返回一个json格式的数据,后来发现前台一直报406错误,上网找了很久,有的是配置  


		
			
                
                    
                        application/json;charset=UTF-8
                    
                
            
			
	
    解决的(需要导入fastjson相关包)

    有的是配置


    
        
            
                
                    
                        
                            text/html; charset=UTF-8
                            application/json;charset=UTF-8
                        
                    
                
                
                    
                        
                            text/html; charset=UTF-8
                            application/json;charset=UTF-8
                        
                    
                
            
        
    
    解决的(需要导入jackon相关包)
    但是,我在这边这两种方法都无效,暂时不知道为什么,然后在网上找到个例子,下载下来之后,里面没有上面的两种配置,只是加了@ResponseBody注解就可以用了,看了一下jar包,发现他用的是3.1.2版本的,而我用的是3.2.5版本的,不知道是不是这个问题,于是debug一下,出现这个问题的原因终于被我找出来了,如下

    两个版本的AbstractMessageConverterMethodProcessor类都有一个方法:getAcceptableMediaTypes,这个方法获取可以接收资源类型,就是这个地方,两个版本的处理方式不一样,所以,导致两个版本的结果也不一样,我们看一下实现:

    3.2.5版本:

	private List getAcceptableMediaTypes(HttpServletRequest request) throws HttpMediaTypeNotAcceptableException {
		List mediaTypes = this.contentNegotiationManager.resolveMediaTypes(new ServletWebRequest(request));
		return mediaTypes.isEmpty() ? Collections.singletonList(MediaType.ALL) : mediaTypes;
	}
    3.1.2版本:
	private List getAcceptableMediaTypes(HttpInputMessage inputMessage) {
		try {
			List result = inputMessage.getHeaders().getAccept();
			return result.isEmpty() ? Collections.singletonList(MediaType.ALL) : result;
		}
		catch (IllegalArgumentException ex) {
			if (logger.isDebugEnabled()) {
				logger.debug("Could not parse Accept header: " + ex.getMessage());
			}
			return Collections.emptyList();
		}
	}
    很明显,两个方法不一样,关键的的是第一句代码,3.1.2版本的是直接获取请求头中的Accept,请求头中的Accept为*/*(使用jquery的ajax请求的时候,默认是*/*),所以,json类型的可以匹配到,所以转换成功,而3.2.5版本的获取的方式不是获取请求头,一路跟踪进去,发现它关键的代码实现如下:

	protected String getMediaTypeKey(NativeWebRequest webRequest) {
		HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
		if (servletRequest == null) {
			logger.warn("An HttpServletRequest is required to determine the media type key");
			return null;
		}
		String path = urlPathHelper.getLookupPathForRequest(servletRequest);
		String filename = WebUtils.extractFullFilenameFromUrlPath(path);
		String extension = StringUtils.getFilenameExtension(filename);
		return (StringUtils.hasText(extension)) ? extension.toLowerCase(Locale.ENGLISH) : null;
	}
    它是从请求的路径来返回可接收的类型,我的SpringMVC匹配的是*.html后缀,所以,它最后返回的是text/html类型,显然,无法匹配,所以最后会报错

    根据上面的原因,我代码修改如下,便成功获取到了暑假:

    1、将*.html后缀改成/,406错误不报了,也成功的获取到了数据

    2、换成3.1.2版本的包,html和/都可以获取到数据

    这是我遇到的问题和解决的方法,发出来分享一下,而网上说的那2种配置的解决方法,在我这里无法解决问题,暂时不知道是什么原因。



你可能感兴趣的:(SpringMVC,SpringMVC)