vida sirve servlet que proyecto para ejemplo desde completo ciclo cero aplicacion java rest spring-mvc servlets jax-rs

java - proyecto - que es un servlet y para que sirve



Razones para no escribir directamente Servlets para crear una API REST (4)

En mi empresa actual estamos iniciando un nuevo proyecto que será una API REST en Java, implementada en un contenedor de servlets como Tomcat. En mi experiencia previa en el uso de marcos REST como JAX-RS con Jersey, JBOSS REST Easy, Spring MVC, sé cuáles son algunas de las ventajas de usar un marco como los que escriben directamente los Servlets para procesar las solicitudes.

(Por supuesto, sabemos que los marcos mencionados todavía usan Servlets debajo de las cubiertas)

Me resulta difícil convencerlos. Ya que están proponiendo escribir servlets pensando que es mejor para el rendimiento (lo que puede ser el caso, pero creo que la sobrecarga de usar uno de esos marcos debería ser insignificante para una API REST).

Aquí están mis razones:

1) Menos repetitivo y código más conciso (que es más fácil de mantener y probar). Con un marco JAX-RS o SpringMVC puede definir un recurso REST muy fácilmente escribiendo métodos con anotaciones que indiquen el PATH del recurso, el método http a utilizar, los parámetros de consulta y url, encabezados como codificación aceptada, etc.

Ejemplo:

@GET @Path("/users") @Produces({MediaType.APPLICATION_JSON}) public UserList getUsers(@QueryParam("group") String group) { return userService.findUsers(group); }

Con los servlets necesitarás al menos algo como esto:

Asigne la url para cada servlet en web.xml (que no es necesario en Servlet 3.0 o superior):

<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>

Luego dentro de la clase 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) Adaptabilidad . Los marcos mencionados le permiten agregar fácilmente funciones a su aplicación que, de lo contrario, tendrá que hacerlo manualmente, como el uso de múltiples entradas y salidas de tipo de medios. Por ejemplo, hacer un servicio para devolver xml o json o cualquier otro dependiendo del encabezado de aceptación. Los marcos como SpringMVC y Jersey facilitan la configuración de serializadores / deserializadores para sus solicitudes y respuestas.

3) Mejores prácticas REST . Normalmente, esos marcos se construyen sobre una sólida comprensión de las mejores prácticas que debe seguir una API REST y se definen en función de los estándares de la arquitectura REST, lo que facilita la creación de una aplicación compatible sólida y estándar. Por otro lado, los Servlets le brindan un alto nivel de libertad sobre cómo procesar sus solicitudes / respuestas, por lo que será más difícil darse cuenta de que no está RECIBIENDO nada.

¿Cualquier otro?


Déjame jugar al abogado del diablo con mi respuesta.

Primero, no es necesario agregar los servlets al archivo web.xml. Los Servlets 3.0 le permiten usar annotations .

En segundo lugar, realmente hay un impacto significativo en el rendimiento con estos marcos. Ver estos puntos de referencia

En tercer lugar, puede usar GSON dentro de un servlet, que es más rápido que Jackson (usado de manera predeterminada en Spring y Jersey). Esto le brinda aún más rendimiento, especialmente considerando que el rendimiento es crítico para sus requisitos.

Finalmente, si le preocupa la repetición, coloque el código que escribió dentro del servlet en alguna clase de utilidad y utilícelo desde múltiples servlets. Eso es mejor que cargar con la enorme carga de un framework cuando usted (como la mayoría de las personas) probablemente esté usando una pequeña fracción de su funcionalidad.


Hace varios meses publiqué un comentario que decía que estaba a favor de la solución Servlet 3.0 pura contra el uso de los marcos de trabajo RES MVC.

Después de meses de uso, confirmo mi elección!

Intenté instalar los marcos de Jackson y otros, pero requiere más trabajo que escribir las 5 líneas de código adicionales y no tengo que lidiar con un componente de software adicional para configurar, aprender, actualizar ...

Aquí está mi ejemplo de trabajo:

package example; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.gson.Gson; /**@WebServlet(name = "booking", urlPatterns = { "/api/v1/booking" })*/ public class BookingWs extends javax.servlet.http.HttpServlet { public static final Logger LOGGER = LoggerFactory.getLogger(BookingWs.class); protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { // Used for JSON handling Gson gson = new Gson(); // De-serialize from request BookingRequest bRequest = gson.fromJson(request.getReader(), BookingRequest.class); // Do your business logic. BookingResponse bResponse = new BookingResponse(); bResponse.request = bRequest; bResponse.accepted = "bar".equalsIgnoreCase(bRequest.type); bResponse.reason = bResponse.accepted ? "Welcome" : "Only bar table booking left"; // Serialize and send response back; response.setContentType("application/json"); PrintWriter pw = response.getWriter(); gson.toJson(bResponse, pw); } catch (Throwable t) { response.setStatus(500); PrintWriter pw = response.getWriter(); pw.write("{/"error/":/"" + t.getLocalizedMessage() + "/"}"); } } } class BookingRequest{ String type; int seats; String name; long requiredTimestamp; } class BookingResponse{ BookingRequest request; boolean accepted; String reason; }

Tal vez estos marcos tengan una característica que necesitas absolutamente, pero para mí debería ser lo suficientemente decisiva como para que valga la pena la molestia de las librerías extra.

Como dijo un autor francés, Antoine de Saint Exupery:

"La perfección se logra no cuando no hay nada más que agregar, sino cuando no hay nada que quitar".

Me llevé a Jackson para acercarme a él :-)

(Sí, debo admitir que usé GSON, pero es un frasco pequeño, sin necesidad de configuración).


Para mí, la verdadera ventaja de usar Spring MVC es el aumento de la productividad. Escribir todo desde cero para sintonizar las cosas tiene sentido si necesita una aplicación realmente personalizada. Aunque puede ser genial crear algo nuevo sin marcos, cuando crezca, enfrentará problemas que ya fueron resueltos por cientos de desarrolladores muy buenos. El uso de Spring MVC le ahorrará una gran cantidad de tiempo que probablemente perdería reinventando la rueda y aún más tiempo cuando tendrá que entrenar a alguien para lidiar con su increíble código personalizado.


Primero, consideraría configurar una prueba simple con dos aplicaciones que tienen un servlet "Hello World": uno con servlets puros, uno con Spring MVC o Apache CXF o el marco de su elección. Luego ejecute una prueba de rendimiento para demostrar (con suerte) que el impacto de rendimiento es insignificante.

Además, los serializadores y deserializadores son un buen ejemplo, pero el patrón de interceptor / filtro que está disponible en estos marcos también es muy útil para otras cosas:

  • Autenticación / Seguridad
  • Registro de solicitudes en bruto si es necesario
  • Transformaciones de encabezado y contenido que se pueden mantener separadas de la lógica empresarial

Además, hay herramientas que se conectan a estos marcos que generarán documentación (WADLs / WSDLs / Enunciate) y bibliotecas de clases de clientes. También hay bibliotecas de pruebas que se pueden utilizar para generar pruebas automatizadas en marcos bien conocidos.

Solía ​​reinventar la rueda también. Pero ya no tiene sentido (si alguna vez lo hizo).