代码之家  ›  专栏  ›  技术社区  ›  Keibosh

线程安全Java Servlet

  •  3
  • Keibosh  · 技术社区  · 17 年前

    就线程而言,我需要知道下面的代码是否有任何问题。我一直觉得只要不使用类级变量线程就不是问题。

    public class UploadReferralImage extends HttpServlet
    {
        String CLASS_NAME = "UploadReferralImage";
    
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
       // Not handling Get, service must be invoked via Post.
    }
    
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        String METHOD_NAME = "doPost";
        LogHelper.debug(PACKAGE_NAME, CLASS_NAME, METHOD_NAME, "Made it to the servlet");
        String reply = upload(request);
        response.setHeader("Content-Type", "text/xml");
        response.getWriter().write(reply);
        response.getWriter().flush();
        response.getWriter().close();
    }
    
    public String upload(HttpServletRequest request)
    {
    
        String METHOD_NAME = "upload";
        LogHelper.debug(PACKAGE_NAME, CLASS_NAME, METHOD_NAME, "Inside upload");
        String replyMsg = "Unable to call ImageUpload";
    
        try
        {
            ObjectInputStream inputFromApplet = new ObjectInputStream(request.getInputStream());
            FileBean fBean = (FileBean) inputFromApplet.readObject();
    
            inputFromApplet.close();
            LogHelper.debug(PACKAGE_NAME, CLASS_NAME, METHOD_NAME, fBean.getFileName());
    
            replyMsg = doImageUpload(fBean);
    
            } 
            catch (IOException e)
        {   
            e.printStackTrace();
                replyMsg = "Exception :" + e.toString();
    
        } 
            catch (ClassNotFoundException e)
        {
            e.printStackTrace();
                replyMsg = "Exception :" + e.toString();
        }
    
        return replyMsg;
    }
    
    private String doImageUpload(FileBean fBean)
    {
           //Save the file and return the response
           SaveCaseClientAgent saveCaseClientAgent = new SaveCaseClientAgent();
           saveCaseClientAgent.save(fBean);
    }
    
    2 回复  |  直到 17 年前
        1
  •  3
  •   jjnguy Julien Chastang    17 年前

    你说得对。

    只要您远离使用类级变量, Servlet 将是线程安全的。

    为了安全起见,不妨让你的班级水平 String final :

    final String CLASS_NAME = "UploadReferralImage";
    
        2
  •  1
  •   Marcin    17 年前

    通常,servlet容器中只有一个servlet实例,一次可重新为多个请求提供服务。因此,使用实例变量将事物从一个方法传递到另一个方法是一个BAAD概念,因为存在种族条件。

    解决这个问题的最好(也是最简单)方法是编写自己的“处理程序”类,每个请求实例化一次,然后将所有内容传递给它。在代码中,它看起来是这样的:

    public void doGet(HttpServletRequest req, HttpServletResponse resp) {
       new MyHandler().doGet(req, resp);
    }
    

    现在在 MyHandler 重用实例变量是安全的。