1

I am having a problem uploading files using ExtJS with Spring 4.0.5 with RepositoryRestMVC functionality.

Briefly, I have a form created by ExtJS and submits the POST request to Spring MVC backend.

I have setup Spring using java config, no xml files.

Here is my ApplicationInitializer.class in Spring:

public class ApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

private int maxUploadSizeInMb = 5 * 1024 * 1024; // 5 MB

@Override
protected Class<?>[] getRootConfigClasses() {
    return new Class<?>[]{RootConfig.class};
}

@Override
protected Class<?>[] getServletConfigClasses() {
    return new Class<?>[]{};
}

@Override
protected String[] getServletMappings() {
    return new String[]{"/"};
}

@Override
protected Filter[] getServletFilters() {
    return new Filter[]{new HiddenHttpMethodFilter(), new MultipartFilter()};
}

@Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {        
    File uploadDirectory = RootConfig.APP_STORAGE_UPLOADS_DIRECTORY;

    MultipartConfigElement multipartConfigElement = new MultipartConfigElement(
            uploadDirectory.getAbsolutePath(), maxUploadSizeInMb,
            maxUploadSizeInMb * 2, maxUploadSizeInMb / 2);
    registration.setMultipartConfig(multipartConfigElement);
}

}

Here is my WebMvcConfig.class:

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.app.controller")
public class WebMvcConfig extends WebMvcConfigurerAdapter { 

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**").addResourceLocations("/resources/").setCachePeriod(31556926);
        registry.addResourceHandler("/js/**").addResourceLocations("/js/");
     }

    @Bean
    public InternalResourceViewResolver getInternalResourceViewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/");
        resolver.setSuffix(".html");
        return resolver;
    }

    @Bean
    public CommonsMultipartResolver multipartResolver() {       
        System.out.println("===========>>> DispatcherCOntext multipartResolver Called:");
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
        multipartResolver.setMaxUploadSize(7000000);
        return multipartResolver;
    }

}

Here is the FileUploadController.class:

@Controller
public class FileUploadController {

    private final Logger LOG = LoggerFactory.getLogger(getClass());

    @RequestMapping(value="/user/{id}/photo", method=RequestMethod.POST)
    public @ResponseBody List<UploadedFile> upload(
        @RequestParam("file") MultipartFile file) {
        // Do custom steps here
       // i.e. Save the file to a temporary location or database
        LOG.debug("Writing file to disk...done");

        List<UploadedFile> uploadedFiles = new ArrayList<UploadedFile>();
        UploadedFile u = new UploadedFile(file.getOriginalFilename(),
            Long.valueOf(file.getSize()).intValue(),
            "http://localhost:8080/AppPhoto/resources/"+file.getOriginalFilename());

        uploadedFiles.add(u);
        return uploadedFiles;
    }
}

UploadedFile.class Looks like this:

public class UploadedFile implements Serializable {

    private static final long serialVersionUID = -38331060124340967L;
    private String name;
    private Integer size;
    private String url;
    private String thumbnail_url;
    private String delete_url;
    private String delete_type;

    public UploadedFile() {
        super();
    }

    public UploadedFile(String name, Integer size, String url) {
        super();
        this.name = name;
        this.size = size;
        this.url = url;
    }

    public UploadedFile(String name, Integer size, String url,
        String thumbnail_url, String delete_url, String delete_type) {
        super();
        this.name = name;
        this.size = size;
        this.url = url;
        this.thumbnail_url = thumbnail_url;
        this.delete_url = delete_url;
        this.delete_type = delete_type;
    }

    //getter and setters

    @Override
    public String toString() {
        return "UploadedFile [name=" + name + ", size=" + size + ", url=" + url
            + ", thumbnail_url=" + thumbnail_url + ", delete_url="
            + delete_url + ", delete_type=" + delete_type + "]";
    }

}

Lets first look at the ExtJS upload form is as follow:

Ext.define('FHR.view.MyForm11', {
extend: 'Ext.form.Panel',
requires: [
    'Ext.form.field.File',
    'Ext.toolbar.Toolbar',
    'Ext.button.Button'
],
title: 'My Form',
url:'user/1/photo',
initComponent: function() {
    var me = this;
    Ext.applyIf(me, {
        items: [
            {
                xtype: 'filefield',
                anchor: '100%',
                fieldLabel: 'Profile Photo',
                name: 'file',
                allowBlank: false
            }
        ],
        dockedItems: [
            {
                xtype: 'toolbar',
                dock: 'bottom',
                items: [
                    {
                        xtype: 'button',
                        handler: function(button, e) {   
                            var form = button.up('form').getForm();
                            if (form.isValid()) {
                                form.submit({
                                    success: function(form, action) {
                                        // show message alert box
                                    },
                                    failure: function(form, action) {
                                        // show message alert box
                                    }
                                });
                            } else { // display error alert if the data is invalid
                               // show message alert box
                            }
                        },
                        text: 'Upload'
                    }
                ]
            }
        ]
    });

Here is the Problem

On submission of the POST request, I get a 400 Bad request Response

Required MultipartFile parameter 'file' is not present

Any form of assistance will be appreciated.

May the Force be with you

OchiengOlanga
  • 135
  • 1
  • 3
  • 11

1 Answers1

0

I got rid of the Upload configs in the ApplicationInitializer class and instead created an upload xml config....which apparently worked despite wanting to use Java config only. Find below upload config xml

<?xml  version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
    http://www.springframework.org/schema/context" http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="7000000" />
</bean>   

OchiengOlanga
  • 135
  • 1
  • 3
  • 11