使用 Spring 处理带附件的表单提交时出现问题

问题描述 投票:0回答:0

我在处理带有附件的提交时遇到问题。例如,我收到错误:HTTP 状态 400 – 错误请求

输入状态报告

描述 由于被认为是客户端错误的原因(例如,格式错误的请求语法、无效的请求消息帧或欺骗性的请求路由),服务器无法或不会处理请求。然而,每当我在表单提交中包含附件路径时,一旦我将其从表单中删除,表单就会完美提交。我知道问题是我没有正确处理表格,我只是无法理解它。

<form:form method="POST" action="create" modelAttribute="ticket" enctype="multipart/form-data">
<form:label path="customerName">Customer Name:</form:label>
<form:input path="customerName"/><br>
<form:label path="subject">Subject:</form:label>
<form:input path="subject"/><br>
<form:label path="body">Body:</form:label>
<form:textarea path="body"/><br>
<form:label path="attachment">Attachment:</form:label>
<form:input type="file" path="attachment"/><br>
<input type="submit" value="Create"></form:form>

这是我的 TicketController:

package com.example.calebabbottcustomersupport;

import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

@Controller
@RequestMapping("/tickets")
public class TicketController {

    private Map<Integer, Ticket> ticketMap = new HashMap<>();
    private AtomicInteger ticketIdGenerator = new AtomicInteger(1);

    @GetMapping("/list")
    public ModelAndView listTickets() {
        Map<Integer, Ticket> tickets = ticketMap;
        Map<Integer, Boolean> hasAttachmentsMap = new LinkedHashMap<>();

        for (Ticket ticket : tickets.values()) {
            boolean hasAttachments = !ticket.getAllAttachments().isEmpty();
            hasAttachmentsMap.put(ticket.getId(), hasAttachments);
        }

        ModelAndView modelAndView = new ModelAndView("home");
        modelAndView.addObject("tickets", tickets.values());
        modelAndView.addObject("hasAttachmentsMap", hasAttachmentsMap);
        return modelAndView;
    }
    @GetMapping("/view/{id}")
    public String viewTicket(@PathVariable int id, Model model) {
        Ticket ticket = ticketMap.get(id);
        if (ticket != null) {
            model.addAttribute("ticket", ticket);
            return "ticketview";
        } else {
            throw new TicketNotFoundException();
        }
    }

    @GetMapping("/form")
    public String showTicketForm(Model model) {
        model.addAttribute("ticket", new Ticket());
        return "ticketform";
    }

    @PostMapping("/create")
    public String createTicket(@ModelAttribute("ticket") Ticket ticket) throws IOException {
        if (ticket.getCustomerName() != null && ticket.getSubject() != null && ticket.getBody() != null) {
            ticket.setId(ticketIdGenerator.getAndIncrement());

            MultipartFile file = ticket.getAttachment();
            if (file != null && !file.isEmpty()) {
                Attachment attachment = new Attachment(file.getOriginalFilename(), file.getBytes());
                ticket.addAttachment(attachment);
            }

            ticketMap.put(ticket.getId(), ticket);
            return "redirect:list";
        } else {
            throw new InvalidTicketException();
        }
    }

    @GetMapping("/download/{id}/{attachmentIndex}")
    public String downloadAttachment(@PathVariable int id, @PathVariable int attachmentIndex, Model model) {
        Ticket ticket = ticketMap.get(id);
        if (ticket != null) {
            Map<Integer, Attachment> attachments = ticket.getAllAttachments();
            Attachment attachment = attachments.get(attachmentIndex);
            if (attachment != null) {
                model.addAttribute("attachment", attachment);
                return "attachment";
            } else {
                throw new AttachmentNotFoundException();
            }
        } else {
            throw new TicketNotFoundException();
        }
    }

    @ResponseStatus(HttpStatus.NOT_FOUND)
    public static class TicketNotFoundException extends RuntimeException {
        public TicketNotFoundException() {
            super("Ticket not found");
        }
    }

    @ResponseStatus(HttpStatus.NOT_FOUND)
    public static class AttachmentNotFoundException extends RuntimeException {
        public AttachmentNotFoundException() {
            super("Attachment not found");
        }
    }

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public static class InvalidTicketException extends RuntimeException {
        public InvalidTicketException() {
            super("Invalid ticket information");
        }

    }
}


这是我的 Ticket 类,用于存储票证信息:

package com.example.calebabbottcustomersupport;

import org.springframework.web.multipart.MultipartFile;
import java.util.HashMap;
import java.util.Map;

public class Ticket {
    private int id;
    private String customerName;
    private String subject;
    private String body;
    private MultipartFile attachment;
    private Map<Integer, Attachment> attachments;
    private byte[] attachmentContent;

    // Add a no-argument constructor
    public Ticket() {
        this.attachments = new HashMap<>();
    }

    public byte[] getAttachmentContent() {
        return attachmentContent;
    }

    public void setAttachmentContent(byte[] attachmentContent) {
        this.attachmentContent = attachmentContent;
    }

    public Ticket(int id, String customerName, String subject, String body) {
        this.id = id;
        this.customerName = customerName;
        this.subject = subject;
        this.body = body;
        this.attachments = new HashMap<>();
    }

    public Ticket(String customerName, String subject, String body) {
        this.customerName = customerName;
        this.subject = subject;
        this.body = body;
        this.attachments = new HashMap<>();
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void addAttachment(Attachment attachment) {
        attachments.put(attachments.size() + 1, attachment);
    }

    public String getCustomerName() {
        return customerName;
    }

    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
    }

    public void addAttachment(int index, Attachment attachment) {
        attachments.put(index, attachment);
    }

    public int getNumberOfAttachments() {
        return attachments.size();
    }

    public Attachment getAttachment(int index) {
        return attachments.get(index);
    }

    public Map<Integer, Attachment> getAllAttachments() {
        return attachments;
    }

    // Add the getter and setter for the attachment field
    public MultipartFile getAttachment() {
        return attachment;
    }

    public void setAttachment(MultipartFile attachment) {
        this.attachment = attachment;
    }

    // Add toString() method for debugging and logging purposes
    @Override
    public String toString() {
        return "Ticket{" +
                "id=" + id +
                ", customerName='" + customerName + '\'' +
                ", subject='" + subject + '\'' +
                ", body='" + body + '\'' +
                ", attachments=" + attachments +
                '}';
    }
}

这是我处理附件的 Attachment 类:

package com.example.calebabbottcustomersupport;

import java.util.Arrays;

public class Attachment {
    private String name;
    private byte[] contents;

    public Attachment(String name, byte[] contents) {
        this.name = name;
        this.contents = contents;
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public byte[] getContents() {
        return contents;
    }

    public void setContents(byte[] contents) {
        this.contents = contents;
    }

    @Override
    public String toString() {
        return "Attachment{" +
                "name='" + name + '\'' +
                ", contents=" + Arrays.toString(contents) +
                '}';
    }
}

我错过了什么?如果您还需要什么,请告诉我。

forms spring-mvc multipartform-data attachment http-status-code-400
© www.soinside.com 2019 - 2024. All rights reserved.