lunedì 13 marzo 2017

JAVA - PARSE JSON FROM SERVLET

Come processare una richiesta JSON lato server in Java.







Serializzazione vs Notazione

La serializzazione è quella tecnica che permette di trasformare una istanza di un oggetto in un formato per la memorizzazione, la cui lettura può ricostruire una copia esatta di quell'oggetto. Esistono molti tipi di formati per serializzare oggetti, alcuni proprietari altri inter operabili con più linguaggi di programmazione. 

Un sottoinsieme della serializzazione è la notazione, equivalente alla serializzazione con la differenza che la prima rappresenta l'istanza completa di un oggetto (classe, metodo, attributo.. quando possibile) mentre la seconda rappresenta il contenuto di un oggetto (attributi semplici o container di altri attributi, come una visione ad albero).

JSON

Nel mondo delle Web Application, i formati di notazione sono ampiamente utilizzati per trasmettere al server dati complessi e strutturati presupponendo di ricevere dal server la risposta nel medesimo formato. In principio XML era il formato di notazione preferito per comunicare fra client-server ma nel tempo è stato sorpassato da JSON [wikipedia] grazie alla sua natura sintetica.

Apache Tomcat 8

La diffusione di JSON però non è stata globale ed immediata tant'è che alcuni linguaggi di programmazione e tecnologie del web hanno iniziato ad adottare JSON tardivamente. Un esempio è Apache Tomcat [link] che solo dalla versione 8 in poi ha iniziato a supportare le richieste HTTP con contenuto JSON.

JSON e Java

Nel mondo Java, l'implementazione di JSON è avvenuta ufficialmente tramite la specifica JSR-353 [link] nel 2012 anche se parallelamente allo standard definito da Oracle [link] sono nate altre librerie ampliamente utilizzate (e non compatibili con JSR353):
Personalmente ho sempre e solo utilizzato GSON per il solo fatto che è stata la prima libreria che ho utilizzato in Java e non ho mai effettuato test con altre librerie. Per questo esempio verrà utilizzata la libreria GSON.

Parse JSON from Servlet

Prendiamo ad esempio un semplice codice Javascript lato client (per questo esempio viene utilizzata la libreria Javascript jQuery [link], nello specifico le API AJAX di jQuery [link]):

<html>
  <head>
    <title>
      Programmazione Applicata - Parse JSON from Servlet
    </title>
  </head>
  <body>
  <div>
      <label>
        Username
      </label>
      <input type="text" id="username">
    </div>
    <div>
      <label>
        Password
      </label>
      <input type="password" id="password">
    </div>
    <div>
      <button type="button" value="login" id="login">
    </div>
  </body>
</html>
<script src="" type="text/javascript"></script>
<script type="text/javascript">
  $("#login").onClick(function(){
    var json = {
      username: $("#username").val(),
      password: $("#password").val()
    };
    $.ajax({
      dataType: "json",
      url: "MyServlet",
      data: json
    });
  });
</script>

Adesso vediamo come processare la richiesta lato server nella nostra Servlet:

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@WebServlet(name = "MyServlet", urlPatterns = {"/MyServlet"})
public class MyServletextends HttpServlet {
[...]
protected void processRequest(
        HttpServletRequest request, 
        HttpServletResponse response)
        throws ServletException, IOException {
    response.setContentType("application/json");
    try (PrintWriter out = response.getWriter()) {
        BufferedReader reader;
        JsonParser parser;
        JsonElement clientRequest;
        JsonObject loginAttempt;
        String username,password;
        reader = request.getReader();
        parser = new JsonParser();
        clientRequest = parser.parse(reader);
        loginAttempt = clientRequest.getAsJsonObject();
        username = loginAttempt.getAsJsonPrimitive("username").getAsString();
        password = loginAttempt.getAsJsonPrimitive("password").getAsString();
        [...]
    }
[...]
}

Nello stesso modo è possibile realizzare una risposta JSON:

[...]
public class TestClass{
    private String FirstAttribute;
    private String SecondAttribute;
    public TestClass(){
        FirstAttribute = "";
        SecondAttribute = "";
    }
    public String getFirstAttribute(){
        return FirstAttribute;
    }
    public String getSecondAttribute(){
        return SecondAttribute;
    }
    public void setFirstAttribute
        (String FirstAttribute){
        this.FirstAttribute = FirstAttribute;
    }
    public void setSecondAttribute
        (String SecondAttribute){
        this.SecondAttribute = SecondAttribute;
    }   
}
[...]
protected void processRequest
        (HttpServletRequest request,
        HttpServletResponse response)
        throws ServletException, IOException {
    response.setContentType("application/json");
    try (PrintWriter out = response.getWriter()) {
        Gson json;
        TestClass outputObject;
        outputObject = new TestClass();
        outputObject.setFirstAttribute("hello");
        outputObject.setSecondAttribute("world");
        json = new Gson();
        out.print(json.toJsonTree(outputObject));
    }
}
[...]

Conclusione

L'utilizzo della libreria GSON in Java per processare richieste in formato JSON e produrre risposte dello stesso tipo è davvero elementare. Il matrimonio perfetto di queste tecnologie avviene proprio nello sviluppo Web tuttavia la notazione JSON può essere utilizzata anche per la scrittura/lettura di file di configurazione o la comunicazione fra due applicazioni in Socket TCP/IP.



Nessun commento:

Posta un commento