如何上传REST方式/流的使用Spring 3.2弹簧MVC大图片(How do i upload/

2019-07-19 01:01发布

我试着上传/流的大图像的REST控制器,采用文件并将其存储在一个数据库中。

@Controller
@RequestMapping("/api/member/picture")
public class MemberPictureResourceController {

  @RequestMapping(value = "", method = RequestMethod.POST)
  @ResponseStatus(HttpStatus.NO_CONTENT)
  public void addMemberPictureResource(@RequestBody InputStream image) {
    // Process and Store image in database
  }
}

这是我想要达到非工作示例(当然,或者我猜是这样的InputStream不工作)。 我要流/过@RequestBody读取图像。

我已经找遍,但无法找到一个很好的例子,如何实现这一目标。 大多数人似乎只有一个要求,如何在形式上传图片,但不使用REST / RestTemplate做到这一点。 是否有任何人能帮助我吗?

我很感激任何提示在正确的方向。

亲切的问候,克里斯

解决方案

下面我在这里尝试后,从德克和Gigadot输入后为我工作的解决方案。 此刻,我觉得这两种解决方案都值得看。 起初,我尝试后我跟德克有帮助的工作示例,然后我会尝试创建一个与Gigadot帮助。 我将迎来开瑞答案正确的,因为我一直要求明确如何上传过@RequestBody文件。 但我也很好奇,以测试从Gigadot的解决方案,它可能是更容易,更普遍使用。

在下面的例子我存储在MongoDB的GridFS的文件。

溶液1 -德克斯推荐实施例之后

控制器(与在注释测试curl命令):

/**
*
* @author charms
* curl -v -H "Content-Type:image/jpeg" -X PUT --data-binary @star.jpg http://localhost:8080/api/cardprovider/logo/12345
*/
@Controller
@RequestMapping("/api/cardprovider/logo/{cardprovider_id}")
public class CardproviderLogoResourceController {

  @Resource(name = "cardproviderLogoService")
  private CardproviderLogoService cardproviderLogoService;

  @RequestMapping(value = "", method = RequestMethod.PUT)
  @ResponseStatus(HttpStatus.NO_CONTENT)
  public void addCardproviderLogo(@PathVariable("cardprovider_id") String cardprovider_id,
      HttpEntity<byte[]> requestEntity) {
    byte[] payload = requestEntity.getBody();
    InputStream logo = new ByteArrayInputStream(payload);
    HttpHeaders headers = requestEntity.getHeaders();

    BasicDBObject metadata = new BasicDBObject();
    metadata.put("cardproviderId", cardprovider_id);
    metadata.put("contentType", headers.getContentType().toString());
    metadata.put("dirShortcut", "cardproviderLogo");
    metadata.put("filePath", "/resources/images/cardproviders/logos/"); 

    cardproviderLogoService.create1(logo, metadata);
  }
}

服务(未完成,但作为一个测试工作):

@Service
public class CardproviderLogoService {

  @Autowired
  GridFsOperations gridOperation;

  public Boolean create1(InputStream content, BasicDBObject metadata) {
    Boolean save_state = false;
    try {
      gridOperation.store(content, "demo.jpg", metadata);
      save_state = true;
    } catch (Exception ex) {
      Logger.getLogger(CardproviderLogoService.class.getName())
          .log(Level.SEVERE, "Storage of Logo failed!", ex);
    }
    return save_state;    
  }
}

溶液2 - Gigadots推荐实施例之后

这是在春季手册中描述: http://static.springsource.org/spring/docs/3.2.1.RELEASE/spring-framework-reference/html/mvc.html#mvc-multipart

这是很容易的,也默认包含的所有信息。 我想我会去为这个解决方案至少在二进制上传。

感谢大家张贴和你的答案。 它的大加赞赏。

Answer 1:

因为它看起来就好像你正在使用Spring,你可以使用HttpEntity( http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/http/HttpEntity.html )。

使用它,你会得到这样的事情(看“有效载荷”的东西):

@Controller
public class ImageServerEndpoint extends AbstractEndpoint {

@Autowired private ImageMetadataFactory metaDataFactory;
@Autowired private FileService fileService;

@RequestMapping(value="/product/{spn}/image", method=RequestMethod.PUT) 
public ModelAndView handleImageUpload(
        @PathVariable("spn") String spn,
        HttpEntity<byte[]> requestEntity, 
        HttpServletResponse response) throws IOException {
    byte[] payload = requestEntity.getBody();
    HttpHeaders headers = requestEntity.getHeaders();

    try {
        ProductImageMetadata metaData = metaDataFactory.newSpnInstance(spn, headers);
        fileService.store(metaData, payload);
        response.setStatus(HttpStatus.NO_CONTENT.value());
        return null;
    } catch (IOException ex) {
        return internalServerError(response);
    } catch (IllegalArgumentException ex) {
        return badRequest(response, "Content-Type missing or unknown.");
    }
}

我们使用的是在这里,因为这是一个问题的REST PUT“把图像的产品”。 “SPN”是产品数量,imagename由fileService.store()创建。 当然,你也可以张贴的图片创建图像资源。



Answer 2:

当您发送POST请求,有两种类型的编码可以使用到窗体/参数/文件发送到服务器,即application/x-www-form-urlencodedmultipart/form-data 。 下面是更多的阅读 。

使用application/x-www-form-urlencoded不是一个好主意,如果你在你的POST请求大量的内容,因为它通常会崩溃的网页浏览器(从我的经验)。 因此, multipart/form-data的建议。

Spring可以处理multipart/form-data ,如果你添加一个multipart解析器给调度员自动的内容。 Spring的实现来处理,这是使用Apache的公地文件上传,所以你需要把这个库添加到您的项目完成。

现在对于如何真正做到这一点已经在这里博客的主要答案http://viralpatel.net/blogs/spring-mvc-multiple-file-upload-example/

我希望可以帮助你找到一个解决方案。 您可能需要阅读了关于REST是什么。 这听起来像你是一个有点糊涂。 基本上,几乎所有的HTTP请求的RESTful即使URL是丑陋的。



Answer 3:

我最近做了,看到这里的细节 。

在浏览器,我们可以利用文件API的加载一个文件,然后使用Base64编码编码的内容,并最终发布之前分配该编码的内容为JavaScript对象。

在服务器上,我们有一个春天控制器将处理请求。 作为该请求主体转换为Java对象的JSON解组的一部分,用于将图像字节base64编码值将被转换为一个标准的Java字节[],并且为在数据库中存储的LOB。

要检索的图像,另一个弹簧控制器方法可以通过直接流中的字节提供图像。

该博客文章中,我挂上面假设你要使用的图像作为另一个对象的一部分,但原则应该是相同的,如果你想只图像直接合作。 让我知道,如果有什么需要澄清。



文章来源: How do i upload/stream large images using Spring 3.2 spring-mvc in a restful way