SpringCloud folder upload solution

1. Project research

Because you need to study the problem of uploading breakpoints. After a long search, I finally found a better project.

 

On GoogleCode, the code is very inconvenient to get down. It is better to configure the hosts and upload the code to github again.

 

https://github.com/freewebsys/java-large-file-uploader-demo

 

effect:

 

During upload, the progress, time, and percentage are displayed.

 

Description: 20141113102839281.png

Click [Pause] to pause, and click [Resume] to continue.

 

Description: 20141113102836532.png

2. Code analysis

Original project:

 

https://code.google.com/p/java-large-file-uploader/

 

This project was last updated in 2012. The project was packaged and used the simplest method to achieve http breakpoint upload.

 

Because HTML5 has a class library for reading file split files, it can support breakpoint uploads, so this can only be displayed on browsers supported by HTML5.

 

At the same time, cr32 is used in both js and java for file block verification to ensure correct data upload.

 

The code is using the latest servlet 3.0 API, using asynchronous execution, monitoring and other methods.

 

Upload class UploadServlet

@Component("javaLargeFileUploaderServlet")

@WebServlet(name = "javaLargeFileUploaderServlet", urlPatterns = { "/javaLargeFileUploaderServlet" })

public class UploadServlet extends HttpRequestHandlerServlet

        implements HttpRequestHandler {

  

    private static final Logger log = LoggerFactory.getLogger(UploadServlet.class);

  

    @Autowired

    UploadProcessor uploadProcessor;

  

    @Autowired

    FileUploaderHelper fileUploaderHelper;

  

    @Autowired

    ExceptionCodeMappingHelper exceptionCodeMappingHelper;

  

    @Autowired

    Authorizer authorizer;

  

    @Autowired

    StaticStateIdentifierManager staticStateIdentifierManager;

  

  

  

    @Override

    public void handleRequest(HttpServletRequest request, HttpServletResponse response)

            throws IOException {

        log.trace("Handling request");

  

        Serializable jsonObject = null;

        try {

            // extract the action from the request

            UploadServletAction actionByParameterName =

                    UploadServletAction.valueOf(fileUploaderHelper.getParameterValue(request, UploadServletParameter.action));

  

            // check authorization

            checkAuthorization(request, actionByParameterName);

  

            // then process the asked action

            jsonObject = processAction(actionByParameterName, request);

  

  

            // if something has to be written to the response

            if (jsonObject != null) {

                fileUploaderHelper.writeToResponse(jsonObject, response);

            }

  

        }

        // If exception, write it

        catch (Exception e) {

            exceptionCodeMappingHelper.processException(e, response);

        }

  

    }

  

  

    private void checkAuthorization(HttpServletRequest request, UploadServletAction actionByParameterName)

            throws MissingParameterException, AuthorizationException {

  

        // check authorization

        // if its not get progress (because we do not really care about authorization for get

        // progress and it uses an array of file ids)

        if (!actionByParameterName.equals(UploadServletAction.getProgress)) {

  

            // extract uuid

            final String fileIdFieldValue = fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId, false);

  

            // if this is init, the identifier is the one in parameter

            UUID clientOrJobId;

            String parameter = fileUploaderHelper.getParameterValue(request, UploadServletParameter.clientId, false);

            if (actionByParameterName.equals(UploadServletAction.getConfig) && parameter != null) {

                clientOrJobId = UUID.fromString(parameter);

            }

            // if not, get it from manager

            else {

                clientOrJobId = staticStateIdentifierManager.getIdentifier();

            }

  

              

            // call authorizer

            authorizer.getAuthorization(

                    request,

                    actionByParameterName,

                    clientOrJobId,

                    fileIdFieldValue != null ? getFileIdsFromString(fileIdFieldValue).toArray(new UUID[] {}) : null);

  

        }

    }

  

  

    private Serializable processAction(UploadServletAction actionByParameterName, HttpServletRequest request)

            throws Exception {

        log.debug("Processing action " + actionByParameterName.name());

  

        Serializable returnObject = null;

        switch (actionByParameterName) {

            case getConfig:

                String parameterValue = fileUploaderHelper.getParameterValue(request, UploadServletParameter.clientId, false);

                returnObject =

                        uploadProcessor.getConfig(

                                parameterValue != null ? UUID.fromString(parameterValue) : null);

                break;

            case verifyCrcOfUncheckedPart:

                returnObject = verifyCrcOfUncheckedPart(request);

                break;

            case prepareUpload:

                returnObject = prepareUpload(request);

                break;

            case clearFile:

                uploadProcessor.clearFile(UUID.fromString(fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId)));

                break;

            case clearAll:

                uploadProcessor.clearAll();

                break;

            case pauseFile:

                List<UUID> uuids = getFileIdsFromString(fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId));

                uploadProcessor.pauseFile (uuids);

                break;

            case resumeFile:

                returnObject =

                        uploadProcessor.resumeFile(UUID.fromString(fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId)));

                break;

            case setRate:

                uploadProcessor.setUploadRate(UUID.fromString(fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId)),

                        Long.valueOf(fileUploaderHelper.getParameterValue(request, UploadServletParameter.rate)));

                break;

            case getProgress:

                returnObject = getProgress(request);

                break;

        }

        return returnObject;

    }

  

  

    List<UUID> getFileIdsFromString(String fileIds) {

        String[] splittedFileIds = fileIds.split(",");

        List<UUID> uuids = Lists.newArrayList();

        for (int i = 0; i < splittedFileIds.length; i++) {

            uuids.add(UUID.fromString(splittedFileIds[i]));

        } 

        return uuids;

    }

  

  

    private Serializable getProgress(HttpServletRequest request)

            throws MissingParameterException {

        Serializable returnObject;

        String[] ids =

                new gson ()

                        .fromJson(fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId), String[].class);

        Collection<UUID> uuids = Collections2.transform(Arrays.asList(ids), new Function<String, UUID>() {

  

            @Override

            public UUID apply(String input) {

                return UUID.fromString(input);

            }

  

        });

        returnObject = Maps.newHashMap();

        for (UUID fileId : uuids) {

            try {

                ProgressJson progress = uploadProcessor.getProgress(fileId);

                ((HashMap<String, ProgressJson>) returnObject).put(fileId.toString(), progress);

            }

            catch (FileNotFoundException e) {

                log.debug("No progress will be retrieved for " + fileId + " because " + e.getMessage());

            }

        }

        return returnObject;

    }

  

  

    private Serializable prepareUpload(HttpServletRequest request)

            throws MissingParameterException, IOException {

  

        // extract file information

        PrepareUploadJson [] fromJson =

                new gson ()

                        .fromJson(fileUploaderHelper.getParameterValue(request, UploadServletParameter.newFiles), PrepareUploadJson[].class);

  

        // prepare them

        final HashMap<String, UUID> prepareUpload = uploadProcessor.prepareUpload(fromJson);

  

        // return them

        return Maps.newHashMap(Maps.transformValues(prepareUpload, new Function<UUID, String>() {

  

            public String apply(UUID input) {

                return input.toString();

            };

        }));

    }

  

  

    private Boolean verifyCrcOfUncheckedPart(HttpServletRequest request)

            throws IOException, MissingParameterException, FileCorruptedException, FileStillProcessingException {

        UUID fileId = UUID.fromString(fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId));

        try {

            uploadProcessor.verifyCrcOfUncheckedPart(fileId,

                    fileUploaderHelper.getParameterValue(request, UploadServletParameter.crc));

        }

        catch (InvalidCrcException e) {

            // no need to log this exception, a fallback behaviour is defined in the

            // throwing method.

            // but we need to return something!

            return Boolean.FALSE;

        }

        return Boolean.TRUE;

    }

}

 

Asynchronous upload UploadServletAsync

 

@Component("javaLargeFileUploaderAsyncServlet")

@WebServlet(name = "javaLargeFileUploaderAsyncServlet", urlPatterns = { "/javaLargeFileUploaderAsyncServlet" }, asyncSupported = true)

public class UploadServletAsync extends HttpRequestHandlerServlet

        implements HttpRequestHandler {

  

    private static final Logger log = LoggerFactory.getLogger(UploadServletAsync.class);

  

    @Autowired

    ExceptionCodeMappingHelper exceptionCodeMappingHelper;

  

    @Autowired

    UploadServletAsyncProcessor uploadServletAsyncProcessor;

      

    @Autowired

    StaticStateIdentifierManager staticStateIdentifierManager;

  

    @Autowired

    StaticStateManager<StaticStatePersistedOnFileSystemEntity> staticStateManager;

   

    @Autowired

    FileUploaderHelper fileUploaderHelper;

  

    @Autowired

    Authorizer authorizer;

  

    /**

     * Maximum time that a streaming request can take.<br>

     */

    private long taskTimeOut = DateUtils.MILLIS_PER_HOUR;

  

  

    @Override

    public void handleRequest(final HttpServletRequest request, final HttpServletResponse response)

            throws ServletException, IOException {

  

        // process the request

        try {

  

            //check if uploads are allowed

            if (!uploadServletAsyncProcessor.isEnabled()) {

                throw new UploadIsCurrentlyDisabled();

            }

              

            // extract stuff from request

            final FileUploadConfiguration process = fileUploaderHelper.extractFileUploadConfiguration(request);

  

            log.debug("received upload request with config: "+process);

  

            // verify authorization

            final UUID clientId = staticStateIdentifierManager.getIdentifier();

            authorizer.getAuthorization(request, UploadServletAction.upload, clientId, process.getFileId());

  

            //check if that file is not paused

            if (uploadServletAsyncProcessor.isFilePaused(process.getFileId())) {

                log.debug("file "+process.getFileId()+" is paused, ignoring async request.");

                return;

            }

              

            // get the model

            StaticFileState fileState = staticStateManager.getEntityIfPresent().getFileStates().get(process.getFileId());

            if (fileState == null) {

                throw new FileNotFoundException("File with id " + process.getFileId() + " not found");

            }

  

            // process the request asynchronously

            final AsyncContext asyncContext = request.startAsync();

            asyncContext.setTimeout(taskTimeOut);

  

  

            // add a listener to clear bucket and close inputstream when process is complete or

            // with

            // error

            asyncContext.addListener(new UploadServletAsyncListenerAdapter(process.getFileId()) {

  

                @Override

                void clean() {

                    log.debug("request " + request + " completed.");

                    // we do not need to clear the inputstream here.

                    // and tell processor to clean its shit!

                    uploadServletAsyncProcessor.clean(clientId, process.getFileId());

                }

            });

  

            // then process

            uploadServletAsyncProcessor.process(fileState, process.getFileId(), process.getCrc(), process.getInputStream(),

                    new WriteChunkCompletionListener() {

   

                        @Override

                        public void success() {

                            asyncContext.complete();

                        }

  

  

                        @Override

                        public void error(Exception exception) {

                            // handles a stream ended unexpectedly , it just means the user has

                            // stopped the

                            // stream

                            if (exception.getMessage() != null) {

                                if (exception.getMessage().equals("Stream ended unexpectedly")) {

                                    log.warn("User has stopped streaming for file " + process.getFileId());

                                }

                                else if (exception.getMessage().equals("User cancellation")) {

                                    log.warn("User has cancelled streaming for file id " + process.getFileId());

                                    // do nothing

                                }

                                else {

                                    exceptionCodeMappingHelper.processException(exception, response);

                                }

                            }

                            else {

                                exceptionCodeMappingHelper.processException(exception, response);

                            }

  

                            asyncContext.complete();

                        }

  

                    });

        }

        catch (Exception e) {

            exceptionCodeMappingHelper.processException(e, response);

        }

  

    }

  

}

 

 

3. Request flow chart:

 

The main idea is to split the file and upload it in chunks.

Description: 20141113114708718.jpg

For detailed reference information, you can search online for "up6 large file upload control"

Welcome to join the group to discuss: 374992201

Guess you like

Origin www.cnblogs.com/songsu/p/12721534.html