有问题的Spring mvc文件上传问题

时间:2015-03-31 18:16:44

标签: java spring spring-mvc file-upload

我的Spring WebInitializer类添加了 dispatcher.setMultipartConfig(新的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));
    }
}

我的WebMvcConfig类有一个带有@Bean注释的 multipartResolver()方法。

@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);
    }
}

AppConfig类仅用于导入必要的configuartion类。

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

}

UploadedFile类

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;
    }
}

已修改 uploadXML.jsp 并添加了缺少的 encyte 属性

第二次修改添加了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 -->

最后控制器类已更新已添加@ModelAttribute而不是@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";
    } 
}

我一直在搞乱这一点,并感谢任何协助。

谢谢!

已编辑我看到我在表单标记上缺少 encyte 属性...

但现在错误已更改为:

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

所以......不确定这意味着什么,我的意思是我的控制器方法有@RequestParam("uploadedFile") UploadedFile文件

并将其更新为@ModelAttribute现在允许控制器方法被命中...但是,UploadedFile对象属性为空意味着MultipartFile属性未被设置...

添加修改已添加modelAttribute="uploadedFile"以形成代码...仍然看起来自定义模型UploadedFile属性未绑定到MultipartFile

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

基于聊天讨论。

用户配置了两个多部分解析器。一个是servlet 3.0容器,另一个是commons-io。

删除dispatcher.setMultipartConfig(new MultipartConfigElement("/"));解决了问题。