2015-01-21 14 views
6

Tôi cần tạo phương thức trong Spring MVC có thể xử lý cả hai yêu cầu JSON và Multipart Form.Dịch vụ REST có thể sử dụng cả JSON và Multipart Form

Đây là phương pháp chữ ký của tôi:

@RequestMapping(value = { "/upload_image" }, method = RequestMethod.POST) 
public @ResponseBody void uploadImage(final ImageDTO image) 

lớp ImageDTO trông như sau:

public class ImageDTO { 
    private String imageUrl; 
    private Long imageId; 
    private MultipartFile image; 

    public String getImageUrl() { 
    return imageUrl; 
    } 

    public void setImageUrl(final String url) { 
    this.imageUrl = url; 
    } 

    public Long getImageId() { 
    return imageId; 
    } 

    public void setImageId(final Long imageId) { 
    this.imageId = imageId; 
    } 

    public MultipartFile getImage() { 
    return image; 
    } 

    public void setImage(MultipartFile image) { 
    this.image = image; 
    } 
} 

Vì vậy, kịch bản là tôi cần phải hỗ trợ hai kịch bản: 1. Hình ảnh lên tải từ hình thức , trong đó Content-Type là multipart-form (tất cả các thành viên DTO không rỗng) 2. Tải lên hình ảnh bằng JSON, chỉ sử dụng imageUrl. Trong trường hợp này, cơ thể yêu cầu trông như thế này:

{ 
    "imageId":"1236", 
    "imageUrl":"http://some.image.url", 
    "image":null 
} 

Việc thực hiện xử lý các yêu cầu nhiều phần dữ liệu tốt, nhưng khi gửi JSON, đối tượng ImageDTO chứa NULLs trong tất cả các thành viên.

Có thể làm cho cùng một phương thức xử lý cả hai loại nội dung không?

Cảm ơn bạn.

Trả lời

1

Tiếp nhận JSON bạn cần phải đánh dấu ImageDTO tranh cãi với @RequestBody

@RequestMapping(value = { "/upload_image" }, method = RequestMethod.POST) 
public @ResponseBody void uploadImage(final @RequestBody ImageDTO image) 
+0

Cảm ơn bạn. Tôi đã thử điều đó rồi, điều này thực sự làm cho JSON hoạt động, nhưng khi gửi yêu cầu nhiều phần thì nó thất bại và lỗi nói rằng loại nội dung dạng nhiều phần không được hỗ trợ. –

+2

Có, Bạn không thể trực tiếp làm điều đó. – shazin

+0

Tôi hiểu. Cảm ơn nhiều. –

1

Có phải đối mặt với một tình huống tương tự, và đây là những gì tôi muốn đưa ra. Cả hai đều không phải là cách rất sạch sẽ, nhưng hoạt động hoàn hảo. Bạn cần gửi yêu cầu số nhiều yêu cầu từ khách hàng:

Lưu ý: Kiểu dữ liệu của biến giữ tệp là InputStream. Bạn cần thay đổi nó cho phù hợp

  1. này rất hữu ích trong trường hợp bạn không nhận thức được số lượng file bạn nhận được trong quý vị yêu cầu.

    // imports 
    import org.apache.commons.fileupload.servlet.ServletFileUpload; 
    import org.apache.commons.fileupload.FileItem; 
    import org.apache.commons.fileupload.disk.DiskFileItemFactory; 
    
    // code flow 
    // HttpServletRequest request 
    final FileItemFactory factory = new DiskFileItemFactory(); 
    final ServletFileUpload fileUpload = new ServletFileUpload(factory); 
    List items = null; 
    private Map<String, InputStream> fileMap = new HashMap<String, InputStream>(); 
    
    if (ServletFileUpload.isMultipartContent(request)) { 
    
        // get the request content and iterate through 
        items = fileUpload.parseRequest(request); 
    
        if (items != null) { 
         final Iterator iter = items.iterator(); 
         while (iter.hasNext()) { 
          final FileItem item = (FileItem) iter.next(); 
          final String fieldName = item.getFieldName(); 
          final String fieldValue = item.getString(); 
          // this is for non-file fields 
          if (item.isFormField()) { 
           switch (fieldName) { 
            case "imageId" : 
            // set inside your DTO field 
            break; 
    
            // do it for other fields 
           } 
    
          } else { 
           // set the image in DTO field 
          } 
         } 
        } 
    } 
    
  2. Trong trường hợp này, bạn sẽ phải xử lý số cố định dạng trường. Tôi đã thực hiện trong phương pháp còn lại như sau:

    @Path("/upload") 
    @POST 
    @Consumes(MediaType.MULTIPART_FORM_DATA) 
    public ResponseDTO upload(FormDataMultiPart multiPartData) { 
    
         // non-file fields 
         final String imageId = multiPartData.getField("imageId").getValue(); 
    
         // for file field  
         final FormDataBodyPart imagePart = multiPartData.getField("image"); 
         final ContentDisposition imageDetails= imagePart.getContentDisposition(); 
         final InputStream imageDoc = imagePart.getValueAs(InputStream.class); 
    
         // set the retrieved content in DTO 
    } 
    
+0

Điều này có vẻ như Jax-Rs không Spring MVC – shazin

+0

Nếu tôi hiểu chính xác bạn, điều này sẽ yêu cầu rằng yêu cầu sẽ luôn luôn có nội dung "multipart-form". Tôi tự hỏi liệu nó có thể làm cho phương pháp có thể xử lý cả hai hình thức multipart, nhưng cũng json trong yêu cầu. –

+0

Có, điều này sẽ yêu cầu yêu cầu biểu mẫu nhiều phần. Bạn không thể gửi nội dung tệp trong một yêu cầu JSON. –

0

tôi đã có kết quả tương tự - NULLs trong tất cả các thành viên DTO cho đến khi tôi đã giới thiệu chú thích @ModelAttribute.Bây giờ tất cả mọi thứ hoạt động tốt, đây là đoạn code làm việc:

phương pháp điều khiển:

@RequestMapping(value = "/save", method = RequestMethod.POST, 
     consumes = { "multipart/form-data" }) 
public void create(@Valid @ModelAttribute("entryForm") final EntryDTO entryDTO, 
     final BindingResult validationResult) throws FormValidationError { 
    validate(entryDTO, validationResult); 
    entryService.save(entryDTO); 
} 

DTO:

public class EntryDTO { 

    private String phrase; 

    private String translation; 

    private MultipartFile imageFile; 

} 

Mẫu:

<form method="post" name="entryForm" action="http://localhost:8080/save" 
     enctype="multipart/form-data"> 
    <p><input type="text" name="phrase" value="test"/> phrase</p> 
    <p><input type="text" name="translation" value="тест"/> translation</p> 
    <p><input type="file" name="imageFile"/></p> 
    <p><input type="submit"/></p> 
</form> 

Lưu ý, biểu mẫu có tên "entryForm" và tương ứng với @ModelAttribute ("entryForm").

Các vấn đề liên quan