it-swarm.com.de

Gründe für das direkte Schreiben von Servlets für die Erstellung eines REST API

In meiner jetzigen Firma beginnen wir ein neues Projekt, das eine REST - API in Java ist, die in einem Servlet-Container wie Tomcat bereitgestellt wird. In meiner früheren Erfahrung mit REST - Frameworks wie JAX-RS mit Jersey, JBOSS REST - Easy, Spring-MVC. Ich weiß, welche Vorteile es hat, ein Framework wie dasjenige zu verwenden, das direkt über die Servlets geschrieben wird Anfragen. 

(Natürlich wissen wir, dass die genannten Frameworks immer noch Servlets unter der Abdeckung verwenden.)

Es fällt mir schwer, sie zu überzeugen. Da sie vorschlagen, Servlets zu schreiben, denken, es ist besser für die Leistung (was zwar der Fall sein kann, aber ich denke, der Aufwand für die Verwendung eines dieser Frameworks sollte für eine REST - API unbedeutend sein).

Hier sind meine Gründe:

1) Weniger Boilerplate und prägnanterer Code (der einfacher zu warten und zu testen ist). Mit einem JAX-RS-Framework oder SpringMVC können Sie eine Ressource REST sehr leicht definieren, indem Sie Methoden schreiben, deren Anmerkungen den PFAD der Ressource, die zu verwendende http-Methode, die Abfrage- und URL-Parameter, Header wie akzeptierte Codierung usw. enthalten.

Beispiel:

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

Bei Servlets brauchst du mindestens so etwas:

Ordnen Sie die URL für jedes Servlet in web.xml zu (was in Servlet 3.0 und darüber nicht erforderlich ist):

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

Dann in der Servlet-Klasse:

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) Anpassungsfähigkeit. Mit den genannten Frameworks können Sie der Anwendung auf einfache Weise Funktionen hinzufügen, die Sie sonst manuell ausführen müssen, z. B. die Verwendung mehrerer Ein- und Ausgänge des Medientyps. Beispiel: Erstellen eines Dienstes zum Zurückgeben von XML oder Json oder einem anderen abhängig vom Accept-Header. Durch Frameworks wie SpringMVC und Jersey ist es sehr einfach, Serialisierer/Deserializer für Ihre Anfragen und Antworten zu konfigurieren.

3) REST Best Practices. Normalerweise basieren diese Frameworks auf einem soliden Verständnis der besten Vorgehensweisen, denen eine REST - API befolgt werden muss, und werden auf der Grundlage von Standards der REST -Architektur definiert, die das Erstellen einer soliden und standardkonformen Anwendung erleichtert. Auf der anderen Seite geben Ihnen Servlets ein so hohes Maß an Freiheit bei der Bearbeitung Ihrer Anfragen/Antworten, dass es schwieriger zu erkennen ist, dass Sie überhaupt nicht RESTfull sind.

Sonst noch?

20
raspacorp

Lassen Sie mich mit meiner Antwort den Befürworter des Teufels spielen.

Erstens müssen Sie die Servlets nicht zur Datei web.xml hinzufügen. In Servlets 3.0 können Sie Anmerkungen verwenden. 

Zweitens gibt es bei diesen Frameworks wirklich einen erheblichen Performance-Schlag. Siehe diese Benchmarks

Drittens können Sie GSON in einem Servlet verwenden, das ist schneller als Jackson (standardmäßig in Spring und Jersey verwendet). Dies bringt Ihnen noch mehr Leistung, vor allem wenn man bedenkt, dass Leistung für Ihre Anforderungen von entscheidender Bedeutung ist.

Wenn Sie sich Sorgen um Boilerplate machen, fügen Sie den Code, den Sie in das Servlet geschrieben haben, in eine Dienstprogrammklasse ein und verwenden Sie ihn von mehreren Servlets. Wenn Sie (wie die meisten Leute) wahrscheinlich nur einen kleinen Bruchteil ihrer Funktionalität nutzen würden, ist dies eine gewaltige Last für das Framework. 

27
stepanian

Zuerst würde ich mir überlegen, einen einfachen Test mit zwei Anwendungen zu erstellen, die ein "Hello World" -Servlet haben - eine mit reinen Servlets, eine mit Spring MVC oder Apache CXF oder Ihr bevorzugtes Framework. Führen Sie dann einen Leistungstest durch, um (hoffentlich) zu beweisen, dass der Leistungstreff unerheblich ist.

Serialisierer und Deserialisierer sind ein gutes Beispiel, aber das in diesen Frameworks verfügbare Interceptor/Filter-Muster ist auch für andere Zwecke sehr nützlich:

  • Authentifizierung/Sicherheit
  • Protokollierung von Rohanforderungen, falls erforderlich
  • Header- und Inhaltstransformationen, die von der Geschäftslogik getrennt werden können

Darüber hinaus gibt es Tools, die sich in diese Frameworks einfügen, um Dokumentationsbibliotheken (WADLs/WSDLs/Enunciate) und Client-Klassenbibliotheken zu erstellen. Es gibt auch Testbibliotheken, mit denen automatisierte Tests anhand bekannter Frameworks erstellt werden können.

Ich habe auch das Rad neu erfunden. Aber es macht keinen Sinn mehr (wenn es jemals passiert ist.)

4
Geoff Genz

Vor einigen Monaten habe ich einen Kommentar geschrieben, der besagt, dass ich für die reine Servlet 3.0-Lösung gegen die Verwendung von RES MVC-Frameworks war.

Nach monatelanger Nutzung bestätige ich meine Wahl!

Ich habe versucht, Jackson und andere Frameworks zu installieren, aber es erfordert mehr Arbeit als das Schreiben der zusätzlichen 5 Zeilen Code, und ich muss nicht mit einer zusätzlichen Software-Komponente zurechtkommen, um sie einzurichten, zu lernen, zu aktualisieren ...

Hier ist mein Arbeitsbeispiel:

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

Vielleicht haben diese Frameworks eine Funktion, die Sie unbedingt benötigen, aber für mich sollte es entscheidend sein, den Aufwand zusätzlicher Bibliotheken zu verdienen.

Als französischer Schriftsteller sagte Antoine de Saint Exupery:

"Perfektion wird nicht erreicht, wenn nichts mehr hinzuzufügen ist, sondern es gibt nichts mehr zum Mitnehmen".

Ich habe Jackson mitgenommen, um näher dran zu kommen :-)

(Ja, ich muss zugeben, ich habe GSON verwendet, aber es ist ein kleines Gefäß, ohne dass eine Konfiguration erforderlich ist).

2
Orden

Der wirkliche Vorteil des Einsatzes von Spring MVC ist für mich die Steigerung der Produktivität. Schreiben Sie alles von Grund auf, um die Abstimmung zu optimieren, ist es sinnvoll, wenn Sie eine wirklich individuelle Anwendung benötigen. Obwohl es cool sein kann, etwas Neues ohne Frameworks zu erstellen, werden Sie, wenn es größer wird, auf Probleme stoßen, die bereits von Hunderten verdammt guter Entwickler gelöst wurden. Wenn Sie Spring MVC verwenden, sparen Sie viel Zeit, die Sie wahrscheinlich mit der Neuerfindung des Rades verschwenden würden, und noch mehr Zeit, wenn Sie jemanden trainieren müssen, der sich mit Ihrem fantastischen benutzerdefinierten Code auskennt. 

0
Pedreiro