有一个程序A通过url调用Servlet,如果响应不成功(比如程序里访问url的时候产生网络问题、超时等等情况)就再调用一次。
应用中出现这种情况:程序A实际第一次就调用成功了Servlet的url,但是由于Servlet内部程序执行时间太长,迟迟没有给程序A响应,造成程序A以为没有成功,又重复调用了一次url。结果是调用了两次,重复了。
现在想去掉这种重复,有两个思路:
思路1、程序A通过url调用Servlet时立刻返回正确响应,告诉程序A已经成功访问Servlet了,不需要再重复调用了。Servlet这边自己负责自己的代码是否执行成功,就是虽然告诉程序A调用成功了,但Servlet执行过程中还有可能出现问题,不过跟程序A已经没有关系了。我通过直接关闭response实现这个思路
[code="java"]
Servlet{
doGet(){
response.setHeader("Content-type", "text/html;charset=UTF-8");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
out.println("OK" );
out.flush();
out.close();
...其他程序...
}
}
[/code]
这样只要访问这个Servlet的网络是正常的,程序A调用这个url基本就不会出问题,也就避免了重复发送的问题。但是Servlet内部如果出错了程序A也就不知道了,需要Servlet自己来做错误处理。
思路2、在Servlet里面可以用集合做一个缓存,调用一次记录一个request带的参数,这样如果重复调用的话就匹配这个集合,如果集合中存在参数就不执行了。
再开启一个线程,用线程去处理Servlet里的业务功能,Servlet自身只需要返回正确响应就可以了。
这样的话程序A调用Servlet的url应该也不会有问题,因为业务逻辑被另一个线程处理,出了问题不影响Servlet,也就不影响程序A的响应了。
我的想法是如果第一种方法可行,那就没必要再开启一个线程了。因为Servlet在Tomcat中也是由Tomcat开启多个线程的,反正思路1已经给调用Servlet的程序A返回正确响应了,在Tomcat开启的一个Servlet线程中处理业务逻辑也就不会影响上级调用程序了,所以思路1可以更简单实现需求的功能。
不知我是否描述清楚了?我的想法是否可行?建议用思路1还是2呢?
再求证一个事情:程序内部通过url调用Servlet时,Servlet在什么情况下返回响应,是在Servlet所有代码执行完吗?还是在response的输出流关闭的时候?如果跟容器有关,那么我想知道Tomcat的实现。