如何使用Spring 3.2 spring-mvc以宁静的方式上传/流式传输大图像 [英] How do i upload/stream large images using Spring 3.2 spring-mvc in a restful way

查看:78
本文介绍了如何使用Spring 3.2 spring-mvc以宁静的方式上传/流式传输大图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试将大图像上传/流式传输到REST控制器,该控制器将文件并存储到数据库中.

I try to upload/stream a large image to a REST controller that takes the file and stores it in to a database.

@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流式传输/读取图像.

This is a non-working example of what I'm trying to achieve (of course, or I guess so InputStream is not working). I want to stream/read the image over the @RequestBody.

我到处搜索过,但是找不到一个很好的例子来实现这一目标.大多数人似乎只问如何通过表单上传图像,而不使用REST/RestTemplate来完成.有没有人可以帮助我呢?

I have searched everywhere but can't find a good example how to achieve this. Most people seem to ask only how to upload images over forms but don't use REST/RestTemplate to do it. Is there anyone that can help me with this?

感谢您对正确方向的任何提示.

I'm thankful for any hint in to the right direction.

亲切的问候, 克里斯

解决方案

在下面,我尝试发布来自Dirk和Gigadot的投入后对我有用的解决方案.目前,我认为两种解决方案都值得一看.首先,我尝试在Dirk的帮助下发布一个工作示例,然后尝试在Gigadot的帮助下创建一个示例.我将Dirks答案标记为正确答案,因为我一直在明确询问如何通过@RequestBody上载文件.但是我也很好奇要从Gigadot测试该解决方案,因为它可能更容易使用并且更常见.

Below here I try to post the solutions that worked for me after the Input from Dirk and Gigadot. At the moment I think both solutions are worth while looking at. At first I try to post a working example with the help I got from Dirk and then I'll try to create one with the help from Gigadot. I will mark Dirks answer as the correct one as I have been asking explicitly how to upload the file over the @RequestBody. But I'm also curious to test the solution from Gigadot as it is maybe easier and more common to use.

在以下示例中,我将文件存储在MongoDB GridFS中.

In the below examples I store the files in MongoDB GridFS.

解决方案1-Dirks建议后的示例

控制器(在注释中带有curl命令用于测试):

Controller (with curl command for testing in the comment):

/**
*
* @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 (unfinished but working as a test):

@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建议后的示例

Spring手册对此进行了描述: http://static.springsource.org/spring/docs/3.2.1.RELEASE/spring-framework-reference/html/mvc.html#mvc-multipart

This is described in the Spring manual: http://static.springsource.org/spring/docs/3.2.1.RELEASE/spring-framework-reference/html/mvc.html#mvc-multipart

这非常容易,并且默认情况下还包含所有信息.我认为我至少会针对二进制上传使用此解决方案.

This is quite easy and also contains all information by default. I think I'll go for this solution at least for the binary uploads.

感谢大家发表和回答.非常感谢.

Thanks everyone for posting and for your answers. It's much appreciated.

推荐答案

看起来就像您在使用spring一样,您可以使用HttpEntity(

As it looks as if you are using spring you could use HttpEntity ( http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/http/HttpEntity.html ).

使用它,您会得到如下信息(请看有效载荷"):

Using it, you get something like this (look at the 'payload' thing):

@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.");
    }
}

我们在这里使用PUT,是因为它是RESTfull将图像投放到产品". "spn"是产品编号,图像名称由fileService.store()创建.当然,您也可以发布图像以创建图像资源.

We're using PUT here because it's a RESTfull "put an image to a product". 'spn' is the products number, the imagename is created by fileService.store(). Of course you could also POST the image to create the image resource.

这篇关于如何使用Spring 3.2 spring-mvc以宁静的方式上传/流式传输大图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆