【问题标题】:mongodb not finding filemongodb找不到文件
【发布时间】:2015-08-19 22:45:14
【问题描述】:

我有一个 spring-boot 应用程序充当图像服务器。它接收一个图像,例如:

 @RequestMapping(value = "images/{id}", method = RequestMethod.POST)
    @ResponseBody
    public ResponseEntity addPortrait(@RequestParam MultipartFile file, @PathVariable Long patientId) throws Exception {

        try {
            GridFSFile storedFile = mongoFileService.add( file, id );
            LOGGER.info( "Returning Filename " + storedFile.getFilename() );
            return ResponseEntity.ok().contentType( MediaType.APPLICATION_JSON )
                    .body(  SERVER_URL+ storedFile.getFilename() );

        } catch ( Exception ex ) {
            ex.printStackTrace();
            LOGGER.error("Error storing file " + file.getOriginalFilename(), ex );
            return ResponseEntity.status( HttpStatus.INTERNAL_SERVER_ERROR )
                    .contentType( MediaType.APPLICATION_JSON).body(MISSING_IMAGE_PATH );

        }
    }

然后调用:

private GridFsOperations gridFsOperations;

public GridFSFile add(MultipartFile file, Long patientId) throws IOException {
    StringBuilder sb = new StringBuilder();
    sb.append(System.currentTimeMillis());
    sb.append("_");
    sb.append(file.getOriginalFilename());
    return gridFsOperations.store( file.getInputStream(), sb.toString() );
    // return gridFsAppStore.store(file, sb.toString());
}

返回的结果是正确的,我可以在 MongoDB 中看到文件:

db.getCollection('fs.files').find({}):

所以我很确定 PUT 调用有效。

但是,当我尝试使用控制器检索该图像时:

@RequestMapping(value = "images/{filename}", method = RequestMethod.GET)
    @ResponseBody
    public ResponseEntity getSizedImage(@PathVariable String filename, @RequestParam int width, @RequestParam int height) throws Exception {
        if (savedFile != null) {
            try {
               BufferedImage image = ImageIO.read( savedFile.getInputStream() );
               image = resize( image, Method.SPEED, width, height, Scalr.OP_ANTIALIAS );

               LOGGER.info( "Returning Filename " + savedFile.getFilename() + " sized to " + width + " X " + height );
               return ResponseEntity.ok().contentLength( savedFile.getLength() )
                    .contentType( MediaType.IMAGE_JPEG ).body( image );
          } catch (Exception ex) {
            ex.printStackTrace();
            LOGGER.error("Error sizing file " + filename + ": " + ex.getMessage());
              return ResponseEntity.status( HttpStatus.INTERNAL_SERVER_ERROR )
                    .contentType( MediaType.APPLICATION_JSON).body("Error sizing file " + filename + ": " + ex.getMessage() );
           }
       } else {
        LOGGER.error("Could not find requested file " + filename );
        return ResponseEntity.status( HttpStatus.NOT_FOUND )
                        .contentType( MediaType.APPLICATION_JSON).body(MISSING_IMAGE_PATH );
    }
    }

获取图片的MongoFileService是:

@Component
public class MongoFileService {

     @Autowired
     private GridFsOperations gridFsOperations;

      public GridFSDBFile getStore(String filename) throws IOException {

           Query query = new Query( GridFsCriteria.whereFilename().is( filename ) );
    return gridFsOperations.findOne( query );
      }

      public GridFSFile add(MultipartFile file, Long id) throws IOException {

          StringBuilder sb = new StringBuilder();
          sb.append(System.currentTimeMillis());
          sb.append("_");
          sb.append(file.getOriginalFilename());
          return gridFsOperations.store( file.getInputStream(), sb.toString() );
      }

}

我什么也得不到。没有错误,没有图像或日志中除了:

"Error retrieving file " and the file name parameter provided

我正在使用 Spring-Boot 1.3.0.BUILD-SNAPSHOT、MongoDB 2.4.14、Spring-Data。

谁能看到为什么没有返回这个结果?

更新为显示 MongoFileService 我在控制器中设置了一个断点,收到的文件名是“1440128243370_IMG_3415”,其中缺少“JPG”扩展名。如果我手动更改调试器中的值,则会返回文件。

为了解决这个问题,我在我的项目中添加了以下内容:

@Configuration
public class AllResources extends WebMvcConfigurerAdapter {

    @Override
    public void configurePathMatch(PathMatchConfigurer matcher) {
        matcher.setUseRegisteredSuffixPatternMatch(true);
    }
}

【问题讨论】:

  • 只要看看你的代码,我就会说GridFSDBFile savedFile = mongoFileService.getStore( filename ); 正在返回null。可以分享mongoFileService的代码吗?注意:对于null 和异常的情况,我个人不会使用相同的日志级别和错误消息。我会去警告和LOGGER.warn("{} could not be found", filename)LOGGER.error("Exception while retrieving file " + filename, ex) 例外。在这些情况下,我个人也更喜欢返回 404 和 500 而不是 JSON 字符串,但这取决于您的设计。
  • 我已更新问题以显示 mongoFileService。这是关于返回代码的好建议,我也会将它们更改为只返回代码而不是相同的默认消息。
  • 完美。我认为您的查询有问题,因为如果 Query 与任何条目不匹配,findOne 将返回 null
  • 我认为您使用的是普通的Criteria 确实相关。你能试试GridFsCriteria.whereFilename().is(filename)吗?
  • 我替换了它(请参阅更新的问题),但仍然找不到。无论如何要在Mongo或Spring中打开调试以查看是否发生任何错误,或者这只是Mongo找不到它

标签: mongodb spring-boot spring-data


【解决方案1】:

一种可能的方法是更改​​@RequestMapping 中与相关方法匹配的URI 模板变量。语法为{varName:regex}。要使您的 {filename} 变量匹配所有内容(包括点和文件扩展名),请使用以下定义:

@RequestMapping(value = "images/{filename:.+}", method = RequestMethod.GET)

更多详情请见documentation

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多