Appsmith 에서 PDF 띄우기

2025. 6. 17. 14:08·Wishy (이력서 평가 프로젝트)

현재 진행하고 있는 이력서 평가 프로젝트에서 이력서 상세화면 조회 시 사용자의 이력서를 보여주는 것은 평가를 해야하기에

필수적인 기능이라고 생각했다. 그래서 Appsmith에서 PDF를 띄우기 위해 여러가지 시도를 하게 되었다

결과 화면

 

이런식으로 PDF 렌더링에 성공할 수 있었다

 

아래 내용은 내가 이를 위해 한 여러가지 시도를 상세하게 적어 보았다

한 줄 요약

  • 로컬에 있는 파일을 그대로 띄워보려 했으나 실패
  • 정적 자원으로 처리하여 웹 서버 형식으로 띄워보려 했으나 실패
  • Iframe으로 PDF 다운로드 형식으로 진행하려 했으나 실패
  • Google Docs Viewer를 사용하여 성공!

 

나는 Appsmith 클라우드에서 개발 중이였고 빠르게 테스트를 하는 게 목적이였다

그렇기에 안정적으로 파일 서버를 구축하는 것은 나중의 일이였고 일단은 Appsmith라는 플랫폼에서

내가 원하는 방향으로 화면이 나오는지 확인이 중요했다. 

 

만약 내가 원하는 방향으로 나오지 않는다면 이 플랫폼을 쓸 이유가 없었다

시도 1. 로컬에 있는 파일을 그대로 띄우기

내가 로컬에 임의의 폴더를 만들고 그 경로로 업로드된 이력서 파일을 저장했기 때문에 로컬 파일 시스템에

접근하여 파일을 띄우려고 시도했다

 

그러나 Appsmith는 웹 기반 앱이여서 로컬 파일 시스템에 접근할 수 없었고 PDF를 띄우려면 해당 파일을

웹 서버를 통해 접근 가능한 URL로 공개해야한다는 정보를 얻게 되었다


 

시도 2. 정적 자원 처리

file:
static-path-pattern: /uploads/**

application.yml 파일에서 이런 식으로 환경 변수를 구성한다면

저 경로를 포함한 url로 데이터를 요청했을때 정적 자원으로 처리를 할 수 있다고 생각했다

 

문제 1. X-Frame-Options

 X-Frame-Options 이란?

 

X-Frame-Options는 웹 페이지가 다른 웹페이지의 <frame>, <iframe>, <object> 등의 요소에 삽입되는 것을 제어하는 

HTTP 응답 헤더이다.

사용 가능한 옵션은 아래와 같다.

  • DENY : iframe 비허용(불가)
  • SAMEORIGIN : 동일 도메인 내에선 접근 가능
  • ALLOW-FROM {도메인} : 특정 도메인 접근 가능

이로 인해 iframe으로 PDF를 렌더링 하려고 했으나 실패했고 스프링 시큐리티 설정 변경을 통해 해결할 수 있었다

@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .headers(headers -> headers
                .frameOptions(frame -> frame.sameOrigin()) // SAMEORIGIN으로 허용
            )
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/uploads/**").permitAll()
                .anyRequest().authenticated()
            )
            .csrf(csrf -> csrf.disable());
        return http.build();
    }
}

 

문제 2. ngrok 관련 문제

Appsmith에서 로컬의 스프링부트 서버를 연결해 데이터를 가져오기 위해서는 localhost로는 되지 않았다

그래서 나는 ngrok 이라는 로컬 서버를 외부에서 사용할 수 있는 플랫폼을 프리 플랜으로 사용 중이였다

문제들을 다 해결했다고 생각했으나 연결 거부했다는 오류가 발생했고 여러 시도들을 통해 이 오류가

ngrok 프리 플랜의 한계라는 것을 알게 되었다

 

이 시도가 성공했다면 일단 테스트용으로 놔두고 추후에 리팩토링을 했겠지만

나는 /uploads/{년}/{월}/{일}로 파일을 저장하고 있었기 때문에

년, 월, 일 데이터를 따로 가지고 있지 않아 이를 java에서 분리하는 로직은 번거롭고 의미없다고 생각했다


시도3. URL를 바꾸자

이력서 PDF 파일의 id만 넘겨서 파일을 다운로드 받는 api를 요청하는것으로 방법을 변경 했다

 

 

이런 식으로 서버에 데이터를 요청하고

@GetMapping("file/{resumeId}")
    public ResponseEntity<Resource> getFile(@PathVariable Long resumeId) throws MalformedURLException {
        Path filePath = resumeService.getFilePath(resumeId);
        String fileName = filePath.getFileName().toString();
        Resource resource = new UrlResource(filePath.toUri());
        if (resource.exists()) {
            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"" + fileName + "\"");
            headers.add("X-Frame-Options", "ALLOWALL");
            return ResponseEntity.ok()
                    .contentType(MediaType.APPLICATION_PDF)
                    .headers(headers)
                    .body(resource);
        } else {
            return ResponseEntity.notFound().build();
        }
    }

 

이런 식으로 받아온다면 브라우저가 자동으로 pdf를 렌더링 할 수 있기에 가능할 꺼라 생각했지만 

결국 Appsmith의 정책 및 여러가지 이유로 실패했다


시도 4. Google Docs Viewer

Google Docs Viewer란?

 

Google Docs Viewer는 웹 상에서 PDF, DOC, PPT 등 문서 파일을 브라우저 내에서 바로 미리보기 할 수 있도록 제공하는 Google의 무료 도구이다. iframe으로 쉽게 임베딩할 수 있어 외부 문서를 웹페이지에 표시하는 데 자주 사용된다.

 

gpt와의 오랜 대화 끝에 gpt는 한줄기 빛을 선사해줬다. 바로 구글 독스 뷰어

 

요청 url은 

https://docs.google.com/gview?url=요청하고자 하는 주소&embedded=true

 

이런식으로 사용하면 되고 결국 성공할 수 있었다

 


 

이 과정을 통해 렌더링 되는 과정, 요청 헤더의 옵션, 정적 자원 처리 등등 여러 가지를 배울 수 있었다

또 gpt는 굉장히 좋은 도구이지만 나처럼 내 프로젝트의 코드의 흐름과 문맥을 아는 건 아니니까 이 글을 쓰기 위해 나누었던

대화를 보며 비슷한 내용을 많이 반복해서 물어보고 응답해줬다는 생각이 든다

요새 바이브 코딩이 핫해 커서도 사용해보았지만 개발자의 지식은 여전히 중요하다

내가 내용을 정확히 알고 해당 로직을 처리했다면 2배는 빠르게 성공할 수 있었을꺼 같다

역시 AI에 의존하면 안되고 오늘 지식들을 다 내것으로 만들어야겠다

'Wishy (이력서 평가 프로젝트)' 카테고리의 다른 글

파일 업로드 API 부하 테스트 (근데 이제 K6를 곁들인...)  (4) 2025.07.30
Aws EC2, Docker 사용하여 AppSmith 배포하기  (0) 2025.05.16
'Wishy (이력서 평가 프로젝트)' 카테고리의 다른 글
  • 파일 업로드 API 부하 테스트 (근데 이제 K6를 곁들인...)
  • Aws EC2, Docker 사용하여 AppSmith 배포하기
코딩숙
코딩숙
개발이라는 끝이 없는 바다 묵묵히 꾸준히 항해하기
  • 코딩숙
    코딩숙
    코딩숙
  • 전체
    오늘
    어제
    • 분류 전체보기 (63)
      • CS 공부 (17)
        • 클라우드 (3)
        • 네트워크 (3)
      • 개발 공부 (40)
        • 오류 해결 (4)
        • 알고리즘 (12)
        • Spring (3)
        • JPA (2)
        • TIL(오늘 내가 배운 것) (9)
        • 코드복습 (1)
        • 디자인 패턴 (1)
      • IT 관련 영상 메모 (1)
      • 데일리피드백 (0)
      • Tools (1)
      • Wishy (이력서 평가 프로젝트) (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    user mode
    JPA
    키 페어 분실
    appsmith
    302 Found
    프로그래머스
    게임 맵 최단거리 자바
    데이터 타입
    isBefore()
    404 Not Found
    isAfter()
    http
    HTTP BODY
    데이터베이스 손상
    인프런
    자바
    setter method
    programmers #정수 내림차순으로 배치하기
    getter method
    데이터베이스 백업
    개발자
    innodb
    java
    프로그래머스 네트워크 자바
    도메인설계
    백준
    변수
    키 페어 변경
    개발공부
    마이크로서비스
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
코딩숙
Appsmith 에서 PDF 띄우기
상단으로

티스토리툴바