Java: Implementing Transform View pattern, to conv

2019-03-05 06:14发布

问题:

I have read the Oracle tutorial: https://docs.oracle.com/javase/tutorial/jaxp/xslt/transformingXML.html

The w3school guide: https://www.w3schools.com/xml/xsl_intro.asp

And a StackOverflow's thread: XSLT processing with Java?

I am learning the Transform View pattern and I would like to implement it in Java.

I have created an XML file, Alumnos.xml:

<?xml version="1.0"?>
<ALUMNO>
    <NOMBRE>Luis</NOMBRE>
    <APPELLIDO1>Navarro</APPELLIDO1>
    <APPELLIDO2>Morote</APPELLIDO2>
    <ASIGNATURAS>
        <ASIGNATURA>PR4</ASIGNATURA>
        <NOTA>5</NOTA>
        <ASIGNATURA>BD2</ASIGNATURA>
        <NOTA>8</NOTA>
        <ASIGNATURA>IR</ASIGNATURA>
        <NOTA>10</NOTA>
    </ASIGNATURAS>
</ALUMNO>

And a Xsl file, called Alumnos.xsl

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet 
    xmlns:xsl=
    "http://www.w3.org/1999/XSL/Transform" 
    version="1.0"
>

    <xsl:template match="ALUMNO">
        <HTML>
            <BODY bgcolor="gray">
                <xsl:apply-templates/>
            </BODY>
        </HTML>
    </xsl:template>

    <xsl:template match="NOMBRE">
        <P>
            <B>Nombre: </B>
            <xsl:apply-templates/>
        </P>
    </xsl:template>

    <xsl:template match="ASIGNATURA">
        <h1>Aginatura: </h1>
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:output method="html"/>

</xsl:stylesheet>

Currently I have the following Java class, AlumnosCommand.java:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package frontController;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.logging.Level;
import java.util.logging.Logger;
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.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

/**
 *
 * @author YonePC
 */
@WebServlet(name = "AlumnosCommand", urlPatterns = {"/AlumnosCommand"})
public class AlumnosCommand extends FrontCommand {

    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code>
     * methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter writer = response.getWriter();
        writer.println("<h1>Hi</h1>");

    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

    @Override
    public void process(HttpServletRequest request) {
        try {

            TransformerFactory factory = TransformerFactory.newInstance();
            StreamSource xls = new StreamSource(new File("Alumnos.xsl"));
            Transformer newTransformer = factory.newTransformer(xls);

            StreamSource xml = new StreamSource(new File("Alumnos.xml"));
            newTransformer.transform(xml, new StreamResult(new File("output.xml")));

            forward("/Alumnos.jsp");

        } catch (ServletException ex) {
            Logger.getLogger(AlumnosCommand.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(AlumnosCommand.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TransformerException ex) {
            Logger.getLogger(AlumnosCommand.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

}

The above class has the purpose of reading the xml, and transform it with the xls and convert it into a new xml file (it should be later used to print the actual HTML for the page).

The difficulty I am facing is that when I press on the 'See pupils list':

The AlumnosCommand.java appears totally blank:

I thought it could be a routing /server problem but it is okay, because if I delete the lines related to load xml and convert it, we see the AlumnosCommand.java

How could I use the given XML file with the proposed XSL rules, to convert it into HTML and render it into the AlumnosCommand.java page?

As a note I include the app's architecture:

回答1:

The process() method is transforming the Alumnos.xml into output.xml using Alumnos.xsl. This output.xml will have all the HTML code and it will be created in the same location as your XML and XSL files. The request is then forwarded to Alumnos.jsp. Does this JSP file perform reading from output.xml to print anything? My guess is no and hence you are not seeing anything on the web page.

The process() needs to be modified to write the transformation to a Writer object e.g. PrintWriter. HttpServletResponse already has a getWriter() method which will help in printing the output. Below is the sample code that would do it.

protected void doGet(HttpServletRequest request, HttpServletResponse response) {
    try {
        TransformerFactory factory = TransformerFactory.newInstance();
        StreamSource xsl = new StreamSource(new File("Alumnos.xsl"));
        Transformer newTransformer = factory.newTransformer(xsl);

        StreamSource xml = new StreamSource(new File("Alumnos.xml"));
        PrintWriter writer = response.getWriter();
        Result result = new StreamResult(writer);
        newTransformer.transform(xml, result);
    } catch (IOException ioe) {
        ioe.printStackTrace();
    } catch (TransformerException te) {
        te.printStackTrace();
    }
}