gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 06:05:47 24 4
gpt4 key购买 nike

我在 Tomcat 上使用 Java Servlet 编写了一些 REST API。这是我第一次接触 Java、API 和 Tomcat。当我研究和阅读有关 servlet、方法和参数传递以及最近的线程安全性的内容时,我意识到我需要来自那些我认为更有经验的人的一些评论、建议和教程指导。我发现了许多问题/答案,这些问题/答案似乎都能解决问题,但我缺乏经验,无法实现我想要的清晰度。

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

  1. 这些全局变量是否会创建不安全的线程环境
  2. 由于响应在私有(private)方法中不可见,如果这些全局变量不安全,我该如何确定是否需要停止进程并发送错误响应
  3. 虽然节省了空间,但我是否应该在 doGet 方法中执行所有 XML 处理
  4. 我是否应该为各种数据检索任务和数据处理调用所有不同的私有(private)方法
  5. 访问同一数据库的每个方法都应该打开一个连接,还是 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();
}

最佳答案

I have "global" variables defined at the class level

您有在类级别声明的实例变量。 Java 中没有全局变量。

so that I may track the success of a method and determine if I need to send an error response.

技术差

I do this because the method(s) already return a value.

如果返回值已被获取,您应该为此使用异常。

Are those global variables creating an unsafe thread environment

这些实例变量正在创建一个不安全的线程环境。

Since the response is not visible in the private methods, how else might I determine the need to stop the process and send an error response if those global variables are unsafe?

通过方法抛出异常,请参见上文。如果没有异常,则发送 OK 响应,无论采用何种形式,否则发送适合该异常的任何错误响应。

Though clipped for space, should I be doing all of the XML handling in the doGet method

如果它很长或重复(也在其他地方使用),则不可以。

Should I be calling all of the different private methods for the various data retrieval tasks and data handling

当然,为什么不呢?

Should each method that accesses the same database open a Connection or should the doGet() method create a Connection and pass it to each method

doGet() 应该打开连接,将其传递给每个方法,然后准确地关闭它。

注意,您不需要 ServletConfig 变量,或者 init()getServletConfig() 方法。如果删除所有这些,您可以在需要时通过毫无意义地重写的 getServletConfig() 方法从基类中获取它。

关于Java Servlet 方法参数、响应和线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51371740/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com