我目前正在尝试从表单(名称、密码、图像)等发送数据。我正在使用 Spring Boot、JPA、Thymeleaf 和 MultipartFile,但出现以下错误:
Failed to convert property value of type
org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile
to required type byte[] for property header;
nested exception is java.lang.IllegalArgumentException:
Cannot convert value of type org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile
to required type byte for property header[0]: PropertyEditor [org.springframework.beans.propertyeditors.CustomNumberEditor]
returned inappropriate value of type org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile
在在这里发布我的问题之前,我在谷歌上进行了搜索,但找不到任何可以帮助我的东西。起初,我认为 MultipartFile 有问题,但决定摆脱 BindingResult(我用它来显示我的 thymeleaf 模板中的错误,例如密码不匹配正则表达式或某些字段没有足够的字符等)和它解决了这个问题。图片已成功上传到数据库。
但是,我想保留 BindingResult 并使其与 MultipartFile 一起使用。
这是我的代码。
我的实体(配置):
@Entity
@Table(name = "config")
public class Config {
@Id
@GeneratedValue
private int id;
@NotNull
@Size(min=4, max=50, message="le nom du restaurant doit contenir au moins 4 caractères")
private String restaurantName;
@NotNull
private String url;
@Pattern(regexp="^(?=.{8,}$)(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).*$", flags = Flag.UNICODE_CASE,
message="Le mot de passe doit contenir au moins 8 caratères dont une majuscule, une minuscule et 1 chiffre")
private String password;
private String linkColor;
private String menuColor;
private String buttonColor;
@Column(name = "header")
private byte[] header;
public String getRestaurantName() {
return restaurantName;
}
public void setRestaurantName(String restaurantName) {
this.restaurantName = restaurantName;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getLinkColor() {
return linkColor;
}
public void setLinkColor(String linkColor) {
this.linkColor = linkColor;
}
public String getMenuColor() {
return menuColor;
}
public void setMenuColor(String menuColor) {
this.menuColor = menuColor;
}
public String getButtonColor() {
return buttonColor;
}
public void setButtonColor(String buttonColor) {
this.buttonColor = buttonColor;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public byte[] getHeader() {
return header;
}
public void setHeader(byte[] header) {
this.header = header;
}
}
我的配置服务:
@Service
public class ConfigService {
@Autowired
private ConfigRepository repo;
public Config getConfigById(int id) {
return repo.findById(id).orElse(null);
}
public Config getConfigByRestaurantName(String name) {
return repo.findByRestaurantName(name);
}
public String deleteConfig(int id) {
repo.deleteById(id);
return "Config has been deleted!";
}
public long configAlreadyExist() {
return repo.count();
}
public List<Config> getAll() {
return repo.findAll();
}
public Config saveConfig(Config config) {
return repo.save(config);
}
}
配置控制器:
@PostMapping("/config/add")
public String addConfig(@Valid @ModelAttribute("config") Config config, BindingResult bindingResult, @RequestParam(value="header", required=false) MultipartFile file) throws IOException {
if(bindingResult.hasErrors()) {
return "config";
}
else {
config.setHeader(file.getBytes());
service.saveConfig(config);
return "redirect:/config/confirm";
}
}
我的表格(我正在使用百里香叶):
<form action="#" th:action="@{/config/add}" th:object="${config}" method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="restaurant_name">Nom du restaurant</label>
<input type="text" th:field="*{restaurantName}"/>
<div th:if="${#fields.hasErrors('restaurantName')}" th:errors="*{restaurantName}" class="error">Restaurant Name error</div>
</div>
<div class="form-group">
<label for="url">URL du site</label>
<input type="text" class="form-control" id="url" th:field="*{url}">
</div>
<div class="form-group">
<label for="link_color">Couleur pour les liens</label>
<select class="form-control" th:field="*{linkColor}">
<option value="blue">Bleu</option>
<option value="red">Rouge</option>
<option value="yellow">Jaune</option>
<option value="green">Vert</option>
<option value="grey">Gris</option>
</select>
</div>
<div class="form-group">
<label for="menu_color">Couleur pour les menus</label>
<select class="form-control" th:field="*{menuColor}">
<option value="blue">Bleu</option>
<option value="red">Rouge</option>
<option value="yellow">Jaune</option>
<option value="green">Vert</option>
<option value="grey">Gris</option>
</select>
</div>
<div class="form-group">
<label for="button_color">Couleur pour les boutons</label>
<select class="form-control" th:field="*{buttonColor}">
<option value="blue">Bleu</option>
<option value="red">Rouge</option>
<option value="yellow">Jaune</option>
<option value="green">Vert</option>
<option value="grey">Gris</option>
</select>
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" th:field="*{password}"/>
</div>
<div th:if="${#fields.hasErrors('password')}" th:errors="*{password}" class="error">Password error</div>
<div class="form-group">
<label for="header">Header file</label>
<input type="file" class="form-control" id="header" th:field="*{header}">
<div th:if="${#fields.hasErrors('header')}" th:errors="*{header}" class="error">Header error</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
<div>
<p th:text="${error}" id="error"></p>
</div>
</form>
据我了解,在我的实体(配置)中,标头是一个字节 [](longblob),但由于 MultifilePart 以不同的格式处理我的文件,一个与我的实体中的字节 [] 不匹配的格式,这就是导致错误。
请问有什么简单的方法可以解决这个问题吗?
谢谢!
编辑:我通过使用 @InitBinder 找到了一个临时解决方法
@InitBinder
public void setAllowedFields(WebDataBinder dataBinder) {
dataBinder.setDisallowedFields("header");
}
我仍然很想知道是否有另一种方法来处理这个问题(不禁用该字段),所以我仍然可以检查文件是否为 png、jpg 等(以增加安全性)。