JavaServlet方法参数、响应和线程安全

JavaServlet方法参数、响应和线程安全,java,servlets,Java,Servlets,我已经在Tomcat上使用Javaservlet编写了一些RESTAPI。这是我第一次使用Java、API和Tomcat。当我研究和阅读servlet、方法和参数传递,以及最近的线程安全时,我意识到我需要你们中那些经验丰富得多的人的一些评论、建议和指导。我发现很多问题/答案似乎都是针对某个片段的,但我缺乏经验,这让我无法清晰地表达自己的想法 下面的代码显示了一个servlet示例的顶部以及一个示例私有方法。我在类级别定义了“全局”变量,以便跟踪方法的成功情况并确定是否需要发送错误响应。我这样做是

我已经在Tomcat上使用Javaservlet编写了一些RESTAPI。这是我第一次使用Java、API和Tomcat。当我研究和阅读servlet、方法和参数传递,以及最近的线程安全时,我意识到我需要你们中那些经验丰富得多的人的一些评论、建议和指导。我发现很多问题/答案似乎都是针对某个片段的,但我缺乏经验,这让我无法清晰地表达自己的想法

下面的代码显示了一个servlet示例的顶部以及一个示例私有方法。我在类级别定义了“全局”变量,以便跟踪方法的成功情况并确定是否需要发送错误响应。我这样做是因为方法已经返回了一个值

  • 这些全局变量是否创建了不安全的线程环境
  • 由于响应在私有方法中不可见,如果这些全局变量不安全,我如何确定是否需要停止进程并发送错误响应
  • 虽然空间有限,但我应该在doGet方法中完成所有的XML处理吗
  • 我应该为各种数据检索任务和数据处理调用所有不同的私有方法吗
  • 访问同一数据库的每个方法是打开一个连接,还是doGet方法创建一个连接并将其传递给每个方法
  • 协助、建议、教授、指导您认为合适的内容,或为我指出正确的学习资源,以便我可以学习如何做得更好。欢迎直接和建设性的批评——不喜欢抨击和贬损性的言论

    @WebServlet(name = "SubPlans", urlPatterns = {"*omitted*"})
    public class SubPlans extends HttpServlet {
    
      private transient ServletConfig servletConfig;
      private String planSpecialNotes,
          planAddlReqLinks,
          legalTermsHeader,
          legalTermsMemo,
          httpReturnMsg;
      private String[] subPlanInd = new String[4];
      private boolean sc200;
      private int httpReturnStatus;
    
      private static final long serialVersionUID = 1L;
    
      {
        httpReturnStatus = 0;
        httpReturnMsg = "";
        sc200 = true;
        planAddlReqLinks = null;
        planSpecialNotes = null;
        legalTermsHeader = "";
        legalTermsMemo = null;
      }
    
      @Override
      public void init(ServletConfig servletConfig)
          throws ServletException {
        this.servletConfig = servletConfig;
      }
    
      @Override
      public ServletConfig getServletConfig() {
        return servletConfig;
      }
    
      @Override
      public String getServletInfo() {
        return "SubPlans";
      }
    
      @Override
      public void doGet(HttpServletRequest request, HttpServletResponse   response)
          throws ServletException, IOException {
        List<HashMap<String, Object>> alSubDeps = new ArrayList<HashMap<String, Object>>();
        String[] coverageDates = new String[6],
            depDates = new String[8];
        String eeAltId = null,
            eeSSN = null,
            carrier = null,
            logosite = null,
            fmtSSN = "X",
            subSQL = null,
            healthPlan = null,
            dentalPlan = null,
            visionPlan = null,
            lifePlan = null,
            tier = null,
            healthGroupNum = null,
            effdate = null,
            holdEffDate = null,
            planDesc = "",
            planYear = "",
            summaryBenefitsLink = null;
        int[][] effdates = new int[6][4];
        int holdDistrictNumber = 0,
            districtNumber = 0,
            holdUnit = 0,
            unit = 0;
        boolean districtHasHSA = false;
        XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
        try {
          eeAltId = request.getParameter("*omitted*");
          if ( eeAltId != null ) {
            Pattern p = Pattern.compile(*omitted*);
            Matcher m = p.matcher(eeAltId);
            if ( m.find(0) ) {
              eeSSN = getSSN(eeAltId);
            } else {
              httpReturnStatus = 412;
              httpReturnMsg = "Alternate ID format incorrect.";
              System.err.println("Bad alternate id format " + eeAltId);
              sc200 = false;
            }
          } else {
            httpReturnStatus = 412;
            httpReturnMsg = "Alternate ID missing.";
            System.err.println("alternate id not provided.");
            sc200 = false;
          }
          if ( sc200 ) {
            coverageDates = determineDates();
            subSQL = buildSubSQLStatement(eeSSN, coverageDates);
            alSubDeps = getSubDeps(subSQL);
            if ( sc200 ) {
              XMLStreamWriter writer = outputFactory.createXMLStreamWriter(response.getOutputStream());
              writer.writeStartDocument("1.0");
              writer.writeStartElement("subscriber");
         //  CLIPPED //
              writer.writeEndElement();   // subscriber
              writer.writeEndDocument();
              if ( sc200 ) {
                response.setStatus(HttpServletResponse.SC_OK);
                writer.flush();
              } else {
                response.sendError(httpReturnStatus, httpReturnMsg);
              }
            }
          }
        } catch (Exception e) {
          e.printStackTrace();
          System.err.println("Error writing XML");
          System.err.println(e);
        }
      }
      @Override
      public void destroy() {
    
      }
    
      private String getPlanDescription(String planID) {
        String planDesc = null;
        String sqlEE = "SELECT ...";
        Connection connGPD = null;
        Statement stGPD = null;
        ResultSet rsGPD = null;
        try {
          connGPD = getDbConnectionEE();
          try {
            stGPD = connGPD.createStatement();
            planDesc = "Statement error";
            try {
              rsGPD = stGPD.executeQuery(sqlEE);
              if ( !rsGPD.isBeforeFirst() )
                planDesc = "No data";
              else {
                rsGPD.next();
                planDesc = rsGPD.getString("Plan_Description");
              }
            } catch (Exception rsErr) {
              httpReturnStatus = 500;
              httpReturnMsg = "Error retrieving plan description.";
              System.err.println("getPlanDescription: " + httpReturnMsg + " " + httpReturnStatus);
              System.err.println(rsErr);
              sc200 = false;
            } finally {
              if ( rsGPD != null ) {
                try {
                  rsGPD.close();
                } catch (Exception rsErr) {
                  System.err.println("getPlanDescription: Error closing result set.");
                  System.err.println(rsErr);
                }
              }
            }
          } catch (Exception stErr) {
            httpReturnStatus = 500;
            httpReturnMsg = "Error creating plan description statement.";
            System.err.println("getPlanDescription: " + httpReturnMsg + " " + httpReturnStatus);
            System.err.println(stErr);
            sc200 = false;
          } finally {
            if ( stGPD != null ) {
              try {
                stGPD.close();
              } catch (Exception stErr) {
                System.err.println("getPlanDescription: Error closing query statement.");
                System.err.println(stErr);
              }
            }
          }
        } catch (Exception connErr) {
          httpReturnStatus = 500;
          httpReturnMsg = "Error closing database.";
          System.err.println("getPlanDescription: " + httpReturnMsg + " " + httpReturnStatus);
          System.err.println(connErr);
          sc200 = false;
        } finally {
          if ( connGPD != null ) {
            try {
              connGPD.close();
            } catch (Exception connErr) {
              System.err.println("getPlanDescription: Error closing connection.");
              System.err.println(connErr);
            }
          }
        }
        return planDesc.trim();
      }
    
    @WebServlet(name=“SubPlans”,urlPatterns={“*省略*”})
    公共类子计划扩展了HttpServlet{
    私有瞬态ServletConfig ServletConfig;
    专用字符串计划专用注释,
    PlanAddlReqLink,
    立法会主席,
    立法会,
    httpReturnMsg;
    私有字符串[]子平面标识=新字符串[4];
    专用布尔sc200;
    私有int-httpReturnStatus;
    私有静态最终长serialVersionUID=1L;
    {
    httpReturnStatus=0;
    httpReturnMsg=“”;
    sc200=真;
    planAddlReqLinks=null;
    planSpecialNotes=null;
    legalTermsHeader=“”;
    legaltermsemo=null;
    }
    @凌驾
    公共void init(ServletConfig ServletConfig)
    抛出ServletException{
    this.servletConfig=servletConfig;
    }
    @凌驾
    公共ServletConfig getServletConfig(){
    返回servletConfig;
    }
    @凌驾
    公共字符串getServletInfo(){
    返回“子计划”;
    }
    @凌驾
    public void doGet(HttpServletRequest请求、HttpServletResponse响应)
    抛出ServletException、IOException{
    List-alSubDeps=new-ArrayList();
    String[]coverageDates=新字符串[6],
    depDates=新字符串[8];
    字符串eeAltId=null,
    eeSSN=null,
    载波=空,
    logosite=null,
    fmtSSN=“X”,
    subSQL=null,
    healthPlan=null,
    dentalPlan=null,
    visionPlan=null,
    生命计划=空,
    层=空,
    healthGroupNum=null,
    effdate=null,
    holdEffDate=null,
    planDesc=“”,
    planYear=“”,
    summaryBenefitsLink=null;
    int[]efffdates=新int[6][4];
    int holdDistrictNumber=0,
    districtNumber=0,
    holdUnit=0,
    单位=0;
    布尔区hashsa=false;
    XMLOutputFactory outputFactory=XMLOutputFactory.newInstance();
    试一试{
    eeAltId=request.getParameter(“*省略*”);
    如果(eeAltId!=null){
    模式p=模式.compile(*省略*);
    匹配器m=p.Matcher(eeAltId);
    如果(m.find(0)){
    eeSSN=getSSN(eeAltId);
    }否则{
    httpReturnStatus=412;
    httpReturnMsg=“备用ID格式不正确。”;
    System.err.println(“错误的备用id格式”+eeAltId);
    sc200=假;
    }
    }否则{
    httpReturnStatus=412;
    httpReturnMsg=“缺少备用ID。”;
    System.err.println(“未提供备用id”);
    sc200=假;
    }
    如果(sc200){
    coverage日期=determineDates();
    subSQL=buildSubSQLStatement(eeSSN,coverageDates);
    alSubDeps=getSubDeps(subSQL);
    如果(sc200){
    XMLStreamWriter writer=outputFactory.createXMLStreamWriter(response.getOutputStream());
    writer.writeStartDocument(“1.0”);
    writer.WriteStarteElement(“认购人”);
    //剪短//
    writer.writeEndElement();//订阅服务器
    writer.writeEndDocument();
    如果(sc200){
    response.setStatus(HttpServletResponse.SC_OK);
    writer.flush();
    }否则{
    sendError(httpReturnStatus,httpReturnMsg);
    }
    }
    }
    }捕获(例外e){
    e、 printStackTrace();
    System.err.println(“写入XML时出错”);
    系统错误println(e);
    }
    }
    @凌驾
    公共空间销毁(){
    }
    私有字符串getPlanDescription(字符串planID){
    字符串planDesc=null;
    字符串sqlEE=“选择…”;
    连接connGPD=null;
    语句stGPD=null;
    结果集rsGPD=null;
    试一试{
    connGPD=getDbConnectionEE();
    试一试{
    stGPD=connGPD.createStatement();
    planDesc=“语句错误”;
    试一试{
    rsGPD=stGPD.executeQuery(sqlEE);
    如果(!rsGPD.isBeforeFirst())
    planDesc=“无数据”;
    否则{
    rsGPD.next();
    planDesc=rsGPD.getString(“计划描述”);
    }
    }捕获(异常rsErr){
    httpReturnStatus=500;
    httpReturnMsg=“检索计划说明时出错。”;
    System.err.println(“getPlanDescription:+httpReturnMsg+”+httpReturnStatus);
    系统错误打印项次(rsErr);
    sc200=假;