Microsoft 社는 2022년 6월 15일 Internet Explorer 11의 지원을 종료했습니다.

파일 업로드

제목

파일 업로드

Graha 응용프로그램은 간단하게 파일 업로드 및 다운로드 기능을 추가할 수 있다.

최신 버전의 Graha 라이브러리에서는 Graha XML 파일을 자동으로 생성하는 관리자 프로그램에서 간단하게 파일업로드 기능을 추가할 수 있다.

전체 예제는 memo.xml 에서 구할 수 있고, Graha 메모장에서 파일 업로드 및 다운로드 기능을 사용하려면 "<!--prop" 와 "<!--files" 를 찾아서 주석을 풀어주면 된다.

1. 입력/수정 기능에서

구문의 전체 사용법은 Graha XML 정의파일 레퍼런스 를 참조한다.

1.1. 파일 업로드 및 목록을 위하여

<files>
<file
name="memo.file"
path="${system.context.root.path}WEB-INF/memo/attach/${query.memo.memo_id}"
append="3"
/>
</files>
  • append 속성(속성값 = 3)을 추가하면, 3개의 추가적인 파일 입력창이 표시된다. 최신의 웹브라우저에서는 각각의 파일 입력창에서 여러개의 파일을 선택할 수 있다.
  • path 속성은 파일을 업로드할 디렉토리까지만 지정하는데, "${}" 안에 변수를 넣을 수도 있다.
  • "${query.memo.memo_id}" 에서 memo 는 <table> 의 name 속성값이고, ${system.context.root.path} 은 Graha XML 정의파일 레퍼런스 를 참조한다.
  • "${query.memo.memo_id}" 는 memo_id 를 sql 실행결과에서 가져오기 위한 것이다.
  • 파일을 삭제하기 위해서는 수정 화면에서 파일을 check 하고 저장하면 된다.

파일 저장 경로를 WEB-INF 아래로 설정했으나, 권장되는 방식인지 불분명하므로, 적절한 경로로 변경될 필요도 있어보인다. 2중화에서는 물리적으로 독립적인 디스크에 저장할 필요도 있다.

1.2. 2중화를 위하여

<files>
<file
name="memo.file"
path="${system.context.root.path}WEB-INF/memo/attach/${query.memo.memo_id}"
append="3"
backup="${system.context.root.path}WEB-INF/memo/backup/${query.memo.memo_id}"
/>
</files>
  • backup 속성이 추가되었고, 속성값을 정의하는 방법은 path 와 같다.
  • 파일을 업로드 할 때, path 으로 업로드하고, backup 으로 복사한다.
  • 파일목록을 가져오거나 할 때에는 path 속성에서 정의된 것만 이용한다(엄격한 의미의 2중화는 아니고, 사본을 보관하는 수준이다).

1.3. 권한 체크

1.3.1. 파일 목록

게시물을 읽을 수 있는 권한이 없다면 파일 목록을 조회할 수 있는 권한도 없다.

데이타베이스에서 가져온 것이 없다면, 이미 존재하는 파일 목록도 가져오지 않는다.

1.3.2. 일부 사용자만 파일 업로드 기능을 사용할 수 있도록 하는 방법

다음과 같이 하면 file 이라는 role 이 있는 사용자만 파일 업로드 기능을 사용할 수 있다.

<files auth="${header.remote_user_roles} in 'file'">

1.3.3. 파일 다운로드

파일 다운로드 경로를 직접 입력한 경우에도 권한을 체크해야 한다.

다음과 같이 <auth> 요소를 추가하여 sql 구문으로 파일 다운로드 권한이 있는지 여부를 check 할 수 있다.

<files>
<file
name="memo.file"
path="${system.context.root.path}WEB-INF/memo/attach/${query.memo.memo_id}"
append="3"
backup="${system.context.root.path}WEB-INF/memo/backup/${query.memo.memo_id}"
/>
<auth check="${result} > 0">
<sql>select count(*) from memo.memo where insert_id = ? and memo_id = ?</sql>
<params>
<param name="insert_id" datatype="varchar" value="prop.logined_user" />
<param name="memo_id" datatype="int" value="param.query.memo.memo_id" />
</params>
</auth>
</files>

1.4. 상세 및 삭제 기능을 위하여 파일 경로를 <prop> 로 정의

<querys> / <header> 에 다음과 같이 <prop> 정의를 추가하고,

<prop name="memo.save.directory" value="${system.context.root.path}WEB-INF/memo/" />
<prop name="memo.backup.directory" value="${system.context.root.path}WEB-INF/memo/" />

이를 반영한다.

<files>
<file
name="memo.file"
path="${prop.memo.save.directory}/attach/${query.memo.memo_id}"
append="3"
backup="${prop.memo.backup.directory}/backup/${query.memo.memo_id}"
/>
<auth check="${result} > 0">
<sql>select count(*) from memo.memo where insert_id = ? and memo_id = ?</sql>
<params>
<param name="insert_id" datatype="varchar" value="prop.logined_user" />
<param name="memo_id" datatype="int" value="param.query.memo.memo_id" />
</params>
</auth>
</files>

이렇게 하면 서버 쪽에서 파일 저장 경로를 변경할 때, <prop> 만 변경하면 된다.

2. 상세 기능에서

구문의 전체 사용법은 Graha XML 정의파일 레퍼런스 를 참조한다.

<files>
<file
name="memo.file"
path="${prop.memo.save.directory}/attach/${query.memo.memo_id}"
backup="${prop.memo.backup.directory}/attach/${query.memo.memo_id}"
/>
<auth check="${result} > 0">
<sql>select count(*) from memo.memo where insert_id = ? and memo_id = ?</sql>
<params>
<param name="insert_id" datatype="varchar" value="prop.logined_user" />
<param name="memo_id" datatype="int" value="param.query.memo.memo_id" />
</params>
</auth>
</files>
  • append 속성만 없다.

3. 삭제 기능에서

구문의 전체 사용법은 Graha XML 정의파일 레퍼런스 를 참조한다.

<files>
<file
name="memo.file"
path="${prop.memo.save.directory}/attach/${param.memo_id}"
backup="${prop.memo.backup.directory}/attach/${param.memo_id}"
/>
</files>
  • "${param.memo_id}" 으로 변경되었다. 여기서는 memo_id를 sql 실행결과에서 가져오는 것이 아니다.
  • 데이타베이스에서 삭제한 것이 없다면, 게시물을 삭제할 권한이 없다고 가정하고, 파일을 삭제하지 않는다.
제목

첨부파일