【问题标题】:Serlvet mixing session responsesServlet 混合会话响应
【发布时间】:2013-05-03 10:45:14
【问题描述】:


我正在开发一个 Android 打印应用程序。我的应用程序的一部分是从用户接收文件的本地服务器。
我在 Tomcat Java servlet 中实现了服务器。

我的问题是,当两台设备同时向服务器发送 2 个文件时,有两种可能的结果:
1. 一个客户端收到一个好的响应,第二个客户端收到一个空响应。
2. 一个客户端收到第二个客户端的响应,反之亦然。

这是我的 servlet 代码:

    protected void doPost(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
        new Runnable() {

            @Override
            public void run() {
                try {
                    request.setCharacterEncoding("UTF-8");
                } catch (UnsupportedEncodingException e2) {
                    // TODO Auto-generated catch block
                    e2.printStackTrace();
                }
                response.setCharacterEncoding("UTF-8");
                try {
                    writer = response.getWriter();
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                try {
                    // get access to file that is uploaded from client
                    Part p1 = request.getPart("File");
                    InputStream is = p1.getInputStream();

                    // read filename which is sent as a part
                    Part p2  = request.getPart("MetaData");
                    Scanner s = new Scanner(p2.getInputStream());
                    String stringJson = s.nextLine();    // read filename from stream
                    s.close();

                    json = new JSONObject(stringJson);
                    fileName = new String(json.getString("FileName").getBytes("UTF-8"));
                    fileDirectory = BASE + request.getSession().getId();
                    File dir = new File(fileDirectory);
                    dir.mkdir();
                    // get filename to use on the server
                    String outputfile = BASE + dir.getName() + "/" + fileName;  // get path on the server
                    FileOutputStream os = new FileOutputStream (outputfile);

                    // write bytes taken from uploaded file to target file
                    byte[] buffer = new byte[1024];
                    int ch = is.read(buffer);
                    while (ch != -1) { 
                        os.write(buffer);
                        ch = is.read(buffer);
                    }
                    os.close();
                    is.close();
                }
                catch(Exception ex) {
                    writer.println("Exception -->" + ex.getMessage());
                }
                finally { 
                    try {
                        myRequest = request;
                        try {
                            printFile(request.getSession().getId());
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            writer.println("Exception -->" + e.getMessage());
                        }
                        writer.close();
                    } catch (InterruptedException e) {
                        writer.println("Exception -->" + e.getMessage());
                    }
                }               
            }
        }.run();

    }

tomcat 服务器作为虚拟机在 Ubuntu 13.04 上运行。
有什么想法吗?

【问题讨论】:

  • 除非你真的知道自己在做什么,否则不要在 servlest 中做线程。 (是的,我看到您在发布的示例中删除了线程调用,但是您为什么还要打扰 Runnable?)不要相信客户端也忠实地返回 jsessionid cookie,并且永远不要将未经处理的请求内容传递给系统函数,就像您不会将其传递给数据库一样。

标签: java servlets


【解决方案1】:

我不认为使用 Runnable 有什么不同,但它有点毫无意义。我看不到你在哪里声明了你的作家。如果这是 servlet 的一个实例变量(即不在 post 方法中),那么当两个会话同时使用时,它很容易发生会话交换。尝试在 post 方法中声明它。

【讨论】:

  • 谢谢我的朋友!!问题是声明的地方!我将 PrintWriter 声明为全局变量。现在一切都很好!
【解决方案2】:

您不需要实现 Runnable。默认情况下,Servlet 是线程安全的,这意味着为每个请求创建一个新线程。如果您使用一些静态变量,请确保以线程安全的方式使用它们。我认为您的线程创建可能会困扰 tomcat/container 以不正确的方式发送响应。简而言之,我相信您所做的超出了我们的要求,容器就在您身边。

【讨论】:

    【解决方案3】:

    任何 Web 容器都管理 servlet 的多线程。您无需实现自己的线程。从您的代码中删除多线程,它将完美地工作。

    【讨论】:

    • 我一开始写的时候没有 Runnable,当 2 个设备同时发送文件时,其中一个设备总是收到一条空消息。但我会再给它一次机会。
    • 正如 howiewylie 提到的,将 writer 声明移动到 doPost 方法中。
    猜你喜欢
    • 2015-01-17
    • 1970-01-01
    • 2016-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-08
    • 1970-01-01
    相关资源
    最近更新 更多