在Spring MVC框架下利用Servlet3.0 API實現文件上傳

Servlet3.0提供了對文件上傳的原生支持,不需藉助任何第三方組件,直接使用Servlet3.0提供的API就能夠實現文件上傳功能。本文使用IDEA IDE工具,在Spring MVC框架下,基於註解映射和數據綁定編寫Java業務代碼,利用Servlet3.0 API來實現單個文件的上傳示例。

部署配置文件

MultipartConfig Servlet

在部署描述符中的DispatcherServlet中聲明賦值,使其Servlet變成MultipartConfig Servlet,具體添加以下標籤內容:

//web.xml
<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/springmvc-servlet.xml</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
    <multipart-config>
        <max-file-size>1000000</max-file-size>
    </multipart-config>
</servlet>
<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

添加原因:Spring MVC無法直接對Servlet進行註解。另一種方法是用@MultipartConfig給DispatcherServlet進行註解,效果一樣。

MultipartResolver

在Spring MVC配置文件中添加一個不同的多部分解析器,具體添加以下內容:

//springmvc.servlet.xml
<bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver">
</bean>

編寫Java代碼

Domain類

/**
 * UploadFile.java
 * 
 * @author Zero
 */

public class UploadFile implements Serializable {
    private static final long serialVersionUID = 123456789L;
    private MultipartFile multipartFile;
    private String description;

    public static long getSerialVersionUID() {
        return serialVersionUID;
    }
    public MultipartFile getMultipartFile() {
        return multipartFile;
    }
    public void setMultipartFile(MultipartFile multipartFile) {
        this.multipartFile = multipartFile;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}

Service接口與實現類

/**
 * MyFileService.java
 * 
 * @author Zero
 */

public interface MyFileService {
    //MyFileDto loadFileByGuid(String guid);
    String uploadFile(UploadFile uploadFile, String realPath);
}

//MyFileServiceImpl.java
@Service("myFileService")
public class MyFileServiceImpl implements MyFileService {
    private static final String UPLOAD_ERROR = "文件上傳出錯!";
    private static final String UPLOAD_SUCCESS = "文件上傳成功!";

    @Override
    public String uploadFile(UploadFile uploadFile, String realPath) {
        boolean loadFileVerify = false;
        MultipartFile multipartFile = uploadFile.getMultipartFile();
        String fileName = multipartFile.getOriginalFilename();
        File file = new File(realPath, fileName);
        try {
            multipartFile.transferTo(file);
            loadFileVerify = true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return loadFileVerify ? UPLOAD_SUCCESS : UPLOAD_ERROR;
    }
}

Controller類

/**
 * MyFileController.java
 * 
 * @author Zero
 */

@Controller
@RequestMapping("/public/")
public class MyFileController {

    private static Logger LOG = LoggerFactory.getLogger(FileController.class);
    private static final String UPLOAD_EMPTY = "文件爲空!";

    @Autowired
    private MyFileService fileService;

    @RequestMapping(value = "file_upload", method = RequestMethod.POST)
    public String upload(@ModelAttribute(uploadFile) @Valid UploadFile uploadFile, BindingResult result, HttpServletRequest request, Model model) {
        if (result.hasErrors()) {
            LOG.warn(UPLOAD_EMPTY);
            model.addAttribute("uploadResult", UPLOAD_EMPTY);
            return "index";
        }
        String uploadResult = fileService.uploadFile(uploadFile, request.getServletContext().getRealPath("/file"));
        model.addAttribute("uploadResult", uploadResult);
        return "index";
    }
}

編寫前端頁面代碼

編寫JSP測試表單

//index.jsp
<form action="public/file_upload" method="post" enctype="multipart/form-data">
    <h4>File Upload</h4>
    <div class="form-group">
        <label for="multipartFile">File select:</label>
        <input type="file" name="multipartFile" id="multipartFile"/>
    </div>
    <div class="form-group">
        <label for="description">File description:</label>
        <input type="text" name="description" id="description"/>
    </div>
    <div class="form-group">
        <input type="submit" value="upload"/>
        <p >${uploadResult}</p>
    </div>

</form>

注意事項

1.若BindingResult返回false,可能是domain類參數匹配不對,特別是serialVersionUID,需用idea自生成;
2.若表單post提交的multipartFile數據無法綁定到後臺對應屬性,可能是表單配置不對enctype=”multipart/form-data”。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章