Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
无法在Spring中将MultipartFile转换为Blob_Spring_File_Spring Mvc_Blob_Multipartform Data - Fatal编程技术网

无法在Spring中将MultipartFile转换为Blob

无法在Spring中将MultipartFile转换为Blob,spring,file,spring-mvc,blob,multipartform-data,Spring,File,Spring Mvc,Blob,Multipartform Data,我正在尝试将上传的文件保存为MySql记录中的Blob。我是春天的新手。当我在上传文件后准备保存记录时,当我的POST方法updateCandidate()执行时,我会出现以下异常: 字段“cv”上的对象“candidateForm”中的字段错误:拒绝值[org.springframework.web.multipart.support.StandardMultipartTTPServletRequest$StandardMultipartFile@59c09df6]; 代码[typeMisma

我正在尝试将上传的文件保存为MySql记录中的Blob。我是春天的新手。当我在上传文件后准备保存记录时,当我的POST方法
updateCandidate()
执行时,我会出现以下异常:

字段“cv”上的对象“candidateForm”中的字段错误:拒绝值[org.springframework.web.multipart.support.StandardMultipartTTPServletRequest$StandardMultipartFile@59c09df6]; 代码[typeMismatch.candidateForm.cv、typeMismatch.cv、typeMismatch.java.sql.Blob、typeMismatch];参数[org.springframework.context.support.DefaultMessageSourceResolvable:代码[candidateForm.cv,cv];参数[];默认消息[cv];默认消息[未能将类型为'org.springframework.web.multipart.support.StandardMultipartTtpServletRequest$StandardMultipartFile'的属性值转换为属性'cv'所需的类型'java.sql.Blob';嵌套异常为java.lang.IllegalStateException:无法转换类型为'org.springframework.web.multipart.support.StandardMultipartTtpServlet'的值请求$StandardMultipartFile'为属性“cv”的必需类型“java.sql.Blob”:未找到匹配的编辑器或转换策略]

出了什么问题?如何修复

我的实体:

import java.sql.Blob;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;

@Entity
public class Candidate {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(unique = true)
private String ssn;
private String name;
private String surname;
private String technology;
private String media;
@Lob
private Blob cv;
private boolean activeCV;

public Long getId() {
    return id;
}
public void setId(Long id) {
    this.id = id;
}
public String getSsn() {
    return ssn;
}
public void setSsn(String ssn) {
    this.ssn = ssn;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public String getSurname() {
    return surname;
}
public void setSurname(String surname) {
    this.surname = surname;
}
public String getTechnology() {
    return technology;
}
public void setTechnology(String technology) {
    this.technology = technology;
}
public String getMedia() {
    return media;
}
public void setMedia(String media) {
    this.media = media;
}
public Blob getCv() {
    return cv;
}
public void setCv(Blob cv) {
    this.cv = cv;
}
public boolean isActiveCV() {
    return activeCV;
}
public void setActiveCV(boolean activeCV) {
    this.activeCV = activeCV;
}

}
为我服务:

@Autowired
private CandidateRepository repository;

...

public Optional<Candidate> getCandidate(Long id){
    return repository.findById(id);
}

public void addOrUpdateCandidate(Candidate candidate) {
    repository.save(candidate);
}
My updateCandidateForm.jsp:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
    <body>

        <form:form method="POST" action="updateCandidateResult" modelAttribute="candidateForm" enctype="multipart/form-data">
        <form:hidden path="id"/>
         <table>
            <tr>
                <td><form:label path="name">Name</form:label></td>
                <td><form:input path="name"/></td>
            </tr>
            <tr>
                <td><form:label path="surname">Surname</form:label></td>
                <td><form:input path="surname"/></td>
            </tr>
            <tr>
                <td><form:label path="ssn">SSN</form:label></td>
                <td><form:input path="ssn"/></td>
            </tr>
            <tr>
                <td><form:label path="technology">Known Technology</form:label></td>
                <td><form:input path="technology"/></td>
            </tr>
            <tr>
                <td><form:label path="media">Found us on</form:label></td>
                <td><form:input path="media"/></td>
            </tr>
            <tr>
                <td><form:label path="cv">Select a cv</form:label></td>
                <td><input type="file" name="cv" /></td>
            </tr>
            <tr>
                <td><form:label path="activeCV">Active CV</form:label></td>
                <td><form:checkbox path="activeCV" /></td>
            </tr>
            <tr>
                <td><input type="submit" value="Submit"/></td>
            </tr>
        </table>
    </form:form>
</body>
在controller中,现在我首先关心的是pojo是否可以正确实例化,因此我的GET-POST对是:

@GetMapping("/updateCandidate/{id}")
public String showUpdateUserForm(@PathVariable("id") Long id, Model model) {
    CandidatePOJO candidatePOJO = new CandidatePOJO();
    candidatePOJO.setId(id);
    model.addAttribute("candidateForm", candidatePOJO);
    return "updateCandidateForm";
}

@PostMapping("/updateCandidate/updateCandidateResult")
public String updateCandidate(@ModelAttribute("candidateForm") CandidatePOJO candidatePOJO) {
    System.out.println("CANDIDATE POJO");
    System.out.println(candidatePOJO.toString());   // here I notice id = null

    /* MultipartFile to Blob conversion */
    //  MultipartFile file = candidatePOJO.getCv();
    //  InputStream iStream = file.getInputStream();
    //  long size = file.getSize();
    //  Session session = emf.unwrap(Session.class);
    //  Blob cv = Hibernate.getLobCreator(session).createBlob(iStream, size);

    /* instantiating the entity object to be freezed in db */
    // Candidate candidate = new Candidate();
    // set all data from candidatePOJO..
    //      candidate.setCv(cv);

    //  service.addOrUpdateCandidate(candidate);
    return "updateCandidateResult";
}
我得到了一个没有id设置的CandidatePOJO对象。我无法获得从get到POST的id通行证。有人知道怎么了吗

编辑3: 在我选择了支持POJO的解决方案很多天后,难以置信的是,我注意到ID从GET方法传递到POST方法(我没有做任何更改,我只是执行了经典的Maven项目清理,就像我发布问题时那样)。不幸的是,我现在面临另一个例外(当然,在恢复先前在POST方法中注释的代码之后):

javax.persistence.PersistenceException:Hibernate无法将EntityManagerFactory作为“org.Hibernate.Session”展开

如何解决这个问题

编辑4: 正上方的异常已解决替换:

Session session = emf.unwrap(Session.class);
与:


通过使用SUPPORT POJO,我终于解决了问题。事实上,我之前已经通过代码解决了问题。文章中的代码是正确的(EDIT 2)。当我经常执行Maven项目清理时,这并没有发现错误。我在过去几个小时内执行了清理,我的代码工作得令人难以置信。我猜不出神奇之处:D我不知道到底发生了什么。通过代码,我用两种不同的方式解决了问题。首先:

@Autowired
private EntityManagerFactory emf;

// ........

@GetMapping("/updateCandidate/{id}")
public String showUpdateUserForm(@PathVariable("id") Long id, Model model) {
    Candidate candidate = service.getCandidate(id).get();

    CandidatePOJO candidatePOJO = new CandidatePOJO();
    candidatePOJO.setId(id);
    candidatePOJO.setName(candidate.getName());
    candidatePOJO.setSurname(candidate.getSurname());
    candidatePOJO.setSsn(candidate.getSsn());
    candidatePOJO.setMedia(candidate.getMedia());
    candidatePOJO.setTechnology(candidate.getTechnology());
    candidatePOJO.setActiveCV(candidate.isActiveCV());

    model.addAttribute("candidateForm", candidatePOJO);
    return "updateCandidateForm";
}

@PostMapping("/updateCandidate/updateCandidateResult")
public String updateCandidate(@ModelAttribute("candidateForm") CandidatePOJO candidatePOJO) throws IOException {
    MultipartFile file = candidatePOJO.getCv();
    InputStream iStream = file.getInputStream();
    long size = file.getSize();
    EntityManager em = emf.createEntityManager();
    Session session = (Session) em.getDelegate();
    Blob cv = Hibernate.getLobCreator(session).createBlob(iStream, size);

    Candidate candidate = new Candidate();
    candidate.setId(candidatePOJO.getId());
    candidate.setName(candidatePOJO.getName());
    candidate.setSurname(candidatePOJO.getSurname());
    candidate.setSsn(candidatePOJO.getSsn());
    candidate.setMedia(candidatePOJO.getMedia());
    candidate.setTechnology(candidatePOJO.getTechnology());
    candidate.setActiveCV(candidatePOJO.isActiveCV());
    candidate.setCv(cv);

    service.addOrUpdateCandidate(candidate);
    return "updateCandidateResult";
}
第二(使用相同的GET):


作为Spring的新手,我还不知道它们之间的区别。我希望有更多的解释。此外,我想修改这段代码,以摆脱对POJO的支持,只处理实体对象:如果有人能解决我最初的问题,我将永远感激!

例外说明一切:您的方法已经成功了候选对象作为参数,因此Spring应该根据请求的参数填充其属性。但它不能从您发送的多部分文件中填充Blob类型的属性。只是不要将您的持久实体用于候选表单。请使用专用类,它代表客户端发送的内容,而不是数据库行包含。我被限制使用Blob作为该字段类型。因此,如果我做得好,它会在POST开始执行时尝试转换,当它无法执行时会停止转换,因此它甚至无法详细说明我的编码转换(?。您能写一些代码吗?:)创建一个类。一个简单的POJO,包含表单发送的每个参数的getter和setter,以及相应的类型。使用该类,而不是候选类作为命令。应用必要的转换,将此命令对象中的数据复制到实体中。Hello@JBNizet,我使用了一个POJO,正如您所说的。如果我编写了corre实际上,系统抛出了相同的异常,确认了我的信念,即它不是对象的类型(实体bean,POJO)这会造成混乱。如果我确实编码错误,我想找出正确的做法。我想告诉你我是如何编辑我的GET和POST的。我不知道如何打开这里的聊天框。请原谅我可能的英语错误。谢谢,我省略了一些东西。现在它部分工作。我可以让系统实例化t他有一个候选POJO(cv类型不是Blob,而是MultipartFile),但它没有设置id,所以我的帖子检索一个未设置字段的对象
@GetMapping("/updateCandidate/{id}")
public String showUpdateUserForm(@PathVariable("id") Long id, Model model) {
    CandidatePOJO candidatePOJO = new CandidatePOJO();
    candidatePOJO.setId(id);
    model.addAttribute("candidateForm", candidatePOJO);
    return "updateCandidateForm";
}

@PostMapping("/updateCandidate/updateCandidateResult")
public String updateCandidate(@ModelAttribute("candidateForm") CandidatePOJO candidatePOJO) {
    System.out.println("CANDIDATE POJO");
    System.out.println(candidatePOJO.toString());   // here I notice id = null

    /* MultipartFile to Blob conversion */
    //  MultipartFile file = candidatePOJO.getCv();
    //  InputStream iStream = file.getInputStream();
    //  long size = file.getSize();
    //  Session session = emf.unwrap(Session.class);
    //  Blob cv = Hibernate.getLobCreator(session).createBlob(iStream, size);

    /* instantiating the entity object to be freezed in db */
    // Candidate candidate = new Candidate();
    // set all data from candidatePOJO..
    //      candidate.setCv(cv);

    //  service.addOrUpdateCandidate(candidate);
    return "updateCandidateResult";
}
Session session = emf.unwrap(Session.class);
EntityManager em = emf.createEntityManager();
Session session = (Session) em.getDelegate();
@Autowired
private EntityManagerFactory emf;

// ........

@GetMapping("/updateCandidate/{id}")
public String showUpdateUserForm(@PathVariable("id") Long id, Model model) {
    Candidate candidate = service.getCandidate(id).get();

    CandidatePOJO candidatePOJO = new CandidatePOJO();
    candidatePOJO.setId(id);
    candidatePOJO.setName(candidate.getName());
    candidatePOJO.setSurname(candidate.getSurname());
    candidatePOJO.setSsn(candidate.getSsn());
    candidatePOJO.setMedia(candidate.getMedia());
    candidatePOJO.setTechnology(candidate.getTechnology());
    candidatePOJO.setActiveCV(candidate.isActiveCV());

    model.addAttribute("candidateForm", candidatePOJO);
    return "updateCandidateForm";
}

@PostMapping("/updateCandidate/updateCandidateResult")
public String updateCandidate(@ModelAttribute("candidateForm") CandidatePOJO candidatePOJO) throws IOException {
    MultipartFile file = candidatePOJO.getCv();
    InputStream iStream = file.getInputStream();
    long size = file.getSize();
    EntityManager em = emf.createEntityManager();
    Session session = (Session) em.getDelegate();
    Blob cv = Hibernate.getLobCreator(session).createBlob(iStream, size);

    Candidate candidate = new Candidate();
    candidate.setId(candidatePOJO.getId());
    candidate.setName(candidatePOJO.getName());
    candidate.setSurname(candidatePOJO.getSurname());
    candidate.setSsn(candidatePOJO.getSsn());
    candidate.setMedia(candidatePOJO.getMedia());
    candidate.setTechnology(candidatePOJO.getTechnology());
    candidate.setActiveCV(candidatePOJO.isActiveCV());
    candidate.setCv(cv);

    service.addOrUpdateCandidate(candidate);
    return "updateCandidateResult";
}
@PostMapping("/updateCandidate/updateCandidateResult")
public String updateCandidate(@ModelAttribute("candidateForm") CandidatePOJO candidatePOJO) throws IOException, SerialException, SQLException {
    MultipartFile file = candidatePOJO.getCv();
    Blob cv = new SerialBlob(file.getBytes());

    Candidate candidate = new Candidate();
    candidate.setId(candidatePOJO.getId());
    candidate.setName(candidatePOJO.getName());
    candidate.setSurname(candidatePOJO.getSurname());
    candidate.setSsn(candidatePOJO.getSsn());
    candidate.setMedia(candidatePOJO.getMedia());
    candidate.setTechnology(candidatePOJO.getTechnology());
    candidate.setActiveCV(candidatePOJO.isActiveCV());
    candidate.setCv(cv);

    service.addOrUpdateCandidate(candidate);
    return "updateCandidateResult";
}