代码之家  ›  专栏  ›  技术社区  ›  Muhammed Ozdogan

Spring Boot+从服务器接收的角度渲染照片

  •  0
  • Muhammed Ozdogan  · 技术社区  · 8 年前

    我希望用户可以将照片发送到服务器,然后在浏览器上接收和查看它们。

    这是创建实体时的端点:

     @RequestMapping(value = "/create", method = RequestMethod.POST,
                consumes = {"multipart/form-data"})
        @ResponseBody
        public void create(
                @RequestPart("actor") @Valid ActorDto actorDto,
                @RequestPart("file") @Valid MultipartFile file
                ) {
    
                String actorProfilePhotoLocation = fileService.saveActorProfile(file);
                Actor actor = converter.convertToEntity(actorDto, actorProfilePhotoLocation);
                actorService.create(actor);
    
        }
    

    当我收到数据时,我是在用文件系统而不是数据库写照片。

    在这里:

    public String saveActorProfile(MultipartFile file, ActorDto actorDto) {
        String fileName = System.currentTimeMillis()
                + "." + this.getFileExtension(file.getOriginalFilename());
    
        File directory = new File(ACTOR_DIRECTORY);
    
        if(!directory.exists()) {
            directory.mkdirs();
        }
    
    
        try {
            byte[] bytes = file.getBytes();
            Path path = Paths.get(ACTOR_DIRECTORY + "//" + fileName );
            Files.write(path, bytes);
    
            return path.toString();
        } catch (IOException e) {
            logger.error("FileService::saveActorProfile has failed." +
                    " With parameters: "
            + " file: " + file
            + " message: " + e.getMessage());
            return null;
        }
    }
    

    这部分没问题,我没什么问题。但当我将照片发送给客户端时,客户端无法看到照片,因为我将其作为字节数组发送。

    这是我的dto:

    @Getter
    @Setter
    public class ActorDto {
    
        private Long actorId;
    
        private String name;
    
        private String surname;
    
        private String description;
    
        private List<HeroDto> heroList;
    
        private Byte[] photoBuffer;
    
    }
    

    Angular和Spring引导在不同的端口工作,它们的应用程序上下文不同。所以我不能像静态背景那样提供照片。

    我正在试图发送照片,因为我从磁盘读取。

    在这里:

      public ActorDto convertToDto(Actor source) throws IOException {
    
            ActorDto dto = modelMapper.map(source, ActorDto.class);
            byte[] photo = Files.readAllBytes(Paths.get(source.getProfilePhotoPath()));
            dto.setPhotoBuffer(this.autoBoxingByteArray(photo));
    
            return dto;
        }
    

    我正在返回dto列表以获取请求。


    当客户端接收到数据时,我试图将字节数组转换为base64字符串。 但图像没有显示出来。

    在这里:

    export class Actor {
      actorId: number;
      name: string;
      surname: string;
      description: string;
      heroList: Hero[];
      photoBuffer: number[];
      photo: string;
    }
    

    这是转换部分:

    在我的情况下” value.photoBuffer “类似于: [-119, 80, 78,...] 这是一个数字数组。

    “value.photo”类似于: data:image/png;base64,LTExOQ==ODA=Nzg=NzE=MTM=MTA=MjY... "

    src 的属性 <img> 是:“ unsafe:data:image/png;base64,LTExOQ==ODA=Nzg=NzE=MTM=MTA=MjY... "

    manipulateReceivedData(actorList: Actor[]): void {
        const PNG_PREFIX = 'data:image/png;base64,';
        actorList.forEach((value: Actor, index: number, array: Actor[]) => {
          let photo = PNG_PREFIX;
          value.photoBuffer.forEach((byte: number, j: number, bytes: number[]) => {
            photo += btoa(byte.toString());
          });
          value.photo = photo; // Convert byte array to string that represent a image in base64;
        });
      }
    

    在中

    Html部分:

                <div class="col-md-4" *ngFor="let a of actorList">
                  <div class="card mb-4 box-shadow">
                    <img class="card-img-top" [src]="a.photo" alt="Card image cap">
                    <div class="card-body">
                      <h5 class="card-text text-center">{{a.name}} {{a.surname}}</h5>
                      <p class="card-text">{{a.description}}</p>
                      <div class="d-flex justify-content-between align-items-center">
                        <div class="btn-group">
                          <button type="button" class="btn btn-sm btn-outline-secondary">View</button>
                          <button type="button" class="btn btn-sm btn-outline-secondary">Edit</button>
                        </div>
                      </div>
                    </div>
                  </div>
    

    我可以在文件系统中很好地看到浏览器上传的图像。 但我无法实现在浏览器中表示图像。

    我哪里出错了?

    还有附加问题? 假设我有一个在浏览器上表示图像的工具。我试图同时代表50个图像,这是性能问题吗?

    1 回复  |  直到 8 年前
        1
  •  2
  •   Muhammed Ozdogan    8 年前

    Ohh祝福JavaScript和TypeScript。其中一个用奇怪的格式编码我的字节数组,我看到有很多“ = 所以我试着用“Java”代码对它进行编码,结果成功了。

    以下是代码:

    @Getter
    @Setter
    public class ActorDto {
    
        private Long actorId;
    
        private String name;
    
        private String surname;
    
        private String description;
    
        private List<HeroDto> heroList;
    
        private String photo; // I have replaced byte array with String.
    
    }
    

    在我以字节形式读取文件之后。

    我用Java对其进行编码。

    public ActorDto convertToDto(Actor source) throws IOException {
    
            ActorDto dto = modelMapper.map(source, ActorDto.class);
            byte[] photo = Files.readAllBytes(Paths.get(source.getProfilePhotoPath()));
    
            StringBuilder base64 = new StringBuilder("data:image/png;base64,");
            base64.append(Base64.getEncoder().encodeToString(photo));
            dto.setPhoto(base64.toString());
    
            return dto;
        }
    

    __

    我从前端模型中删除了数字数组字段:

    export class Actor {
      actorId: number;
      name: string;
      surname: string;
      description: string;
      heroList: Hero[];
      photo: string;
    }
    

    在html中,由于“ unsafe “Angular将其添加到src属性上的前缀,如” unsafe:data:image/png;base64,... “但应该是这样” data:image/png;base64,... “否则将不显示图像:”

     <div class="col-md-4" *ngFor="let a of actorList">
                  <div class="card mb-4 box-shadow">
                    <img class="card-img-top" [src]="a.photo | safeUrl" alt="Card image cap">
                    <div class="card-body">
                      <h5 class="card-text text-center">{{a.name}} {{a.surname}}</h5>
                      <p class="card-text">{{a.description}}</p>
                      <div class="d-flex justify-content-between align-items-center">
                        <div class="btn-group">
                          <button type="button" class="btn btn-sm btn-outline-secondary">View</button>
                          <button type="button" class="btn btn-sm btn-outline-secondary">Edit</button>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
    

    以下是新添加的管道:

    @Pipe({name: 'safeUrl'})
    export class SafeUrlPipe implements PipeTransform {
    
      constructor(private sanitizer: DomSanitizer)  {}
    
      transform(value: any, ...args: any[]): any {
    
        return this.sanitizer.bypassSecurityTrustResourceUrl(value);
    
      }
    
    }
    

    而且它是有效的。现在我可以在浏览器上看到图像了。

    但我仍然对性能感到困惑。从服务器获取和显示图像是一种真正的孤独吗?我不确定,但至少它起作用了。