Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
718 views
in Technique[技术] by (71.8m points)

java - Store pictures in H2 database spring boot thymleaf

Good day. I want to store an image in an h2 database, then retrieve and display the same image in an html page. I am using spring boot and file upload method, but I am getting errors in the binding results

Here are the pages/classes:

Category.java

package com.vishal.project.entities;

@Entity
@Table(name="category")
public class Category implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
@Column(name="ID")
private Long id;

@Size(min=1, max=90)
@Column(name="CATEGORY_NAME")
private String CategoryName;


@Lob
@Column(name="CATEGORY_PHOTO")
private byte[] CategoryPhoto;


public Category(Long id, @Size(min = 1, max = 90) String categoryName, byte[] categoryPhoto) {
    super();
    this.id = id;
    CategoryName = categoryName;
    CategoryPhoto = categoryPhoto;
}

public byte[] getCategoryPhoto() {
    return CategoryPhoto;
}

public void setCategoryPhoto(byte[] categoryPhoto) {
    CategoryPhoto = categoryPhoto;
}

public Category() {}

@OneToMany(mappedBy = "category", cascade=CascadeType.ALL, orphanRemoval=true)
private Set<Book> Books = new HashSet<>();

public Set<Book> getBooks() {
    return Books;
}

public void setBooks(Set<Book> books) {
    Books = books;
}

public Long getId() {
    return id;
}
public void setCategoryID(Long id) {
    this.id = id;
}
public String getCategoryName() {
    return CategoryName;
}
public void setCategoryName(String categoryName) {
    CategoryName = categoryName;
}

@Override
public String toString() {

    return "Category ID:" + id + 
           "Category Name:"+ CategoryName;
}


}

Categorycontroller.java

package com.vishal.project.web;


import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import com.vishal.project.entities.Category;
import com.vishal.project.services.CategoryService;
import com.vishal.project.util.Message;


@Controller
@RequestMapping(value="/categories")
public class CategoryController {


private final Logger logger = LoggerFactory.getLogger(BookController.class);

@Autowired
private MessageSource  messageSource;

@Autowired 
private CategoryService categoryService;

@GetMapping
public String list(Model uiModel) {
    logger.info("Listing categories:");
    List<Category> categories = categoryService.findALL();
    uiModel.addAttribute("categories", categories);
    logger.info("No. of categories: " + categories.size());
    return "categories";
}

@GetMapping(value = "/{id}" , consumes="Multipart/formdata")
public String show(@PathVariable Long id, Model model) {
    Category category = categoryService.findbyID(id);


    model.addAttribute("category", category);
    return "showCategory";
}

@GetMapping(value = "/edit/{id}")
public String updateForm(@PathVariable Long id, Model model) {
    model.addAttribute("category", categoryService.findbyID(id));
    return "updateCategory";
}

@GetMapping(value = "/new")
public String create(Model uiModel) {
    logger.info("creating Category ...");
    Category category = new Category();     

    uiModel.addAttribute("category", category);
    return "updateCategory";
}


@PostMapping(value = "/upload")
public String saveCategory(@Valid @ModelAttribute("category") Category category, BindingResult bindingResult,
        Model uiModel, HttpServletRequest httpServletRequest, RedirectAttributes redirectAttributes,
        Locale locale, @RequestParam(value="file", required=true) MultipartFile file) {
    logger.info("Creating Category....");
    logger.info("Category ID" + category.getId());
    logger.info("Category ID" + category.getCategoryName());
    logger.info("Category ID" + category.getCategoryPhoto());
    if(bindingResult.hasErrors())
    {
        logger.info("Error:", bindingResult.getAllErrors());
        logger.debug("field Error:", bindingResult.getFieldError());
        uiModel.addAttribute("message", new Message("error", messageSource.getMessage("category_save_fail", new Object[] {}, locale)));
        uiModel.addAttribute("category", category);
        return "updateCategory";
    }
    uiModel.asMap().clear();
    redirectAttributes.addFlashAttribute("message", 
            new Message("success", messageSource.getMessage("Category_save_success", new Object[] {}, locale)));
    //process upload file 
    logger.info("File Name :", file.getName() );
    logger.info("File Size :", file.getSize() );
    logger.info("File content type :", file.getContentType() );
    if(file != null) {
    byte[] filecontent = null;
    try
    {
        InputStream inputStream = file.getInputStream();
        if(inputStream == null) 
            logger.debug("file InputStream is null");
        filecontent = IOUtils.toByteArray(inputStream);     
        category.setCategoryPhoto(filecontent);
    }catch(IOException ex) {
        logger.error("Error Saving uploaded file");
    }
    category.setCategoryPhoto(filecontent);
    }

    categoryService.save(category);
    return "redirect:/categories/" + category.getId().toString();
}

}

category Image

categoryShow.page

<body>
<div th:replace="fragments/header_admin :: header_admin">Header</div>
<div class="container">

<h1>Category Details</h1>

<div>
    <form class="form-horizontal" th:object="${category}" >
    <input type="hidden" th:field="*{id}"/>
        <div class="form-group">
            <label class="col-sm-2 control-label">Category Name:</label>
            <div class="col-sm-10">
                <p class="form-control-static" th:text="${CategoryName}"> 
</p></div>
        </div>

        <div class="form-group">
            <label class="col-sm-2 control-label" >Category Photo</label>
            <div class="col-sm-10">
                <p class="form-control-static" ><img alt="CatName" 
  th:src="@{CategoryPhoto}" /> </p></div>
        </div>
    </form>
</div>

categoryUpdate page (create or update a Category with details and image)

<div class="container">

<h1>Category Details</h1>

<div>
    <form  class="form-horizontal" th:object="${category}" th:action="@{/categories/upload}" method="post" enctype="multipart/form-data">
        <input type="hidden" th:field="*{id}"/>
        <div class="form-group">
            <label class="col-sm-2 control-label">Category Name</label>
            <div class="col-sm-10">
                <input class="form-control" th:field="*{CategoryName}"/>
            </div>
        </div>
          <div class="form-group">
            <label class="col-sm-2 control-label">Category Photo</label>
            <div class="col-sm-10">
                <input name="file" type="file" class="form-control" th:field="*{CategoryPhoto}"/>
            </div>
        </div>
        <div class="row">
            <button class="btn btn-default">Save</button>
        </div>
    </form>
</div>
<div th:insert="~{fragments/footer :: footer}">&copy; 2017 Iuliana Cosmina & Apress</div>

The error : I am getting in bindingResult of CategoryController.saveCategory() method.

When I debug the code I am getting the error. Here's a pic to demonstrate:

enter image description here

I am having a hard time showing images on the CategoryShow page using thymleaf. Any help would be appreciated.

Update: Can anyone tell me what this error means, please:

Failed to convert property value of    type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' to required type 'byte[]' for property 'CategoryPhoto'; nested exception is 
java.lang.IllegalArgumentException: Cannot convert value of type 'org.springframework.web.multipart.support.
StandardMultipartHttpServletRequest$StandardMultipartFile' to required type 'byte' for property
'CategoryPhoto[0]': PropertyEditor [org.springframework.beans.propertyeditors.CustomNumberEditor] returned 
inappropriate value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' 

**Final Update: I am getting this error : ** Required request part 'file' is not present

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

What you always can do is to compare a working file upload example with yours.

Another thing that will be helpful to compare your input names with the name your controller's method expect your file.

If your posted code is still relevant, you can find the name "Fileimport" on your file input in the template, but in your controller you expect file ( @RequestParam(value="file", required=false) ).

Other things that help you in debugging:

  • using the developer tools of the browser and see what your are sending through the network
  • log incoming requests on server side (either in this way, or it is too complicated for you, you can simply iterate through the parameter names and log them (and if possible, their values too)

If this did not help on you, then please update the post: update your code (template + controller, if changed) and give use a better stacktrace: on better I mean you should show not just the last N line of the stacktrace, but at least to the first line where the execution goes through your code (in other words the class name starts with your package), even better if the first Caused by or the second if it is meaningful) is there.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...