在阅读HttpServlet源码过程中,发现doOptions()方法设计好像有点问题,暂时不清楚原因。
源码流程:
1、获取servlet重写方法列表(重写方法示例:service()、doGet()、doPost()...)
2、判断methods是否包含get、post、put、delete四个请求处理方法,计算对应allow值(allow_get、allow_post...)
3、根据allow值拼接输出内容,设置到response响应头部(示例:Allow: GET, POST, PUT, DELETE)
问题:
在上述第二步中,多重if语句应该改为if-else语句比较好,毕竟method.name值不会被修改,只能是doGet、doPost、doPut、doDelete四个值中的一种。
暂不清楚为什么servlet源码这么设计。
for (int i=0; i<methods.length; i++) {
Method m = methods[i];
if (m.getName().equals("doGet")) {
ALLOW_GET = true;
ALLOW_HEAD = true;
}
if (m.getName().equals("doPost")) {
ALLOW_POST = true;
}
if (m.getName().equals("doPut")) {
ALLOW_PUT = true;
}
if (m.getName().equals("doDelete")) {
ALLOW_DELETE = true;
}
}
源码:
protected void doOptions(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException {
//1.获取servlet重写方法列表
Method[] methods = getAllDeclaredMethods(this.getClass());
boolean ALLOW_GET = false;
boolean ALLOW_HEAD = false;
boolean ALLOW_POST = false;
boolean ALLOW_PUT = false;
boolean ALLOW_DELETE = false;
boolean ALLOW_TRACE = true;
boolean ALLOW_OPTIONS = true;
//trace相关代码省略...
//2.判断methods是否get、post、put、delete四个请求处理方法
for (int i=0; i<methods.length; i++) {
Method m = methods[i];
if (m.getName().equals("doGet")) {
ALLOW_GET = true;
ALLOW_HEAD = true;
}
if (m.getName().equals("doPost")) {
ALLOW_POST = true;
}
if (m.getName().equals("doPut")) {
ALLOW_PUT = true;
}
if (m.getName().equals("doDelete")) {
ALLOW_DELETE = true;
}
}
//3.根据请求方法对应的allow状态值拼接内容,设置到响应头部。
//最终结果示例:Allow:GET, POST, PUT, DELETE
String allow = null;
if (ALLOW_GET) {
allow=METHOD_GET;
}
if (ALLOW_HEAD) {
if (allow==null) {
allow=METHOD_HEAD;
} else {
allow += ", " + METHOD_HEAD;
}
}
if (ALLOW_POST) {
if (allow==null) {
allow=METHOD_POST;
} else {
allow += ", " + METHOD_POST;
}
}
if (ALLOW_PUT) {
if (allow==null) {
allow=METHOD_PUT;
} else {
allow += ", " + METHOD_PUT;
}
}
if (ALLOW_DELETE) {
if (allow==null) {
allow=METHOD_DELETE;
} else {
allow += ", " + METHOD_DELETE;
}
}
if (ALLOW_TRACE) {
if (allow==null) {
allow=METHOD_TRACE;
} else {
allow += ", " + METHOD_TRACE;
}
}
if (ALLOW_OPTIONS) {
if (allow==null) {
allow=METHOD_OPTIONS;
} else {
allow += ", " + METHOD_OPTIONS;
}
}
resp.setHeader("Allow", allow);
}