我正在通过Spring Form在Spring MVC 4项目中尝试上传文件,但是当我使用我的日志提交表单时说:Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@527de1e2
和Invalid CSRF token found
。
我从Spring Security Reference找到了解决方案 ,但是在Spring安全性之前放置Multipart Filter之后,我的Model Attrbute返回NULL。
这是我的代码:
JSP代码段
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<html>
<body>
<div>
<form:form action="save?${_csrf.parameterName}=${_csrf.token}"
method="post" modelAttribute="book" enctype="multipart/form-data">
<table>
<form:input type="hidden" path="id" />
<tr>
<td>ISBN:</td>
<td><form:input path="isbn" autofocus="autofocus"/></td>
</tr>
<tr>
<td>Title:</td>
<td><form:input path="title" /></td>
</tr>
<tr>
<td>Author:</td>
<td><form:input path="author" /></td>
</tr>
<tr>
<td>Publisher:</td>
<td><form:input path="publisher" /></td>
</tr>
<tr>
<td>Call Number:</td>
<td><form:input path="callNumber" /></td>
</tr>
<tr>
<td>Pages:</td>
<td><form:input path="pages" /></td>
</tr>
<tr>
<td>Pages:</td>
<td><form:input path="imageFile" type="file" /></td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="Save">
</td>
</tr>
</table>
</form:form>
</div>
模型
@Entity
@Table(name="books")
public class Book implements Serializable {
private static final long serialVersionUID = 4235334951865878125L;
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@NotNull
@NotEmpty
@Size(min = 1, max = 25)
@Column(name = "isbn")
private String isbn;
@NotNull
@NotEmpty
@Size(min = 1, max = 50)
@Column(name = "title")
private String title;
@Size(max = 50)
@Column(name = "author")
private String author;
@Size(max = 50)
@Column(name = "publisher")
private String publisher;
@Size(max = 25)
@Column(name = "call_number")
private String callNumber;
@Column(name = "pages")
private int pages;
@Column(name = "image_file")
private byte[] imageFile;
//Setter & Getter
}
Controller Snippet:
@RequestMapping(value = "/save", method = RequestMethod.POST)
@PreAuthorize("hasAnyAuthority('BOOK_ADD', 'BOOK_EDIT')")
public String saveBook(@ModelAttribute @Valid Book book, BindingResult result) {
bookValidator.validate(book, result);
if (result.hasErrors()) {
return "book/form";
}
if (bookService.getBook(book.getId()) == null) {
bookService.save(book);
} else {
bookService.update(book);
}
return "redirect:/book";
}
Servlet配置:
@Bean(name = "multipartResolver")
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setDefaultEncoding("UTF-8");
return resolver;
}
Spring Security Initializer:
@Override
protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
insertFilters(servletContext, new MultipartFilter());
}
SQL表:
CREATE TABLE `books` (
`id` INT(5) UNSIGNED NOT NULL AUTO_INCREMENT,
`isbn` VARCHAR(25) NOT NULL,
`title` VARCHAR(50) NOT NULL,
`author` VARCHAR(50) NULL DEFAULT NULL,
`publisher` VARCHAR(50) NULL DEFAULT NULL,
`call_number` VARCHAR(25) NULL DEFAULT NULL,
`pages` INT(5) NULL DEFAULT NULL,
`image_file` MEDIUMBLOB NULL,
PRIMARY KEY (`id`)
)
和使用的库Snippet:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.3.RELEASE</version>
</dependency>
<dependency.
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.0.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.0.3.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
答案 0 :(得分:1)
您可以在Book类中添加新的MultipartFile属性,就像其他人建议的那样,并使其成为瞬态。设置此属性后,也可以设置imageFile。
@Column(name = "image_file")
private byte[] imageFile;
@Transient
private MultipartFile multiPartFile;
public void setMultiPartFile(MultipartFile multiPartFile) {
this.multiPartFile = multiPartFile;
if(multiPartFile != null){
this.setImageFile(multiPartFile.getBytes());
}
}
答案 1 :(得分:0)
通过更改
来尝试 private byte[] imageFile;
到
private MultipartFile imageFile;
<强>更新强>
如果在DB中使用blob数据类型,则从前端使用MultipartFile
接收文件,然后使用byte []获得另一个getter setter。
private MultipartFile imageFileFrntEnd;
// getter
public MultipartFile setImageFileFrntEnd(MultipartFile file){
//convert to byte[] and set to imageFile
}
private byte[] imageFile;
//getter setter
答案 2 :(得分:0)
Arip Hidayat,
我认为你需要编辑一些代码。
非常简单的java + spring mvc文件上传
config .xml
<!-- MultipartResolver -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="-1" />
<property name="maxInMemorySize" value="-1" />
</bean>
<!-- BeanNameViewResolver -->
<bean id="downloadViewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver">
<property name="order">
<value>0</value>
</property>
</bean>
HTML
<form id="upload_form" action="/upload" method="POST" enctype="multipart/form-data">
<label>file : </label>
<input type="file" name="file" id="file" />
<input type="submit" value="upload" />
</form>
模型
public class MultipartFileModel {
private MultipartFile file;
//...getter, setter
}
这很重要。
输入标记名称=“文件”
模型MultipartFile变量名称=“文件”
控制器
@RequestMapping(value = "/upload")
private ModelAndView writeFile(MultipartFileModel model) {
MultipartFile multipartfile = model.getFile();
// you use "multipartfile"
// ... you write file
}