0

My spring WebInitializer class adds the dispatcher.setMultipartConfig(new MultipartConfigElement("/"))

public class WebInitializer implements WebApplicationInitializer {

    private static final String DISPATCHER_SERVLET_NAME = "dispatcher";
    private static final String DISPATCHER_SERVLET_MAPPING = "/";
    private static final Logger log = Logger.getLogger(WebInitializer.class);

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {

        AnnotationConfigWebApplicationContext ctx
            = new AnnotationConfigWebApplicationContext();
        ctx.register(AppConfig.class);
        log.debug(ctx);
        // Add the servlet mapping manually and make it initialize automatically
        ServletRegistration.Dynamic dispatcher = servletContext.addServlet(DISPATCHER_SERVLET_NAME, new     DispatcherServlet(ctx));

        dispatcher.addMapping(DISPATCHER_SERVLET_MAPPING);
        dispatcher.setLoadOnStartup(1);
        dispatcher.setMultipartConfig(new MultipartConfigElement("/"));

        EnumSet<DispatcherType> dispatcherTypes = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD);

        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setEncoding("UTF-8");
        characterEncodingFilter.setForceEncoding(true);

        FilterRegistration.Dynamic characterEncoding = servletContext.addFilter("characterEncoding", characterEncodingFilter);
        characterEncoding.addMappingForUrlPatterns(dispatcherTypes, true, "/*");

        FilterRegistration.Dynamic security = servletContext.addFilter("springSecurityFilterChain", new DelegatingFilterProxy());
        security.addMappingForUrlPatterns(dispatcherTypes, true, "/*");
        log.debug(security);       

        FilterRegistration.Dynamic sitemesh = servletContext.addFilter("sitemesh", new MySiteMeshFilter());
        sitemesh.addMappingForUrlPatterns(dispatcherTypes, true, "*.jsp");

        servletContext.addListener(new ContextLoaderListener(ctx));
    }
}

My WebMvcConfig class has a multipartResolver() method with @Bean annotation.

@EnableWebMvc
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {

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

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

    @Bean
    public InternalResourceViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new  InternalResourceViewResolver();
        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix("/WEB-INF/pages/");
        viewResolver.setSuffix(".jsp");
        log.debug(viewResolver);
        return viewResolver;
    }

    @Bean
    public SimpleMappingExceptionResolver exceptionResolver() {
        SimpleMappingExceptionResolver exceptionResolver = new SimpleMappingExceptionResolver();

        Properties exceptionMappings = new Properties();

        exceptionMappings.put("java.lang.Exception", "error/error");
        exceptionMappings.put("java.lang.RuntimeException", "error/error");

        exceptionResolver.setExceptionMappings(exceptionMappings);

        Properties statusCodes = new Properties();

        statusCodes.put("error/404", "404");
        statusCodes.put("error/error", "500");

        exceptionResolver.setStatusCodes(statusCodes);

        log.debug(exceptionResolver);
        return exceptionResolver;
    }

    @Bean    
    public CommonsMultipartResolver multipartResolver(){
        CommonsMultipartResolver cmr = new CommonsMultipartResolver();
        cmr.setDefaultEncoding("UTF-8");
        cmr.setMaxUploadSize(-1);
        return cmr;
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
           registry.addResourceHandler("/static/**").addResourceLocations("/static/");
        log.debug(registry);
    }
}

The AppConfig class is used to just for importing necessary configuartion classes.

@Configuration
@ComponentScan(basePackages = {"edu.indstate.ics.transcript"})
@Import(value = {WebMvcConfig.class, SecurityConfig.class,  DataConfig.class})
public class AppConfig {

}

UploadedFile class

public class UploadedFile {

    private MultipartFile uploadedFile;
    private String name = null;

    public MultipartFile getUploadedFile() {
        return uploadedFile;
    }

    public void setUploadedFile(MultipartFile uploadedFile) {
        this.uploadedFile = uploadedFile;
        this.name = uploadedFile.getOriginalFilename();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Edited uploadXML.jsp and added missing encyte attribute

2nd Edit added modelAttribute="uploadedFile"

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>

<div class="modal fade" id="uploadXMLTranscript" tabindex="-1" role="dialog" aria-hidden="true">
    <form:form  id="uploadXMLTranscriptForm" method="POST" modelAttribute="uploadedFile" enctype='multipart/form-data' action="uploadXMLTranscript?${_csrf.parameterName}=${_csrf.token}">        
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times; </span></button>
                    <h4 class="modal-title">Upload XML Transcript</h4>
                </div>
                <div class="modal-body">
                    <p>
                    <div class="input-group">
                        <label for="file">Transcript Id: </label> 
                        <input id="file" type="file" name="uploadedFile" accept="text/xml" /> 
                    </div>
                    </p>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                    <input type="submit" class="btn btn-primary" >Upload</input>
                </div>
            </div><!-- /.modal-content -->
        </div><!-- /.modal-dialog -->
    </form:form>
</div><!-- /.modal -->

and finally the controller class updated added @ModelAttribute instead of @RequestParam

@Controller 
public class TranscriptUploadController   {

    private static final Logger logger =   Logger.getLogger(TranscriptUploadController.class);   

    @Autowired
    private TranscriptBo transcriptBo;    

    @RequestMapping(value = {"/", "/secure/uploadXMLTranscript**"}, method = RequestMethod.POST)
    public String uploadXMLTranscript(@ModelAttribute("uploadedFile") UploadedFile file, ModelMap model) {
        String userName = (String)     SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        TranscriptStatusCounts transStatCount = transcriptBo.findTranscriptStatusCount();

        logger.debug(file);

        model.addAttribute("uploadedFile", new UploadedFile());
        model.addAttribute("transStatCount", transStatCount);
        model.addAttribute("userName", userName);

        logger.debug("Preparing to transform uploadedFile object = " + file);   

        List<Swbhxml> transcripts = new ArrayList<>();
//        transcripts.add(transcript);

        model.addAttribute("transcripts", transcripts);
        model.addAttribute("headerTitle", "Search by Transcript Last Name Results");    

        if (null != transcripts && transcripts.size() > 0) {
            model.addAttribute("transcript", transcripts.get(0));
        } else {
            model.addAttribute("transcript", new Swbhxml());
        }

        return "secure/transcript/viewStudentTranscript";
    } 
}

I have been messing with this for a while and appreciate any assistance.

Thanks!

EDITED I saw I was missing encyte attribute on the form tag...

But now the error has changed to:

    org.springframework.web.bind.MissingServletRequestParameterException: Required UploadedFile parameter 'uploadedFile' is not present

So...not sure what this means, I mean my controller method has the @RequestParam("uploadedFile") UploadedFile file

AND updated that to @ModelAttribute which now allows controller method to be hit...however, the UploadedFile object properties are null meaning that MultipartFile property is not being set...

addition edit added modelAttribute="uploadedFile" to form tag... still looks like custom model UploadedFile property is not binding to MultipartFile

Any ideas?

9
  • @Marc... I see stackoverflow lists an edit you made but I don't see it...oh, ok you added Java tag Commented Mar 31, 2015 at 18:22
  • 1
    Just added the java tag because there are only a few people subscribed to the spring-mvc tag Commented Mar 31, 2015 at 18:25
  • Try adding enctype="multipart/form-data" to your form definition and give it a try. Also i would use @ModelAttribute instead of @RequestParam in the controller to map to the object. Commented Mar 31, 2015 at 18:57
  • @minion yeah, I just updated my post about that... let me try the @ModelAttribute Commented Mar 31, 2015 at 19:00
  • @Minion...I made the @ModelAttribute change and it hits the controller but the properties inside UploadedFile are null like the MultipartFile field. Any ideas? Commented Mar 31, 2015 at 19:06

1 Answer 1

1

Based on the chat discussion.

The user had two multipart resolvers configured. One that comes with servlet 3.0 container and another using commons-io.

Removing the dispatcher.setMultipartConfig(new MultipartConfigElement("/")); resolved the issue.

Sign up to request clarification or add additional context in comments.

1 Comment

thanks for taking the time yesterday to help find this! Great work!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.