본문 바로가기
IT 개발/JAVA

JAVA - WAS 서버에서 이미지 표출 처리

by Love of fate 2023. 3. 13.
728x90
반응형

[WAS 서버에서 이미지 표출 처리하기] 

 

사용자가 사진을 업로드할 시 서버에 저장되고 저장된 이미지를 다시 화면에 뿌려줘야할때

또는 

보안적으로 안전하게 경로를 보여주고 싶지 않을 때 서버에서 이미지 표출 처리 하며

script단에서 <img>태그에 서블릿 경로로 지정한 후 

서버단에서 처리해주는 방식으로 있다.

현재 내가 아는 방식은 두가지가 있으며 아래와 같다.

 

1. ServletOutPutStrrem으로 파일 읽어서 내보내기

 

RequestMapping("/profile")
 public String profile(HttpSession session,HttpServletResponse response , String fileId ) throws Exception {  
  response.setContentType( "image/jpg" );
  ServletOutputStream bout = response.getOutputStream();
 
 //이렇게 String을 이어 붙이기보다는 
 // Paths 객체를 해용한다.
 // Paths.get(fileRepositoryPath, fileUserPicPath, nophoto.jpg)
 // separator가 자동으로 붙는다.
  String imgpath = fileRepositoryPath + File.separator + fileUserPicPath +  File.separator + "nophoto.jpg";
 
  
  String[] exts = {".bmp", ".jpg", ".gif", ".png", ".jpeg"};
  File f = new File(fileRepositoryPath + File.separator + fileUserPicPath +  File.separator +  idno +ext);

  if(f.exists()){
    imgpath = fileRepositoryPath + File.separator + fileUserPicPath +  File.separator +   fileId + ext;
  }
  
  FileInputStream f = new FileInputStream(imgpath); 
  int length;
  byte[] buffer = new byte[10];
  while ( ( length = f.read( buffer ) ) != -1 )
  bout.write( buffer, 0, length );  
  return null;
 }

 

2. ResponseEntity를 사용하여 파일 내보내기

    @GetMapping("/{id}/{soon}/profile")
    public ResponseEntity<Resource> profile(@PathVariable String id, @PathVariable String soon) throws IOException {
        return download(fileService.load(id, soon));
    }
    
    private ResponseEntity<Resource> download(FileEntity fileEntity) throws IOException {
    
        boolean isExists = false;
        Path path = null;
        Resource resource = null;
        
        Long fileSize = 0L;
        String fileName = null;
        
        if (fileEntity != null) {
            path = Paths.get(fileEntity.getFileStreCours(), fileEntity.getStreFileNm());
            if( Files.exists(path) ) {
                fileName = fileEntity.getOrignlFileNm();
                fileSize = fileEntity.getFileSize();
                isExists = true;
            }
        }
        
        if( !isExists ) {
            ClassPathResource clsPathRes = new ClassPathResource("/static/assets/images/jpg/user-photo-default@2x.jpg");
            path = Paths.get(clsPathRes.getURI()); 
            fileName = path.getName();
            fileSize = clsPathRes.getFile().length();
        }
        
        //Resource는 InputStreamResource로 사용할 수 있다.
        //InputStreamResource resource = new InputStreamResource(new FileInputStream(file)); 
        resource = new ByteArrayResource(Files.readAllBytes(path));
        HttpHeaders headers = new HttpHeaders();
//        headers.setContentDispositionFormData("attachment", fileEntity.getOrignlFileNm());//, Charset.forName("utf-8"));
        headers.setContentDisposition(ContentDisposition
                .builder("attachment")
                .filename(fileName, Charset.forName("utf-8"))
                .build());

        return ResponseEntity.ok()
                .headers(headers)
                .contentLength(fileSize)
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .body(resource);
    }
}

 

 두번째 방법은 최근에 알게 되었으며,  파일이 경로에 없을 경우 default 이미지를 표출하는 작업까지 포함이 되어있다.

default 이미지는 리소스에 있으며 front단에서는 리소스에 있는 이미지는 경로 중 img 태그 src 속성에

static을 제외하고 나머지 경로를 적어주면 이미지를 찾지만 

서버단에서는 resource 경로를 전부 작성해줘야한다. 

그러기 위해서는 이미지파일의 리소스 경로를 알아야하는데 이때 사용하는 Class가 ClassPathResource이다.

ClassPathResource 객체를 생성하여 이미지 파일의 일부 경로를 넣어주면 전체 Pull Path를 알 수 있다. 

 

Resource는 FileInputStreamResoucre를 사용해도 되고, ByteArrayResource를 사용해도 된다. 

 

개발자는 알겠지만 뭐든지 정답은 없다. 

어떻게 개발할지 작성을 지속적으로 하다보면 더 좋은 코드를 알 수 있고, 공부는 계속 해야한다. ㅠㅠ 

728x90
반응형