我正在编写一个简单的servlet。它只打印用户传递的值或相应的URL参数。现在,在实现doGet方法时,我看到同样的功能也可以通过服务方法执行。它的代码如下:
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
PrintWriter o = resp.getWriter();
String user = req.getParameter("username");
HttpSession session = req.getSession();
ServletContext context = req.getServletContext();
if (user != "" && user != null) {
session.setAttribute("myhuzu", user);
context.setAttribute("myhuzu", user);
}
o.println("request parameter has value " + user);
o.println("session parameter has user name as "
+ session.getAttribute("myhuzu"));
o.println("context parameter has user name as "
+ context.getAttribute("myhuzu"));
o.println("init parameter has user name as "
+ getServletConfig().getInitParameter("default"));
}
}
所以我的问题是,为什么我们需要doGet或doPOST方法,当服务方法本身正在处理所有这些事情时。由于上面的代码运行完美,如果保存在doGet方法中它也运行完美,那么为什么呢din只保留了其中一个? 注意:我非常了解servlet生命周期和其他相关概念,所以请不要解释所有这些概念。
答案 0 :(得分:4)
HttpServlet类中的服务方法检查哪个方法在head请求中并重定向到指定的方法,就像调用doGet方法的get请求时一样,当servlet以不同的方法回答不同的方法时使用它,就像在REST服务中一样,当您有GET请求时,您将返回一个信息,但是当您有PUT请求时,您将更新信息,因此servlet会为您提供此方法。
另外,它保证你的servlet不会回答错误的请求,使用像你一样的服务方法,即使有一个奇怪的请求,比如“请求方法TEST”,servlet也会响应,并保持servlet的响应状态你的代码更清洁。
查看原始服务代码:
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getMethod();
long errMsg;
if(method.equals("GET")) {
errMsg = this.getLastModified(req);
if(errMsg == -1L) {
this.doGet(req, resp);
} else {
long ifModifiedSince = req.getDateHeader("If-Modified-Since");
if(ifModifiedSince < errMsg) {
this.maybeSetLastModified(resp, errMsg);
this.doGet(req, resp);
} else {
resp.setStatus(304);
}
}
} else if(method.equals("HEAD")) {
errMsg = this.getLastModified(req);
this.maybeSetLastModified(resp, errMsg);
this.doHead(req, resp);
} else if(method.equals("POST")) {
this.doPost(req, resp);
} else if(method.equals("PUT")) {
this.doPut(req, resp);
} else if(method.equals("DELETE")) {
this.doDelete(req, resp);
} else if(method.equals("OPTIONS")) {
this.doOptions(req, resp);
} else if(method.equals("TRACE")) {
this.doTrace(req, resp);
} else {
String errMsg1 = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[]{method};
errMsg1 = MessageFormat.format(errMsg1, errArgs);
resp.sendError(501, errMsg1);
}
}
根据使用的请求方法,它会有不同的反应。
如果您执行自定义http请求,您可以设置所需的方法,而不是GET或PUT或DELETE,您可以发送TEST,您的服务将抛出“Method not implementation”异常,但是如果您覆盖服务方法它很简单,无论如何都会执行你的servlet代码。
答案 1 :(得分:1)
你有doGet和doPost,这样servlet可以根据访问时使用的HTTP动词以不同的方式做出反应。
规范还定义了doHead,doOptions等。
答案 2 :(得分:1)
您可能希望以某种方式回复GET
请求,并在某种程度上回复POST
请求。GET
请求通常仅用于获取数据和给它回来。POST
请求是为了更新后端的某些东西。这就是为什么它被称为幂等。
但是,如果您改写了服务方法,那么您将只有一种响应方式。
答案 3 :(得分:0)
服务方法可以同时提供Get和Post请求。
但是,让我们假设您希望确保除了使用POST请求之外没有人调用您的servlet, 例如:提交登录请求时
如果您允许任何人在这种情况下使用GET;您将制造严重的安全漏洞(因为GET请求将显示URL中的所有登录信息)
所以你实施POST方法作为保证。