Spring MVC 파일 다운로드 최 적 실천

5276 단어 spring mvc
제 가 망상 증 이 있어 서 그런 지 모 르 겠 어 요.
앉 아서 벽돌 을 치 기 를 기다리다.
개인 적 으로 생각 하 다
하나의 프레임 워 크 를 사용 할 때 프로그래머 는 세 가지 등급 으로 나 뉜 다.
1. 데모 개발 보기
2. 문서 개발 보기
3. 소스 코드 개발 보기
분명히 1 보다 2, 2 보다 3.
하지만 시간 비용 을 고려 하면 3 은 2 보다 못 하고 2 는 1 보다 못 하 다.
제 원칙 은 요.
좋 은 demo 가 있 으 면 문 서 를 보지 않 고 좋 은 문서 가 있 으 면 원본 코드 를 보지 않 습 니 다.
파일 다운로드 에 대해 서 는 더 이상 간단 할 수 없 지만, 나 는 비교적 어 리 석 어서 스스로 쓸 줄 모른다.
그래서 구 글 에서 'Spring mvc 3 download' 를 검색 하면 데모 버 전이 많 지 않 습 니 다.

        @RequestMapping("download")
        public void download(HttpServletResponse res) throws IOException {
            OutputStream os = res.getOutputStream();
            try {
                res.reset();
                res.setHeader("Content-Disposition", "attachment; filename=dict.txt");
                res.setContentType("application/octet-stream; charset=utf-8");
                os.write(FileUtils.readFileToByteArray(getDictionaryFile()));
                os.flush();
            } finally {
                if (os != null) {
                    os.close();
                }
            }
        }

나 는 강 한 정신 결벽 증 때문에 마음속 으로 크게 욕 했다.
'이런 개 뿔 코드 도 인터넷 에?'
mvc 를 사 용 했 으 니 HttpServletResponse 와 같은 j2ee 인 터 페 이 스 를 어떻게 노출 할 수 있 겠 는가!
나 는 spring 이 더 좋 은 방법 을 제공 했다 고 믿 고 문 서 를 뒤 져 다음 과 같은 코드 를 얻 기 시작 했다.

    @RequestMapping("download")
    public ResponseEntity<byte[]> download() throws IOException {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", "dict.txt");
        return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(getDictionaryFile()),
                                          headers, HttpStatus.CREATED);
    }

이론 상 으로 는 문제 가 없고, 실현 상 으로 는 매우 우아 하 다.
하지만 파일 다운로드 후 내용 은 다음 과 같 습 니 다.

"YWEJMQ0KdnYJMg0KaGgJMw=="

정확 한 내용 은?

aa	1
vv	2
hh	3

코드 를 바 꾸 겠 습 니 다.

ResponseEntity<String>

출력 은 다음 과 같 습 니 다.

"aa    1
\tvv 2
\thh 3"

많은 분 들 이 보 셨 을 거 라 고 믿 습 니 다. 무슨 일이 일 어 났 는 지 알 고 있 습 니 다.
그러나 본인 의 개 똥 같은 기초 지식 때문에 또 몇 시간 을 낭비 하 였 다
먼저 ByteArray HttpMessage Converter 의 소스 코드 를 보 러 갔 어 요.

        public ByteArrayHttpMessageConverter() {
		super(new MediaType("application", "octet-stream"), MediaType.ALL);
	}
        ...
        protected void writeInternal(byte[] bytes, HttpOutputMessage outputMessage) throws IOException {
		FileCopyUtils.copy(bytes, outputMessage.getBody());
	}

아무 문제 가 없 었 어 요.
한참 동안 귀 를 잡 고 볼 을 긁 더 니, 또 AnnotationMethodHandler Adapter 를 보 러 갔다.

        public AnnotationMethodHandlerAdapter() {
		// no restriction of HTTP methods by default
		super(false);

		// See SPR-7316
		StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();
		stringHttpMessageConverter.setWriteAcceptCharset(false);
		this.messageConverters = new HttpMessageConverter[]{new ByteArrayHttpMessageConverter(), stringHttpMessageConverter,
				new SourceHttpMessageConverter(), new XmlAwareFormHttpMessageConverter()};
	}

        public void setMessageConverters(HttpMessageConverter<?>[] messageConverters) {
		this.messageConverters = messageConverters;
	}

Mapping Jackson HttpMessage Converter 를 보 러 갑 니 다.

extends AbstractHttpMessageConverter[color=red]<Object>[/color]

갑자기 자신 이 멍청 한 느낌 이 들 어서 한 3, 4 시간 을 낭비 했다.
수정 xml

    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
            <list>
                [color=red]<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>[/color]
                <bean id="jsonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" >
                    <property name = "supportedMediaTypes">
                        <list>
                            <value>text/plain;charset=UTF-8</value>
                        </list>
                    </property>
                </bean>
            </list>
        </property>
    </bean>

드디어 내 가 원 하 는 대로 됐어.
내 가 몇 시간 동안 한 바보 짓 을 기록 해 봐.
참고 로 모든 예 와 demo 는 최선 의 실천 으로 쓰 는 것 이 좋 습 니 다.
이렇게 해서 저 같은 초보 프로그래머 는 소스 코드 를 볼 기회 가 없어 요.

좋은 웹페이지 즐겨찾기