org.hsweb.web.controller.file.FileController.java Source code

Java tutorial

Introduction

Here is the source code for org.hsweb.web.controller.file.FileController.java

Source

/*
 * Copyright 2015-2016 http://hsweb.me
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.hsweb.web.controller.file;

import com.alibaba.fastjson.JSON;
import org.hsweb.commons.StringUtils;
import org.hsweb.expands.compress.Compress;
import org.hsweb.expands.compress.zip.ZIPWriter;
import org.hsweb.expands.office.excel.ExcelIO;
import org.hsweb.expands.office.excel.config.Header;
import org.hsweb.web.bean.po.resource.Resources;
import org.hsweb.web.core.authorize.annotation.Authorize;
import org.hsweb.web.core.exception.NotFoundException;
import org.hsweb.web.core.logger.annotation.AccessLogger;
import org.hsweb.web.core.message.ResponseMessage;
import org.hsweb.web.service.resource.FileService;
import org.hsweb.web.service.resource.ResourcesService;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * ??
 *
 * @author zhouhao
 * @since 1.0
 */
@RestController
@RequestMapping(value = "/file")
@AccessLogger("?")
@Authorize
public class FileController {

    private org.slf4j.Logger logger = LoggerFactory.getLogger(this.getClass());

    @Resource
    private ResourcesService resourcesService;

    @Resource
    private FileService fileService;

    //???? \ / : | ? < > "
    private static final Pattern fileNameKeyWordPattern = Pattern.compile("(\\\\)|(/)|(:)(|)|(\\?)|(>)|(<)|(\")");

    private static final Map<String, String> mediaTypeMapper = new HashMap<>();

    static {
        mediaTypeMapper.put(".png", MediaType.IMAGE_PNG_VALUE);
        mediaTypeMapper.put(".jpg", MediaType.IMAGE_JPEG_VALUE);
        mediaTypeMapper.put(".jpeg", MediaType.IMAGE_JPEG_VALUE);
        mediaTypeMapper.put(".gif", MediaType.IMAGE_GIF_VALUE);
        mediaTypeMapper.put(".bmp", MediaType.IMAGE_JPEG_VALUE);
        mediaTypeMapper.put(".json", MediaType.APPLICATION_JSON_VALUE);
        mediaTypeMapper.put(".txt", MediaType.TEXT_PLAIN_VALUE);
        mediaTypeMapper.put(".css", MediaType.TEXT_PLAIN_VALUE);
        mediaTypeMapper.put(".js", "application/javascript");
        mediaTypeMapper.put(".html", MediaType.TEXT_HTML_VALUE);
        mediaTypeMapper.put(".xml", MediaType.TEXT_XML_VALUE);
    }

    /**
     * excel
     *
     * @param name       excel??
     * @param headerJson ?JSON ?:{@link Header}
     * @param dataJson   ?JSON ?:{@link List<Map<String,Object>}
     * @param response   {@link HttpServletResponse}
     * @throws Exception   excel
     * @throws IOException excel
     */
    @RequestMapping(value = "/download/{name}.xlsx", method = { RequestMethod.POST })
    @AccessLogger("excel")
    public void downloadExcel(@PathVariable("name") String name, @RequestParam("header") String headerJson,
            @RequestParam("data") String dataJson, HttpServletResponse response) throws Exception {
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        response.setHeader("Content-disposition",
                "attachment;filename=" + URLEncoder.encode(name, "utf-8") + ".xlsx");
        List<Header> headers = JSON.parseArray(headerJson, Header.class);
        List<Map> datas = JSON.parseArray(dataJson, Map.class);
        ExcelIO.write(response.getOutputStream(), headers, (List) datas);
    }

    /**
     * zip.?POST
     *
     * @param name     ??
     * @param dataStr  ?,jsonArray. ?:[{"name":"fileName","text":"fileText"}]
     * @param response {@link HttpServletResponse}
     * @throws IOException      zip
     * @throws RuntimeException zip
     */
    @RequestMapping(value = "/download-zip/{name:.+}", method = { RequestMethod.POST })
    @AccessLogger("zip")
    public void downloadZip(@PathVariable("name") String name, @RequestParam("data") String dataStr,
            HttpServletResponse response) throws IOException {
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(name, "utf-8"));
        ZIPWriter writer = Compress.zip();
        List<Map<String, String>> data = (List) JSON.parseArray(dataStr, Map.class);
        data.forEach(map -> writer.addTextFile(map.get("name"), map.get("text")));
        writer.write(response.getOutputStream());
    }

    /**
     * ,.?GET,POST
     *
     * @param name     ??
     * @param text     
     * @param response {@link HttpServletResponse}
     * @throws IOException 
     */
    @RequestMapping(value = "/download-text/{name:.+}", method = { RequestMethod.GET, RequestMethod.POST })
    @AccessLogger("text")
    public void downloadTxt(@PathVariable("name") String name, @RequestParam("text") String text,
            HttpServletResponse response) throws IOException {
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(name, "utf-8"));
        response.getWriter().write(text);
    }

    /**
     * restful,ID?,?
     * : http://host:port/file/download/aSk2a/file.zip  IDaSk2a.??file.zip
     *
     * @param id       ID
     * @param name     ??
     * @param response {@link HttpServletResponse}
     * @param request  {@link HttpServletRequest}
     * @return , , ?
     * @throws IOException       
     * @throws NotFoundException ?
     */
    @RequestMapping(value = "/download/{id}/{name:.+}", method = RequestMethod.GET)
    @AccessLogger("")
    public ResponseMessage restDownLoad(@PathVariable("id") String id, @PathVariable("name") String name,
            HttpServletResponse response, HttpServletRequest request) throws IOException {
        return downLoad(id, name, response, request);
    }

    /**
     * ID?,?
     * : http://host:port/file/download/aSk2a/file.zip  IDaSk2a.??file.zip
     *
     * @param id       ??id
     * @param name     ??????.?(null).??
     * @param response {@link HttpServletResponse}
     * @param request  {@link HttpServletRequest}
     * @return , , ?
     * @throws IOException       
     * @throws NotFoundException ?
     */
    @RequestMapping(value = "/download/{id}", method = RequestMethod.GET)
    @AccessLogger("")
    public ResponseMessage downLoad(@PathVariable("id") String id,
            @RequestParam(value = "name", required = false) String name, HttpServletResponse response,
            HttpServletRequest request) throws IOException {
        Resources resources = resourcesService.selectByPk(id);
        if (resources == null || resources.getStatus() != 1) {
            throw new NotFoundException("?");
        } else {
            if (!"file".equals(resources.getType()))
                throw new NotFoundException("?");
            //?contentTypeapplication/octet-stream
            String contentType = mediaTypeMapper.get(resources.getSuffix().toLowerCase());
            if (contentType == null)
                contentType = "application/octet-stream";
            //????
            if (StringUtils.isNullOrEmpty(name))
                name = resources.getName();
            //????
            if (!name.contains("."))
                name = name.concat(".").concat(resources.getSuffix());
            //
            name = fileNameKeyWordPattern.matcher(name).replaceAll("");
            int skip = 0;
            long fSize = resources.getSize();
            //??
            try {
                //???
                String Range = request.getHeader("Range").replaceAll("bytes=", "").replaceAll("-", "");
                skip = StringUtils.toInt(Range);
            } catch (Exception e) {
            }
            response.setContentLength((int) fSize);//?
            response.setContentType(contentType);
            response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(name, "utf-8"));
            //try with resource
            try (BufferedInputStream inputStream = new BufferedInputStream(fileService.readResources(resources));
                    BufferedOutputStream stream = new BufferedOutputStream(response.getOutputStream())) {
                //
                if (skip > 0) {
                    inputStream.skip(skip);
                    response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
                    String contentRange = new StringBuffer("bytes ").append(skip).append("-").append(fSize - 1)
                            .append("/").append(fSize).toString();
                    response.setHeader("Content-Range", contentRange);
                }
                byte b[] = new byte[2048 * 10];
                while ((inputStream.read(b)) != -1) {
                    stream.write(b);
                }
                stream.flush();
            } catch (IOException e) {
                logger.debug(String.format("download file error%s", e.getMessage()));
                throw e;
            }
            return null;
        }

    }

    /**
     * ,?.???,{@link FileService#saveFile(InputStream, String)}?
     * ??,??:[{"id":"fileId","name":"fileName","md5":"md5"}]
     *
     * @param files 
     * @return .
     * @throws IOException ?
     */
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    @AccessLogger("")
    public ResponseMessage upload(@RequestParam("file") MultipartFile[] files) throws IOException {
        if (logger.isInfoEnabled())
            logger.info(String.format("start upload , file number:%s", files.length));
        List<Resources> resourcesList = new LinkedList<>();
        for (int i = 0; i < files.length; i++) {
            MultipartFile file = files[i];
            if (!file.isEmpty()) {
                if (logger.isInfoEnabled())
                    logger.info("start write file:{}", file.getOriginalFilename());
                String fileName = file.getOriginalFilename();
                Resources resources = fileService.saveFile(file.getInputStream(), fileName);
                resourcesList.add(resources);
            }
        } //????
        return ResponseMessage.ok(resourcesList).include(Resources.class, "id", "name", "md5");
    }

}