zoukankan      html  css  js  c++  java
  • springboot ResponseEntity<byte[]> 下载文件乱码

    spring3以后添加httpMessageConverter消怎机制。其中可以通过org.springframework.http.ResponseEntity<byte[]>对象下载文件。

    pom文件如下:

    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.14.RELEASE</version>
    </parent>

    <groupId>test</groupId>
    <artifactId>test</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <dependencies>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    </dependency>

    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <!-- 这个是剔除掉自带的 tomcat部署的 -->
    <exclusions>
    <exclusion>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    </exclusion>
    </exclusions>
    </dependency>

    <!-- tomcat容器部署 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
    </dependency>

    <dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.3.0</version>
    </dependency>

    <!-- 分页插件 -->
    <dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.2.5</version>
    </dependency>

    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <optional>true</optional>
    </dependency>

    <!-- 支持 @ConfigurationProperties 注解 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
    </dependency>

    <dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    </dependency>

    <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.47</version>
    </dependency>

    <dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.0</version>
    </dependency>

    <dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-dbcp2</artifactId>
    </dependency>

    <dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
    </dependency>

    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>

    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    </dependency>

    <dependency>
    <groupId>com.belerweb</groupId>
    <artifactId>pinyin4j</artifactId>
    <version>2.5.1</version>
    </dependency>

    <dependency>
    <groupId>commons-beanutils</groupId>
    <artifactId>commons-beanutils</artifactId>
    </dependency>
    </dependencies>

    <build>
    <sourceDirectory>src/main</sourceDirectory>
    <plugins>
    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
    <source>1.7</source>
    <target>1.7</target>
    </configuration>
    </plugin>
    <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <executions>
    <execution>
    <goals>
    <goal>repackage</goal>
    </goals>
    </execution>
    </executions>
    </plugin>
    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <configuration>
    <failOnMissingWebXml>false</failOnMissingWebXml>
    </configuration>
    </plugin>
    </plugins>
    </build>

    <repositories>
    <repository>
    <id>mainMaven</id>
    <name>aliyunMaven</name>
    <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
    </repository>
    </repositories>
    <packaging>war</packaging>
    </project>

    引用额外jar包 common-io.jar

    下载文件代码:

    RequestMapping("/filedownload")
    public org.springframework.http.ResponseEntity<byte[]> filedownload() throws UnsupportedEncodingException,IOException {
      File file = new File("文件路径");
      String fileName=new String("文件名".getBytes("UTF-8"),"iso-8859-1");
      HttpHeaders headers = new HttpHeaders();
      headers.add("Content-Disposition", "attachment;filename="+fileName);
      return new org.springframework.http.ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, HttpStatus.OK);
    }

    文件原内容:

    {"settings":{"analysis":{"analyzer":{"letterAnalyzer":{"type":"custom","tokenizer":"letter"}}}}, "mappings":{"my_type":{"properties":{"title": {"type":"string","analyzer":"letterAnalyzer","search_analyzer":"letterAnalyzer", "search_quote_analyzer":"letterAnalyzer"}}}}}}

    下件后文件内容:

    "eyJzZXR0aW5ncyI6eyJhbmFseXNpcyI6eyJhbmFseXplciI6eyJsZXR0ZXJBbmFseXplciI6eyJ0eXBlIjoiY3VzdG9tIiwidG9rZW5pemVyIjoibGV0dGVyIn19fX0sICJtYXBwaW5ncyI6eyJteV90eXBlIjp7InByb3BlcnRpZXMiOnsidGl0bGUiOiB7InR5cGUiOiJzdHJpbmciLCJhbmFseXplciI6ImxldHRlckFuYWx5emVyIiwic2VhcmNoX2FuYWx5emVyIjoibGV0dGVyQW5hbHl6ZXIiLCAic2VhcmNoX3F1b3RlX2FuYWx5emVyIjoibGV0dGVyQW5hbHl6ZXIifX19fX19"

    文件内容全是乱码,百度了很久没什么结果,只知道是跟HttpMessageConvert有关系。

    打开Spring源码找到AbstractMessageConverterMethodProcessor处理类的执行方法writeWithMessageConverters内容如下:

    @SuppressWarnings("unchecked")
    	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);
    
    		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) {
    					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);
    		}
    	}
    

      

    重点是这行代码messageConverter instanceof GenericHttpMessageConverter和这行messageConverter.canWrite(valueType, selectedMediaType

    HttpMessageConverter一般都继承AbstractHttpMessageConverter类,但有的HttpMessageConverter还实现了GenericHttpMessageConverter<Object>接口。

    如果实现了GenericHttpMessageConverter接口就是通用消息转换类,所有类型的消息都会尝试调用GenericHttpMessageConverter.canWrite方法。没有实现的则调用

    AbstractHttpMessageConverter的canWrite方法。如果canWrite返回true。则调用HttpMessageConverter的write方法。

    调试代码,调试结果是FastJsonHttpMessageConvertery这个类转换了返回消息。

    我的项目里使用了alibaba的FastJson,FastJson的HttpMessageConterver实现类是FastJsonHttpMessageConverter实现了GenericHttpMessageConverter<Object>接口

    package com.alibaba.fastjson.support.spring;
    
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONException;
    import com.alibaba.fastjson.JSONPObject;
    import com.alibaba.fastjson.serializer.SerializeFilter;
    import com.alibaba.fastjson.serializer.SerializerFeature;
    import com.alibaba.fastjson.support.config.FastJsonConfig;
    import com.alibaba.fastjson.util.IOUtils;
    import org.springframework.core.ResolvableType;
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.HttpInputMessage;
    import org.springframework.http.HttpOutputMessage;
    import org.springframework.http.MediaType;
    import org.springframework.http.converter.AbstractHttpMessageConverter;
    import org.springframework.http.converter.GenericHttpMessageConverter;
    import org.springframework.http.converter.HttpMessageNotReadableException;
    import org.springframework.http.converter.HttpMessageNotWritableException;
    import org.springframework.util.StringUtils;
    
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Type;
    import java.lang.reflect.TypeVariable;
    import java.nio.charset.Charset;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    /**
     * Fastjson for Spring MVC Converter.
     * <p>
     * Compatible Spring MVC version 3.2+
     *
     * @author VictorZeng
     * @see AbstractHttpMessageConverter
     * @see GenericHttpMessageConverter
     * @since 1.2.10
     * <p>
     * <p>
     * <p>
     * Supported return type:
     * </p>
     * Simple object: Object
     * <p>
     * <p>
     * With property filter :FastJsonContainer[Object]
     * </p>
     * <p>
     * Jsonp :MappingFastJsonValue[Object]
     * </p>
     * Jsonp with property filter: MappingFastJsonValue[FastJsonContainer[Object]]
     */
    
    public class FastJsonHttpMessageConverter extends AbstractHttpMessageConverter<Object>//
            implements GenericHttpMessageConverter<Object> {
    
        public static final MediaType APPLICATION_JAVASCRIPT = new MediaType("application", "javascript");
    
        private Charset charset = Charset.forName("UTF-8");
    
        @Deprecated
        protected SerializerFeature[] features = new SerializerFeature[0];
    
        @Deprecated
        protected SerializeFilter[] filters = new SerializeFilter[0];
    
        @Deprecated
        protected String dateFormat;
    
        /**
         * with fastJson config
         */
        private FastJsonConfig fastJsonConfig = new FastJsonConfig();
    
        /**
         * @return the fastJsonConfig.
         * @since 1.2.11
         */
        public FastJsonConfig getFastJsonConfig() {
            return fastJsonConfig;
        }
    
        /**
         * @param fastJsonConfig the fastJsonConfig to set.
         * @since 1.2.11
         */
        public void setFastJsonConfig(FastJsonConfig fastJsonConfig) {
            this.fastJsonConfig = fastJsonConfig;
        }
    
        /**
         * Can serialize/deserialize all types.
         */
        public FastJsonHttpMessageConverter() {
    
            super(MediaType.ALL);
        }
    
        @Deprecated
        public Charset getCharset() {
            return this.fastJsonConfig.getCharset();
        }
    
        @Deprecated
        public void setCharset(Charset charset) {
            this.fastJsonConfig.setCharset(charset);
        }
    
        @Deprecated
        public String getDateFormat() {
            return this.fastJsonConfig.getDateFormat();
        }
    
        @Deprecated
        public void setDateFormat(String dateFormat) {
            this.fastJsonConfig.setDateFormat(dateFormat);
        }
    
        @Deprecated
        public SerializerFeature[] getFeatures() {
            return this.fastJsonConfig.getSerializerFeatures();
        }
    
        @Deprecated
        public void setFeatures(SerializerFeature... features) {
            this.fastJsonConfig.setSerializerFeatures(features);
        }
    
        @Deprecated
        public SerializeFilter[] getFilters() {
            return this.fastJsonConfig.getSerializeFilters();
        }
    
        @Deprecated
        public void setFilters(SerializeFilter... filters) {
            this.fastJsonConfig.setSerializeFilters(filters);
        }
    
        @Deprecated
        public void addSerializeFilter(SerializeFilter filter) {
            if (filter == null) {
                return;
            }
    
            int length = this.fastJsonConfig.getSerializeFilters().length;
            SerializeFilter[] filters = new SerializeFilter[length + 1];
            System.arraycopy(this.fastJsonConfig.getSerializeFilters(), 0, filters, 0, length);
            filters[filters.length - 1] = filter;
            this.fastJsonConfig.setSerializeFilters(filters);
        }
    
        @Override
        protected boolean supports(Class<?> clazz) {
            return true;
        }
    
    
        public boolean canRead(Type type, Class<?> contextClass, MediaType mediaType) {
            return super.canRead(contextClass, mediaType);
        }
    
    
        public boolean canWrite(Type type, Class<?> clazz, MediaType mediaType) {
            return super.canWrite(clazz, mediaType);
        }
    
        /*
         * @see org.springframework.http.converter.GenericHttpMessageConverter#read(java.lang.reflect.Type, java.lang.Class, org.springframework.http.HttpInputMessage)
         */
        public Object read(Type type, //
                           Class<?> contextClass, //
                           HttpInputMessage inputMessage //
        ) throws IOException, HttpMessageNotReadableException {
            return readType(getType(type, contextClass), inputMessage);
        }
    
        /*
         * @see org.springframework.http.converter.GenericHttpMessageConverter.write
         */
        public void write(Object o, Type type, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
            super.write(o, contentType, outputMessage);// support StreamingHttpOutputMessage in spring4.0+
            //writeInternal(o, outputMessage);
        }
    
    
        /*
         * @see org.springframework.http.converter.AbstractHttpMessageConverter#readInternal(java.lang.Class, org.springframework.http.HttpInputMessage)
         */
        @Override
        protected Object readInternal(Class<? extends Object> clazz, //
                                      HttpInputMessage inputMessage //
        ) throws IOException, HttpMessageNotReadableException {
            return readType(getType(clazz, null), inputMessage);
        }
    
        private Object readType(Type type, HttpInputMessage inputMessage) throws IOException {
    
            try {
                InputStream in = inputMessage.getBody();
                return JSON.parseObject(in, fastJsonConfig.getCharset(), type, fastJsonConfig.getFeatures());
            } catch (JSONException ex) {
                throw new HttpMessageNotReadableException("JSON parse error: " + ex.getMessage(), ex);
            } catch (IOException ex) {
                throw new HttpMessageNotReadableException("I/O error while reading input message", ex);
            }
        }
    
        @Override
        protected void writeInternal(Object object, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
    
            ByteArrayOutputStream outnew = new ByteArrayOutputStream();
            try {
                HttpHeaders headers = outputMessage.getHeaders();
    
                //鑾峰彇鍏ㄥ眬閰嶇疆鐨刦ilter
                SerializeFilter[] globalFilters = fastJsonConfig.getSerializeFilters();
                List<SerializeFilter> allFilters = new ArrayList<SerializeFilter>(Arrays.asList(globalFilters));
    
                boolean isJsonp = false;
    
                //涓嶇煡閬撲负浠�涔堜細鏈夎繖琛屼唬鐮侊紝 浣嗘槸涓轰簡淇濇寔鍜屽師鏉ョ殑琛屼负涓�鑷达紝杩樻槸淇濈暀涓嬫潵
                Object value = strangeCodeForJackson(object);
    
                if (value instanceof FastJsonContainer) {
                    FastJsonContainer fastJsonContainer = (FastJsonContainer) value;
                    PropertyPreFilters filters = fastJsonContainer.getFilters();
                    allFilters.addAll(filters.getFilters());
                    value = fastJsonContainer.getValue();
                }
    
                //revise 2017-10-23 ,
                // 淇濇寔鍘熸湁鐨凪appingFastJsonValue瀵硅薄鐨刢ontentType涓嶅仛淇�敼 淇濇寔鏃х増鍏煎�銆�
                // 浣嗘槸鏂扮殑JSONPObject灏嗚繑鍥炴爣鍑嗙殑contentType锛歛pplication/javascript 锛屼笉瀵规槸鍚︽湁function杩涜�鍒ゆ柇
                if (value instanceof MappingFastJsonValue) {
                    if(!StringUtils.isEmpty(((MappingFastJsonValue) value).getJsonpFunction())){
                        isJsonp = true;
                    }
                } else if (value instanceof JSONPObject) {
                    isJsonp = true;
                }
    
    
                int len = JSON.writeJSONString(outnew, //
                        fastJsonConfig.getCharset(), //
                        value, //
                        fastJsonConfig.getSerializeConfig(), //
                        //fastJsonConfig.getSerializeFilters(), //
                        allFilters.toArray(new SerializeFilter[allFilters.size()]),
                        fastJsonConfig.getDateFormat(), //
                        JSON.DEFAULT_GENERATE_FEATURE, //
                        fastJsonConfig.getSerializerFeatures());
    
                if (isJsonp) {
                    headers.setContentType(APPLICATION_JAVASCRIPT);
                }
    
                if (fastJsonConfig.isWriteContentLength()) {
                    headers.setContentLength(len);
                }
    
                outnew.writeTo(outputMessage.getBody());
    
            } catch (JSONException ex) {
                throw new HttpMessageNotWritableException("Could not write JSON: " + ex.getMessage(), ex);
            } finally {
                outnew.close();
            }
        }
    
        private Object strangeCodeForJackson(Object obj) {
            if (obj != null) {
                String className = obj.getClass().getName();
                if ("com.fasterxml.jackson.databind.node.ObjectNode".equals(className)) {
                    return obj.toString();
                }
            }
            return obj;
        }
    
        protected Type getType(Type type, Class<?> contextClass) {
            if (Spring4TypeResolvableHelper.isSupport()) {
                return Spring4TypeResolvableHelper.getType(type, contextClass);
            }
    
            return type;
        }
    
    
        private static class Spring4TypeResolvableHelper {
            private static boolean hasClazzResolvableType;
    
            static {
                try {
                    Class.forName("org.springframework.core.ResolvableType");
                    hasClazzResolvableType = true;
                } catch (ClassNotFoundException e) {
                    hasClazzResolvableType = false;
                }
            }
    
            private static boolean isSupport() {
                return hasClazzResolvableType;
            }
    
    
            private static Type getType(Type type, Class<?> contextClass) {
                if (contextClass != null) {
                    ResolvableType resolvedType = ResolvableType.forType(type);
                    if (type instanceof TypeVariable) {
                        ResolvableType resolvedTypeVariable = resolveVariable((TypeVariable) type, ResolvableType.forClass(contextClass));
                        if (resolvedTypeVariable != ResolvableType.NONE) {
                            return resolvedTypeVariable.resolve();
                        }
                    } else if (type instanceof ParameterizedType && resolvedType.hasUnresolvableGenerics()) {
                        ParameterizedType parameterizedType = (ParameterizedType) type;
                        Class<?>[] generics = new Class[parameterizedType.getActualTypeArguments().length];
                        Type[] typeArguments = parameterizedType.getActualTypeArguments();
    
                        for (int i = 0; i < typeArguments.length; ++i) {
                            Type typeArgument = typeArguments[i];
                            if (typeArgument instanceof TypeVariable) {
                                ResolvableType resolvedTypeArgument = resolveVariable((TypeVariable) typeArgument, ResolvableType.forClass(contextClass));
                                if (resolvedTypeArgument != ResolvableType.NONE) {
                                    generics[i] = resolvedTypeArgument.resolve();
                                } else {
                                    generics[i] = ResolvableType.forType(typeArgument).resolve();
                                }
                            } else {
                                generics[i] = ResolvableType.forType(typeArgument).resolve();
                            }
                        }
    
                        return ResolvableType.forClassWithGenerics(resolvedType.getRawClass(), generics).getType();
                    }
                }
    
                return type;
            }
    
            private static ResolvableType resolveVariable(TypeVariable<?> typeVariable, ResolvableType contextType) {
                ResolvableType resolvedType;
                if (contextType.hasGenerics()) {
                    resolvedType = ResolvableType.forType(typeVariable, contextType);
                    if (resolvedType.resolve() != null) {
                        return resolvedType;
                    }
                }
    
                ResolvableType superType = contextType.getSuperType();
                if (superType != ResolvableType.NONE) {
                    resolvedType = resolveVariable(typeVariable, superType);
                    if (resolvedType.resolve() != null) {
                        return resolvedType;
                    }
                }
                for (ResolvableType ifc : contextType.getInterfaces()) {
                    resolvedType = resolveVariable(typeVariable, ifc);
                    if (resolvedType.resolve() != null) {
                        return resolvedType;
                    }
                }
                return ResolvableType.NONE;
            }
        }
    
    
    }
    

      查看canWrite方法调用了AbstractHttpMessageConverter的canWrite方法:

    	@Override
    	public boolean canWrite(Class<?> clazz, MediaType mediaType) {
    		return supports(clazz) && canWrite(mediaType);
    	}
    

      AbstractHttpMessageConvertercanWrite方法里有支持supports方法

     @Override
        protected boolean supports(Class<?> clazz) {
            return true;
        }
    

      FastJsonHttpMessageConverter里的实现是直接返回true.

    这下原因找到了byte[]类型的消息由FastJsonHttpMessageConverter转换了所以内容乱码。

    解决方法重写FastJsonHttpMessageConverter排除对byte[]类型的支持。代码如下。

    public class FastJsonHttpMessageConverterImpl extends FastJsonHttpMessageConverter {
    
    	@Override
    	protected boolean supports(Class<?> clazz) {
    		if (clazz.equals(byte[].class)) {
    			return false;
    		}
    		return true;
    	}
    
    }
    

      

  • 相关阅读:
    C语言学习笔记(二)数据类型、常量和变量简介
    将汉字转换为汉语拼音java实现
    C语言学习笔记(四)运算符与表达式(下)
    数组的几种排序算法的实现
    C语言学习笔记(三)运算符与表达式(上)
    java实现二叉树的常见操作
    java解析Internet网页中的内容
    C语言学习笔记(六)分支程序设计
    C语言学习笔记(一)初识C语言
    C语言学习笔记(五)顺序程序设计
  • 原文地址:https://www.cnblogs.com/xtly2012/p/9759641.html
Copyright © 2011-2022 走看看