在我目前的公司,我们正在启动一个新项目,该项目将是 Java 中的 REST API,部署在像 Tomcat 这样的 servlet 容器中。在我之前使用 JAX-RS 和 Jersey、JBOSS REST Easy、Spring MVC 等 REST 框架的经验中,我知道使用像直接编写 Servlet 来处理请求这样的框架有哪些优势。
(当然我们知道上面提到的框架仍然使用 Servlet)
我发现很难说服他们。因为他们提议编写 servlet,认为它对性能更好(可能是这种情况,但我认为使用其中一个框架的开销对于 REST API 来说应该是微不足道的)。
这是我的理由:
1) 样板更少,代码更简洁(更易于维护和测试)。使用 JAX-RS 框架或 SpringMVC,您可以通过编写带有注释的方法来非常轻松地定义 REST 资源,这些注释指示资源的 PATH、要使用的 http 方法、查询和 url 参数、接受的编码等 header 等。
例子:
@GET
@Path("/users")
@Produces({MediaType.APPLICATION_JSON})
public UserList getUsers(@QueryParam("group") String group) {
return userService.findUsers(group);
}
使用 servlet,您至少需要这样的东西:
在 web.xml 中为每个 servlet 映射 url(这在 Servlet 3.0 及以上版本中不是必需的):
<servlet>
<servlet-name>UsersServlet</servlet-name>
<servlet-class>test.UsersServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UsersServlet</servlet-name>
<url-pattern>/users</url-pattern>
</servlet-mapping>
然后在servlet类里面:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String group = request.getParameter("group");
response.setContentType("application/json");
PrintWriter out = response.getWriter();
JsonSerializer someJsonSerializer = new JsonSerializer();
String json = someJsonSerializer.serialize(userService.findUsers(group));
out.print(json);
}
2) 适应性。提到的框架允许您轻松地向应用程序添加功能,否则您将需要手动完成,例如使用多种媒体类型输入和输出。例如,根据接受 header 制作服务以返回 xml 或 json 或任何其他内容。 SpringMVC 和 Jersey 等框架使为您的请求和响应配置序列化器/反序列化器变得非常容易。
3) REST 最佳实践。通常,这些框架是基于对 REST API 遵循的最佳实践的深入理解而构建的,并且是基于 REST 架构的标准定义的,这使得构建一个可靠且符合标准的应用程序变得更加容易。另一方面,Servlet 在如何处理请求/响应方面为您提供了非常高的自由度,以至于您更难以意识到您根本不是 RESTfull。
还有其他的吗?
最佳答案
让我用我的回答来扮演魔鬼的拥护者。
首先,您不需要将 servlet 添加到 web.xml 文件中。 Servlets 3.0 允许您使用 annotations .
其次,这些框架确实会对性能产生重大影响。见 these benchmarks
第三,可以使用GSON在一个 servlet 中,它比 Jackson 更快(在 Spring 和 Jersey 中默认使用)。这可以让您获得更高的性能,尤其是考虑到性能对您的要求至关重要。
最后,如果您担心样板,请将您编写的代码放在某个实用程序类中的 servlet 中,并在多个 servlet 中使用它。当您(像大多数人一样)可能会使用框架的一小部分功能时,这胜过承担框架的巨大负载。
关于java - 不直接编写 Servlet 来创建 REST API 的原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21947300/