下载图像后,我想重定向另一个页面,但不能

时间:2014-04-30 13:57:37

标签: java

HttpServletResponse response)抛出ServletException,IOException {

    URL url = new URL("http://www.avajava.com/images/avajavalogo.jpg");
    System.out.println(url.getFile().substring(url.getFile().lastIndexOf("/")+1, url.getFile().length()));
    URLConnection connection = url.openConnection();
    InputStream stream = connection.getInputStream();
    response.setHeader("Cache-Control", "no-cache");
    ServletContext context = getServletContext();
    String  mimeType = "application/octet-stream";
    response.setContentType(mimeType);
    response.setHeader("Content-Disposition", "attachment; filename=icon" + ".jpg");
    String headerKey = "Content-Disposition";
    String headerValue = String.format("attachment; filename=\"%s\"",url.getFile().substring(url.getFile().lastIndexOf("/")+1, url.getFile().length()));
    response.setHeader(headerKey, headerValue);
    OutputStream outStream = response.getOutputStream();
    byte[] buffer = new byte[4096];
    int bytesRead = -1;
      while ((bytesRead = stream.read(buffer)) != -1) {
       outStream.write(buffer, 0, bytesRead);
   }

// stream.close();     // outStream.close();

      RequestDispatcher rd = getServletContext().getRequestDispatcher("/next.html");

   rd.include(request, response);

1 个答案:

答案 0 :(得分:3)

好的假设在您的情况下,当用户点击链接或下载按钮时,应用程序应该下载图像,一旦完成,它应该导航到另一个页面。如果是这种情况,则以下解决方法有帮助。

您的解决方案无法正常工作的原因是您首先下载图像并将流写入响应对象的输出strem。这将提交流。因此,如果您在写入流后尝试重定向,则会收到IllegaStateException。这就是在这种情况下发生的事情,它不会被转发。

我建议的解决方法是分别处理两个动作。假设我有一个下载图像的servlet和另一个导航到下一页的servlet。然后你可以使用jquery的文件下载插件等待下载发生,然后触发导航流程。

所以我的第一页就像。

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script type="text/javascript" src="js/jquery-1.9.0.min.js"></script>
<script type="text/javascript" src="js/jquery.fileDownload.js"></script>
<script>
    $(document).on("submit", "form.fileDownloadForm", function(e) {

        $.fileDownload($(this).prop('action'), {
            successCallback : function(url) {
                $('form#nextPage').submit();
            },
            failCallback : function(responseHtml, url) {
                alert('File download failed!!!!');
            }
        });

        e.preventDefault();
    });
</script>
</head>
<body>
    First
    <form action="<%=request.getContextPath()%>/img" method="get"
        class="fileDownloadForm" id="imgForm">
        <input type="submit" value="Download Image">
    </form>
    <form action="<%=request.getContextPath()%>/test" method="get"
        id="nextPage"></form>
</body>
</html>

所以这里我有两种形式(因为我正在使用表单提交方法。如果使用链接,可以避免这种情况),imgForm和nextPage。所以当我们点击imgForm上的下载按钮时,会调用jquery下载插件脚本。请注意e.preventDefault()方法。这将阻止页面提交,以便页面等待下载完成,并在成功完成时调用successCallback方法。因此,我使用下一个提交导航到下一页。如果您不想要第二个表单,可以使用其他方法,例如设置window.location =

不对于服务员。我有两个servlet用于下载图像,第二个用于导航到下一页。

图片Servlet

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class ImageServlet
 */
public class ImageServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public ImageServlet() {
    super();
    // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        URL url = new URL("http://www.avajava.com/images/avajavalogo.jpg");
        Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("10.9.248.37", 18082));
        System.out.println(url.getFile().substring(url.getFile().lastIndexOf("/")+1, url.getFile().length()));
        URLConnection connection = url.openConnection(proxy);
        InputStream stream = connection.getInputStream();
        response.setHeader("Cache-Control", "no-cache");
        ServletContext context = getServletContext();
        String  mimeType = "application/octet-stream";
        response.setContentType(mimeType);
        response.setHeader("Content-Disposition", "attachment; filename=icon" + ".jpg");
        response.setHeader("Set-Cookie", "fileDownload=true; path=/");
        String headerKey = "Content-Disposition";
        String headerValue = String.format("attachment; filename=\"%s\"",url.getFile().substring(url.getFile().lastIndexOf("/")+1, url.getFile().length()));
        response.setHeader(headerKey, headerValue);
        OutputStream outStream = response.getOutputStream();
        byte[] buffer = new byte[4096];
        int bytesRead = -1;
        while ((bytesRead = stream.read(buffer)) != -1) {
           outStream.write(buffer, 0, bytesRead);
       }
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    }
}

导航Servlet

import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class Test
 */
public class Test extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public Test() {
    super();
    // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        RequestDispatcher rd = getServletContext().getRequestDispatcher("/next.jsp");
        rd.include(request, response);
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    }

}

希望很清楚。

请注意ImageServlet中的两个标题

response.setHeader("Content-Disposition", "attachment; filename=icon" + ".jpg");
response.setHeader("Set-Cookie", "fileDownload=true; path=/");

jquery插件需要这些标头才能正常工作。您可以从http://johnculviner.com/jquery-file-download-plugin-for-ajax-like-feature-rich-file-downloads/

获取有关jquery下载插件的更多详细信息