문제

JSP에서 zip 파일을 제공하는 데 문제가 있습니다.

zip 파일은 다운로드가 완료된 후 항상 손상됩니다.나는 읽고 쓰기 위해 몇 가지 다른 방법을 시도했지만 그 중 어느 것도 효과가 없는 것 같습니다.

파일이 열리고 모든 파일 이름이 표시되기 때문에 어딘가에 ASCII 문자를 추가하는 것 같지만 파일을 추출할 수는 없습니다.

내 최신 코드는 다음과 같습니다.

<%@ page import= "java.io.*" %>

<% 
    BufferedReader bufferedReader = null;

    String zipLocation = "C:\\zipfile.zip"; 

    try
    {
        bufferedReader = new BufferedReader(new FileReader(zipLocation));
        response.setContentType("application/zip");
        response.setHeader( "Content-Disposition", "attachment; filename=zipfile.zip" );

        int anInt = 0;
        while((anInt = bufferedReader.read()) != -1)
        {
            out.write(anInt);
        }
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
%>

편집하다:코드를 서블릿으로 옮겼는데 여전히 작동하지 않습니다.주변에 더 많은 항목을 변경했으므로 작동하지 않는 최신 코드는 다음과 같습니다.

public void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException
{
    try
    {
        String templateLocation = Config.getInstance().getString("Site.templateDirectory");

        response.setContentType("application/zip");
        response.setHeader("Content-Disposition", "attachment; filename=output.zip;");

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        BufferedOutputStream bos = new BufferedOutputStream(baos);
        FileInputStream fis = new FileInputStream(templateLocation);

        int len;
        byte[] buf = new byte[1024];

        while ((len = fis.read(buf)) > 0)
        {
            bos.write(buf, 0, len);
        }

        bos.close();
        PrintWriter pr = response.getWriter();
        pr.write(baos.toString());
        pr.close();
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}

편집2:

이것이 제가 실제로 작동하는 서블릿 코드입니다.모두에게 감사드립니다!

public void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException
{
    try
    {
        String templateLocation = Config.getInstance().getString("Site.templateDirectory");

        response.setContentType("application/zip");
        response.setHeader("Content-Disposition", "attachment; filename=output.zip;");

        BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
        FileInputStream fis = new FileInputStream(templateLocation);

        int len;
        byte[] buf = new byte[1024];

        while ((len = fis.read(buf)) > 0)
        {
            bos.write(buf, 0, len);
        }

        bos.close();
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}
도움이 되었습니까?

해결책

ZIP는 이진 파일이므로 문자 데이터로 전송하기에 적합하지 않습니다. 또한 코드 외부의 텍스트는 파일을 손상시킬 수 있습니다.

JSP 대신 평원 바닐라 서블릿을 사용하십시오.

다른 팁

JSP는 출력에 공백을 추가합니다.이것을 서블릿으로 옮기는 것이 좋습니다.

또는 다음을 살펴볼 수 있습니다. JSP 출력에서 ​​공백 제거 , 그러나 ZIP 출력 자체에는 영향을 미치지 않을지 확실하지 않습니다.

이 정확한 스 니펫의 문제는 2 행에 있습니다. JSP 태그 외부에 빈 줄이있어 브라우저로 HTML로 전송됩니다 (즉, HTML 소스의 빈 줄).

< % %>, 특히 공백 (터미널 뉴 라인)이 아닌 것을 제거하거나 다른 곳에서 조언을 따르고 서블릿을 사용하도록 매우주의하십시오. :)

스트림을 response.getWriter(), 다른 사람들이 지적한대로 문자 데이터. 나는 Javadoc을 인용합니다.

PrintWriter getWriter() throws IOException
클라이언트에게 문자 텍스트를 보낼 수있는 인쇄기 객체를 반환합니다. Printwriter는 getcharacterencoding ()에 의해 반환 된 문자 인코딩을 사용합니다.

뿐만 아니라 바이트 배열을 Writer, 당신은 결과를 쓰고 있습니다 ByteArrayOutputStream.toString(), 캐릭터 변환을 수행합니다 ~

response.getOutputStream ()을 사용하려고합니다.

BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());

그런 다음 파일의 바이트 내용을 작성하십시오.

내가 올바르게 기억한다면 독자는 일반적으로 캐릭터 스트림을위한 것입니다. 바이트 라우 포트 스트림의 선을 따라 더 많은 것을 시도 할 수 있습니까? 또한 JSP는 다른 사람들이 언급 한 것처럼 실제로 출력을 손상시킬 수 있습니다.

bufferedReader = new BufferedReader(new FileReader(zipLocation));

Servlet/JSP 문제 외에도 이 줄은 100% 확실하게 데이터를 손상시킵니다.기본 플랫폼 인코딩을 사용하여 이진 데이터를 텍스트로 해석하려고 시도합니다. 이는 파일의 약 절반 바이트가 "알 수 없는 문자"로 대체됨을 의미합니다.

바이트와 ​​문자열은 같은 것이 아닙니다!

나는 또한 일반 서블릿을 사용하는 것을 제안하고 Robert Munteanu의 대답 맞습니다. 그러나 당신은 당신의 JSP에서도 이것을 할 수 있습니다. 문제는 추가 된 공백은 아니지만 암시 적 변수 "out"은 JSPWriter의 인스턴스이며 작가는 바이트가 아닌 캐릭터를위한 것입니다. 사용하려고 노력하십시오 Response.getOutputStream () 그리고 바로 그것에 대해서는 작동해야합니다. 다른 사람이 이미 출력 스트림을 받았다는 예외를 얻을 수 있지만 무시할 수 있습니다.

그러나 내가 말했듯이, 서블릿을 사용하는 것은 훨씬 깨끗할 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top