springMvc文件下载以及遇到的问题

最近开发需要用到一个下载功能,本人记性不好,脑主存估计只剩下索引了,无奈。

所以下载想用到spring封装好的,使用简单。于是copy到:

/**
     * 下载
     */
    @RequiresPermissions("pa:in:kpiData:view")
    @RequestMapping(value = { "/downloadAtt" })
    public ResponseEntity<byte[]> downloadAtt(Model model , HttpServletRequest request)throws Exception {
        HttpHeaders headers = new HttpHeaders();
        String url = request.getParameter("attUrl");
        int num = url.lastIndexOf("\\");
        String fileName = url.substring((num + 1), url.length());
        fileName=new String(fileName.getBytes("UTF-8"),"iso-8859-1");//为了解决一些浏览器的中文名称乱码问题
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", fileName);
        return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(new File(url)),
                headers, HttpStatus.CREATED);

    }
嗯……关键是最后三行,其余没有技术含量。

我这一看,吓一跳,因为以前给某市联通做过绩效,写过上传下载,因为是第n次开发所以代码风格很乱,我也就用了最传统的写法(我才不会告诉你当时太菜鸟,能写出功能就满意,没有甄别的实力)。当时至少还多一倍的代码行数。

spring果然牛,封装得很优雅,搞得我这种脑容量的人都觉得下载是如此简单。然后不禁看了部分源码(推荐直接看试验结果):

public class HttpHeaders implements MultiValueMap<String, String>, Serializable {
    private static final long serialVersionUID = -8578554704772377436L;
    public static final String ACCEPT = "Accept";
    public static final String ACCEPT_CHARSET = "Accept-Charset";
    public static final String ACCEPT_ENCODING = "Accept-Encoding";
    public static final String ACCEPT_LANGUAGE = "Accept-Language";
    public static final String ACCEPT_RANGES = "Accept-Ranges";
    public static final String ACCESS_CONTROL_ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials";
    public static final String ACCESS_CONTROL_ALLOW_HEADERS = "Access-Control-Allow-Headers";
    public static final String ACCESS_CONTROL_ALLOW_METHODS = "Access-Control-Allow-Methods";
    public static final String ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin";
    public static final String ACCESS_CONTROL_EXPOSE_HEADERS = "Access-Control-Expose-Headers";
    public static final String ACCESS_CONTROL_MAX_AGE = "Access-Control-Max-Age";
    public static final String ACCESS_CONTROL_REQUEST_HEADERS = "Access-Control-Request-Headers";
    public static final String ACCESS_CONTROL_REQUEST_METHOD = "Access-Control-Request-Method";
    public static final String AGE = "Age";
    public static final String ALLOW = "Allow";
    public static final String AUTHORIZATION = "Authorization";
    public static final String CACHE_CONTROL = "Cache-Control";
    public static final String CONNECTION = "Connection";
    public static final String CONTENT_ENCODING = "Content-Encoding";
    public static final String CONTENT_DISPOSITION = "Content-Disposition";
    public static final String CONTENT_LANGUAGE = "Content-Language";
    public static final String CONTENT_LENGTH = "Content-Length";
    public static final String CONTENT_LOCATION = "Content-Location";
    public static final String CONTENT_RANGE = "Content-Range";
    public static final String CONTENT_TYPE = "Content-Type";
    public static final String COOKIE = "Cookie";
    .........
哦,header封装的还算好理解。

public class ResponseEntity<T> extends HttpEntity<T> {
    private final Object statusCode;

    public ResponseEntity(HttpStatus status) {
        this((Object)null, (MultiValueMap)null, (HttpStatus)status);
    }

    public ResponseEntity(T body, HttpStatus status) {
        this(body, (MultiValueMap)null, (HttpStatus)status);
    }

    public ResponseEntity(MultiValueMap<String, String> headers, HttpStatus status) {
        this((Object)null, headers, (HttpStatus)status);
    }

    public ResponseEntity(T body, MultiValueMap<String, String> headers, HttpStatus status) {
        super(body, headers);
        Assert.notNull(status, "HttpStatus must not be null");
        this.statusCode = status;
    }.........
ResponseEntity看的有点不知所述,最后一行我传了文件实体,响应头,状态。而这里,实体和响应头交给父类方法处理,状态赋值给了本类的final常量。再看:

public class HttpEntity<T> {
    public static final HttpEntity<?> EMPTY = new HttpEntity();
    private final HttpHeaders headers;
    private final T body;

    protected HttpEntity() {
        this((Object)null, (MultiValueMap)null);
    }

    public HttpEntity(T body) {
        this(body, (MultiValueMap)null);
    }

    public HttpEntity(MultiValueMap<String, String> headers) {
        this((Object)null, headers);
    }

    public HttpEntity(T body, MultiValueMap<String, String> headers) {
        this.body = body;
        HttpHeaders tempHeaders = new HttpHeaders();
        if(headers != null) {
            tempHeaders.putAll(headers);
        }

        this.headers = HttpHeaders.readOnlyHttpHeaders(tempHeaders);
    }
这个类直接将文件实体赋值给本类final实体,响应头经过处理也同样交给本类final响应头。

看到这里似乎就结束,也没看出个所以然……以本人耐心,我没追究,接着就是试验代码是否正确,于是得到如下:




似乎没问题,然后就打开文件……然后……然后就坑爹了。文件乱码,图片打开失败!

然后只能求助度娘,某同志给出这样一个答案:

            <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
            <!-- 将Jackson2HttpMessageConverter的默认格式化输出为false -->
            <bean
                    class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>application/json;charset=UTF-8</value>
                    </list>
                </property>
                <property name="prettyPrint" value="false"/>
                <property name="objectMapper">
                    <bean class="com.csstj.plateform.common.mapper.JsonMapper"></bean>
                </property>
            </bean>
ByteArrayHttpMessageConverter放在json配置前,如果没有就添加一个。

再试果然ok了。

至于为什么,暂搁置,容我再探究下。









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值