简体   繁体   中英

Spring MVC not autowiring in HTTP POST, but doing in Ajax on the same controller

I have a weird situation.

I need to manage a progress-augmented upload that needs to work with ancient.ie version 9.

Upload can be only done via submitting an iframe POST, and we do that leveraging Flow js. During upload, an Ajax period request is issued to monitor the progress of the upload and fill the gauge on the UI.

Code

@Scope("request")
@PreAuthorize("hasFunction('DMS')")
@Controller("/secure/admin/pages/dms/fileRepository")
@RequestMapping("/secure/admin/pages/dms/fileRepository")
public class FileRepositoryController extends BaseController
{
    private final static Logger log = LogManager.getLogger();

    @Autowired
    private FileRepositoryManager fileRepositoryManager;
    @Autowired
    private ApplicationEventMulticaster eventDispatcher;

@RequestMapping(value = "/uploadProgress",
            method =
    {
            RequestMethod.POST,
            RequestMethod.GET
    })
    public PhoenixResponse uploadProgress(HttpSession session)
    {

        UploadInfo info = (UploadInfo) session.getAttribute(UploadInfo.SESSION_KEY);

        if (info == null)
        {
            log.warn("Upload info not found in session");
            return info().withSingleton(new UploadInfo());
        }

        PhoenixResponse res;

        switch (info.getStatus())
        {
            case DONE:
            {
                session.removeAttribute(UploadInfo.SESSION_KEY);
                res = success().withAlert("Upload OK", DEFAULT_ALERT_TIMEOUT);
                break;
            }
            case PROGRESS:
            case START:
            case PROCESSING:
            {
                res = info();
                break;
            }
            case ERROR:
            {
                res = error().withAlert("Errore upload");
                break;
            }
            default:
                throw new RuntimeException();
        }

        res = res.withSingleton(info)
                 .withResponseCode(info.getStatus()
                                       .name());

        return res;

    }

    @RequestMapping(path = "/uploadIframe",
            consumes = MediaType.MULTIPART_FORM_DATA_VALUE,
            produces = MediaType.TEXT_HTML_VALUE)
    public final @ResponseBody ResponseEntity<Void> uploadIframe(@RequestParam("file") MultipartFile file, HttpSession session)
    {
        upload(file, session); //Redirect to Ajax-ready method

        return new ResponseEntity<>(HttpStatus.OK);
    }

    @RequestMapping(value = "/upload",
            method = RequestMethod.POST,
            consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public final PhoenixResponse upload(@RequestParam("file") MultipartFile file, HttpSession session) //Requires modern browser
    {
        UploadInfo info = (UploadInfo) session.getAttribute(UploadInfo.SESSION_KEY);

        log.debug("Upload request received");

        FileUploadDTO result;

        if (file != null && !file.isEmpty())
        {

            String uploadFileName = IOUtils.getFileSafeName(file.getOriginalFilename());
            log.debug("upload file: " + uploadFileName + " user: " + getUsername());
            try
            {
                FileDescriptor fd;
                try (InputStream is = file.getInputStream())
                {
                    fd = fileRepositoryManager.store(is, uploadFileName, AdminModule.ID, getUsername());
                }
                result = new FileUploadDTO(fd.getName(), fd.getLength(), fd.getMimeType(), fd.getId());
                eventDispatcher.multicastEvent(new FileUploadEvent(this, fd));
            }
            catch (IOException | RuntimeException ex)
            {
                info.setStatus(UploadState.ERROR);
                log.error("Error uploading file", ex);
                return error().withAlert(ex.getMessage());
            }
        }
        else
            return error();

        if (info != null)
            info.setStatus(UploadState.DONE);

        return info().withSingleton(result);
    }

}

Explanation: we have two upload methods. One is Ajax-ready and the other responds on POST requests. In fact the uplodaIframe method returns a classic 200 empty page. But since the code is the same it just redirects the call to the Ajax-ready method, which return an unused response object

Problem

When invoking /uploadProgress , though it doesn't use any @Autowired bean, all autowires are set.

When invoking /uploadIframe all beans are null despite there no required=false on their autowires

I also found an interesting difference in the stack trace:

/uploadProgress

FileRepositoryController.uploadProgress(HttpSession) line: 106  
FileRepositoryController$$FastClassByCGLIB$$7ccffed3.invoke(int, Object, Object[]) line: not available  
MethodProxy.invoke(Object, Object[]) line: 204  
CglibAopProxy$CglibMethodInvocation.invokeJoinpoint() line: 720 
CglibAopProxy$CglibMethodInvocation(ReflectiveMethodInvocation).proceed() line: 157 
MethodSecurityInterceptor.invoke(MethodInvocation) line: 68 
CglibAopProxy$CglibMethodInvocation(ReflectiveMethodInvocation).proceed() line: 179 
CglibAopProxy$DynamicAdvisedInterceptor.intercept(Object, Method, Object[], MethodProxy) line: 655  
FileRepositoryController$$EnhancerBySpringCGLIB$$8768d018_2.uploadProgress(HttpSession) line: not available 
GeneratedMethodAccessor1992.invoke(Object, Object[]) line: not available    
Method.invoke(Object, Object...) line: 606  

/uploadIframe

FileRepositoryController$$EnhancerBySpringCGLIB$$8768d018_2(FileRepositoryController).upload(MultipartFile, HttpSession) line: 144  
FileRepositoryController$$EnhancerBySpringCGLIB$$8768d018_2(FileRepositoryController).uploadIframe(MultipartFile, HttpSession) line: 118    
GeneratedMethodAccessor1993.invoke(Object, Object[]) line: not available    
Method.invoke(Object, Object...) line: 606  

I didn't exactly understand why, but the problem was related to the final modifier of the two method.

Removing final had the beans autowired correctly. Kudos to @M.Deinum

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM