You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Primefaces commandButton设enctype后无法触发Bean的action方法

SpringBoot 2.7.5 + PrimeFaces 12 文件上传action不触发问题解决

问题原因

当表单设置enctype="multipart/form-data"后,Spring Boot默认的MultipartResolver会优先解析请求,导致PrimeFaces无法正确处理multipart请求,进而无法触发Bean中的parseFile方法;移除enctype则无法传递文件,导致file为null。此外,Bean的注解搭配存在问题,影响ViewScoped的正常工作。

解决方案

1. 禁用Spring Boot默认的Multipart解析

在application.properties中添加配置,让PrimeFaces自行处理multipart请求:

spring.servlet.multipart.enabled=false

2. 注册PrimeFaces的MultipartFilter

创建配置类,注册MultipartFilter并确保它在FacesServlet之前执行:

import org.primefaces.webapp.filter.MultipartFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class PrimeFacesConfig {
    @Bean
    public FilterRegistrationBean<MultipartFilter> multipartFilter() {
        FilterRegistrationBean<MultipartFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new MultipartFilter());
        registrationBean.addUrlPatterns("/*");
        registrationBean.setOrder(1);
        return registrationBean;
    }
}

3. 修正Bean的注解与字段规范

将@Component替换为CDI的@Named,并将file字段改为私有(符合JavaBean规范):

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import org.primefaces.model.UploadedFile;
import java.io.Serializable;

@Named
@ViewScoped
public class UploadFilesController implements Serializable {

    private static final long serialVersionUID = 1L;

    private UploadedFile file;

    public UploadedFile getFile() {
        System.out.println("getFile");
        return file;
    }

    public void setFile(UploadedFile file) {
        this.file = file;
        System.out.println("SET!");
    }
    
    public void parseFile() {
        if (file != null) {
            System.out.println(file.getFileName());
            FacesMessage message = new FacesMessage("Successful", file.getFileName() + " is uploaded.");
            FacesContext.getCurrentInstance().addMessage(null, message);
        } else {
            System.out.println("File is null");
        }
    }

    @PostConstruct
    public void init() {
        // 初始化逻辑
    }
}

@Named是CDI注解,与@ViewScoped搭配能保证Bean的视图作用域正常生效,避免Spring组件注解导致的作用域异常。

4. 确认页面配置(已正确设置,可忽略)

确保表单和按钮的核心配置无误:

<h:form id="form" enctype="multipart/form-data">
    <p:fileUpload value="#{uploadFilesController.file}" mode="simple" skinSimple="true"/>
    <p:commandButton value="Submit" ajax="false" action="#{uploadFilesController.parseFile}" skinSimple="true"/>
</h:form>

验证

重启应用后,选择文件点击提交,后端会打印文件名并返回成功消息,parseFile方法正常触发,文件也不会为null。

内容的提问来源于stack exchange,提问作者Kresnik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 07:45:34