B / S upload large files

1, project research

Because the need to study the issue breakpoint upload. Looking for a long finally found a good project.

 

In GoogleCode above, the code to get down to super inconvenient, or configure the hosts go, re-upload the code to github above.

 

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

 

effect:

 

Upload, display progress, time and percentage.

 

Description: 20141113102839281.png

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

 

Description: 20141113102836532.png

2, code analysis

The original project:

 

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

 

This project was last updated in 2012, the project was packaged using the easiest way to achieve a breakpoint upload the http.

 

Because there are html5 library to read the file split file, so it can support the breakpoint upload, so this can only be displayed in the browser html5 support of the above.

 

Meanwhile, while a checksum for the file blocks in cr32 and js java, to ensure that the correct data upload.

 

Code using the latest servlet api 3.0 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 pause file:

                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, a flowchart of the request:

 

The main idea is to file segmentation and block the upload.

Description: 20141113114708718.jpg

Detailed reference information online search "up6 large file upload control."

Welcome to the group to discuss: 374 992 201

Guess you like

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