Δημιουργία web εφαρμογών σε java (servlet) με Maven


Έχουμε δει το πως να στήνεις σε πολύ απλά τον tomcat σε ubuntu και τα τρέχεις ένα αρχείο .war σε αυτόν (βλ. εδώ) και πως σε maven να κάνεις μια απλή java εφαρμογή (βλ. εδώ). Σήμερα θα δούμε την web πλευρά της java και πως μπορείς σχετικά εύκολα να κάνεις servlets με maven.

Κατ’ αρχάς δημιουργούμε ένα Maven project για web με την εντολή:

mvn -B archetype:generate  -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-webapp -DgroupId=<basiko package>  -DartifactId=<onoma project>

Το τι σημαίνει κάθε λέξη ανάμεσα σε < … > θα το δείτε εδώ.

Σημείωση:
Tα ονόματα που είδατε παραπάνω να είναι ανάμεσα σε < ... > εδώ θα χρησιμοποιηθούν και παρακάτω στο άρθρο με την ίδια σημασία.

Για χάριν ευκολίας ταυτόχρονα θα δείχνουμε παράλληλα ένα παράδειγμα. Έστω ότι θέλω να δημιουργήσω ένα project με το όνομα article_servlet έτσι θα δώσω την εντολή:

mvn -B archetype:generate  -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-webapp -DgroupId=web  -DartifactId=article_servlet

Και με την εκτέλεση της παραπάνω εντολής θα δημιουργηθούν τα εξής αρχεία:


├── pom.xml
└── src
    └── main
        ├── resources
        └── webapp
            ├── index.jsp
            └── WEB-INF
                └── web.xml

Στον φάκελο main/webapp περιέχονται τα αρχεία που δεν είναι αρχεία .java αλλά συνθέτουν όλη την web εφαρμογή μας πχ. Σελίδες JSP, javascript αρχεία, aplication configuration files κλπ. κλπ. Αλλά σε καμία περίπτωση δεν βάζουμε αρχεία .java λόγο ότι ποτέ δεν θα μεταγλωττιστούν από το maven.

Γι αυτόν τον σκοπό στον φάκελο src/main δημιουργούμε έναν φάκελο java που θα φιλοξενεί τα αρχεία .java της εφαρμογής μας και και πακέτα που φιλοξενούν αυτά.

Προσοχή:
Τα πακέτα της java δεν έχουν καμιά σχέση με τα πακέτα .rpm και .deb του linux

Στο παράδειγμά μας λοιπόν δημιουργούμε τον φάκελο java. Σε τερματικό linux και λοιπόν Unix-οειδών γίνεται με της εντολή mkdir. Συγκεκριμένα στο τερματικό δίνω:

cd article_servlet
mkdir -p ./src/main/java

Έτσι το project θα έχει την εξής δομή των αρχείων:


.
├── pom.xml
└── src
    └── main
        ├── java
        ├── resources
        └── webapp
            ├── index.jsp
            └── WEB-INF
                └── web.xml

Εφόσον το κάνουμε αυτό για να μπορούν τα Servlets μας να γίνουν εποτυχώς compile πρέπει στο pom.xml να βάλουμε κάποιες προσθήκες. Οι γραμμές οι οποίες πρέπει να βάλουμε είναι οι:

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.0.1</version>
        <scope>provided</scope>
    </dependency>

Στο παράδειγμά μας το pom.xml έχει την εξής μορφή:

 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>web</groupId>
  <artifactId>article_servlet</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>article_servlet Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <finalName>article_servlet</finalName>
  </build>
</project>

Και με την προσθήκη των γραμμών θα γίνει (προσοχή στις αλλαγές με αυτό το χρώμα):

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>web</groupId>
  <artifactId>article_servlet</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>article_servlet Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
    <scope>provided</scope>
   </dependency>
  </dependencies>
  <build>
    <finalName>article_servlet</finalName>
  </build>
</project>

Και σαφώς βάζουμε την version για την java (Οι αλλαγές με αυτό το χρώμα):

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>web</groupId>
  <artifactId>article_servlet</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>article_servlet Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
    <scope>provided</scope>
   </dependency>
  </dependencies>
<build>
<finalName>article_servlet</finalName>
<plugins>
 <plugin>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>2.3.2</version>
  <configuration>
    <source>1.7</source>
    <target>1.7</target>
  </configuration>
 </plugin>
</plugins>
</build>
</project>

Και εφόσον κάναμε την προεργασία ώρα να γράψουμε τα servlet μας. Για την συγγραφή του Servlet πρέπει να προσέξουμε τα εξής:

  1. Κάνουμε Import τα:
    import java.io.*;
    import javax.servlet.*;
    import javax.servlet.http.*;
    
  2. Την κλάση ΠΑΝΤΑ την κάνουμε public και πάντα κάνε extend την HttpServlet
  3. 2. Μέθοδοι που μπορούμε να κάνουμε overide είναι:
    • Για Http GET (Σε απλά Ελληνικά να βάζεις παραμέτρους στο Url με ? στην αρχή):
      
      public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
      
    • Για Http POST (Σε απλά Ελληνικά να μπορείς να παίρνει παραμέτρους ΚΑΙ από το URL αλλά ΚΑΙ απ’ ευθείας από την φόρμα):
      
      public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
      

Εφόσον το κάνετε πρέπει με κάποιο τρόπο ο tomcat να ξέρει πως θα «σερβιριστεί» το εκάστοτε servlet. Γι αυτό υπάρχει το αρχείο web.xml που είναι στο φάκελο WEB-INF. θα το βρείτε στο src/main/webapp/WEB-INF σε αυτό το αρχείο ανάμεσα στο <web-app></web-app> δίνουμε εγγραφές με την εξής μορφή:

<servlet>
  <servlet-name> ^όνομα^</servlet-name>
  <servlet-class> ^πακέτο κλάσης^</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>^όνομα^</servlet-name>
  <url-pattern>/^url^</url-pattern>
</servlet-mapping>

Όπου:

  • ^όνομα^: ένα χαρακτηριστικό όνομα για το servlet. Χρησιμεύει για να το ξεχωρίζετε από τα άλλα servlets.
  • ^πακέτο κλάσης^: Η πλήρης διαδρομή του πακέτου κλάσης πχ. Αν στον φάκελο java έχουμε έναν φάκελο toilets και σε αυτό έχουμε το αρχείο Servlet.java τότε το ^πακέτο κλάσης^ θα είναι toilets.Servlet .
  • ^url^: To url που θα δίνεις. πχ. Αν έχουμε ένα servlet mitsos και gi αυτό έχουμε ορίσει το ^url^ kitsos για να επισκεφθεί το servlet θα δίνει στον browser: http://localhost:8080/mitsos/kitsos (Στην θέση του localhost βάζετε τo url ή την ip του σέρver που αντιστοιχεί εαν ο tomcat δεν είναι στον ίδιο τον υπολογιστή.). Προσοχή: το / πρέπει πάνα να μπαίνει στην αρχή της εγγραφής αυτής.

Στο παράδειγμά μας θα κάνουμε το servlet, στον φάκελο Java βάζουμε το εξής αρχείο με όνομα Test.java:

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.*;
import javax.servlet.http.*;

public class Test extends HttpServlet
{
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        response.setContentType("text/plain;charset=UTF-8");
        PrintWriter out=response.getWriter();

        out.println("Hello");
    }
}

Και στο web.xml τις εξής εγγραφές:

    <servlet>
        <servlet-name> Test</servlet-name>
        <servlet-class> Test</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Test</servlet-name>
        <url-pattern>/test</url-pattern>
    </servlet-mapping>

Που σε απλά ελληνικά όπου:

  • ^όνομα^: Τest (θα μπορούσαμε να βάλουμε και άλλο όνομα ανεξαρτήτου κλάσης)
  • ^πακέτο κλάσης^: Test (καμία σχέση με το παραπάνω απλά για χάριν ευκολίας το βάζω έτσι)
  • ^url^: test (Θυμίζω ότι πάντα βάζουμε το / μπροστά)

Έτσι το web.xml γίνεται (οι προθήκες με αυτό το χρώμα):

 <!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
    <servlet>
        <servlet-name> Test</servlet-name>
        <servlet-class> Test</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Test</servlet-name>
        <url-pattern>/test</url-pattern>
    </servlet-mapping>
</web-app>

Και κάνουμε compile με την εντολή:

mvn package

Και μετά το compile τα αρχεία του project αποκτούν αυτήν την δομή:

.
├── article_servlet.iml
├── pom.xml
├── src
│   └── main
│       ├── java
│       │   └── Test.java
│       ├── resources
│       └── webapp
│           ├── index.jsp
│           └── WEB-INF
│               └── web.xml
└── target
    ├── article_servlet
    │   ├── index.jsp
    │   ├── META-INF
    │   └── WEB-INF
    │       ├── classes
    │       │   └── Test.class
    │       └── web.xml
    ├── article_servlet.war
    ├── classes
    │   └── Test.class
    ├── generated-sources
    │   └── annotations
    ├── maven-archiver
    │   └── pom.properties
    └── surefire

Και κάνω βάζω στον tomcat το article_servlet.war που είναι στο φάκελο target.
Αξιοσημείωτο είναι να δούμε τι έχει το .war αρχείο μας. Με την παρακάτω εντολή το κάνω.


pcmagas@dimitris:~/Kwdikas/java/article_servlet$ jar tvf ./target/article_servlet.war 
     0 Sat Mar 14 00:47:00 EET 2015 META-INF/
   126 Sat Mar 14 00:46:58 EET 2015 META-INF/MANIFEST.MF
     0 Sat Mar 14 00:47:00 EET 2015 WEB-INF/
     0 Sat Mar 14 00:47:00 EET 2015 WEB-INF/classes/
    52 Sun Mar 08 17:02:24 EET 2015 index.jsp
   460 Sat Mar 14 00:46:08 EET 2015 WEB-INF/web.xml
   915 Sat Mar 14 00:46:58 EET 2015 WEB-INF/classes/Test.class
     0 Sat Mar 14 00:47:00 EET 2015 META-INF/maven/
     0 Sat Mar 14 00:47:00 EET 2015 META-INF/maven/web/
     0 Sat Mar 14 00:47:00 EET 2015 META-INF/maven/web/article_servlet/
  1077 Mon Mar 09 21:08:08 EET 2015 META-INF/maven/web/article_servlet/pom.xml
   110 Sat Mar 14 00:47:00 EET 2015 META-INF/maven/web/article_servlet/pom.properties

Η παραπάνω γραμμή με bold (που δεν είναι έτσι στο αποτέλεσμα) μας δηλώνει ότι στο WEB-INF/classes μπαίνει ότι αρχείο .java κάνει compile το maven στο /src/main/java.

Εφόσον το κάνω αυτό δίνω στον browser http://^server_ip^/article_servlet/test (αν τρέχει στον δικόσας υπολογιστή βάλτε localhost) και παίρνω το αποτέλεσμα:
Στιγμιότυπο από 2015-03-14 01:06:49

 

 

 

 

 

Ομοίως δημιουργούμε άλλα 2 Servlets , το Test2.java  και το Test3.java, μόνο που θα μπουν σε πακέτα.  To Test2 θα είναι στο πακέτο test ενώ το Test3 θα είναι στο πακέτο test.one.

Κατ’ αρχάς με την εξής εντολή θα δημιουργήσω τους φάκελους που θα παίζει τον ρόλο του πακέτου  με την προϋπόθεση ότι είμαστε στον φάκελο του project.

mkdir -p ./src/main/java/test/one

Έτσι το project μας θα έχει την εξής μορφή:

.
├── article_servlet.iml
├── pom.xml
└── src
    └── main
        ├── java
        │   ├── test
        │   │   └── one
        │   └── Test.java
        ├── resources
        └── webapp
            ├── index.jsp
            └── WEB-INF
                └── web.xml

Στον φάκελο test δημιουργούμε το αρχείο Test2.java και βάζουμε τα εξής:


package test;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class Test2 extends HttpServlet
{
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        response.setContentType("text/plain;charset=UTF-8");
        PrintWriter out=response.getWriter();

        out.println("Hello 2");
    }
}

Και στον φάκελο test.one δημιουργούμε το αρχείο Test3.java που θα περιέχει τα εξής:

package test.one;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class Test3 extends HttpServlet
{
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        response.setContentType("text/plain;charset=UTF-8");
        PrintWriter out=response.getWriter();

        out.println("Hello 3");
    }
}

Ενώ στο web.xml βάζουμε τα εξής (Οι αλλαγές για το Test2 είναι με αυτό το χρώμα και για το Test3 με αυτό το χρώμα):

 <!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
    <servlet>
        <servlet-name> Test</servlet-name>
        <servlet-class> Test</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Test</servlet-name>
        <url-pattern>/test</url-pattern>
    </servlet-mapping>
    
    <servlet>
        <servlet-name> Test3</servlet-name>
        <servlet-class> test.one.Test3</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Test3</servlet-name>
        <url-pattern>/test3</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name> Test2</servlet-name>
        <servlet-class> test.Test2</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Test2</servlet-name>
        <url-pattern>/test2</url-pattern>
    </servlet-mapping>
</web-app>

Αξιοσημείωτο είναι ότι εκεί που είναι το βάζουμε όλη την διαδρομή του πακέτου όπως θα το βάζαμε άμα κάνουμε import σε ένα άλλο αρχείο .java. Σε απλά ελληνικά όπως θα περιγράφατε την διαδρoμή του αρχείου μετά το java έτσι θα το κάνετε αντί όμως να βάλετε / ή \ βαζετε . . Ακόμη εφόσον κάνετε compile (mvn package) μπορείτε να τα επισκευθείτε από τον browser σας δίνοντας http://^server_ip^:8080/test2 και http://^server_ip^:8080/test2 . (Σημειώνω για ακόμη μια φορά ότι στην θέση του ^server_ip^ αν παίζεται στον ίδιο υπολογιστή είναι η localhost)

Advertisements

2 thoughts on “Δημιουργία web εφαρμογών σε java (servlet) με Maven

  1. Παράθεμα: Εισαγωγή Παραμέτρων από φόρμα ή URL από Java Servlets σε κωδικοποίηση UTF-8 | Pc_magas' Blog

  2. Παράθεμα: Φόρτωση σελίδας JSP από Servlet | Pc_magas' Blog

Σχολιάστε

Εισάγετε τα παρακάτω στοιχεία ή επιλέξτε ένα εικονίδιο για να συνδεθείτε:

Λογότυπο WordPress.com

Σχολιάζετε χρησιμοποιώντας τον λογαριασμό WordPress.com. Αποσύνδεση / Αλλαγή )

Φωτογραφία Twitter

Σχολιάζετε χρησιμοποιώντας τον λογαριασμό Twitter. Αποσύνδεση / Αλλαγή )

Φωτογραφία Facebook

Σχολιάζετε χρησιμοποιώντας τον λογαριασμό Facebook. Αποσύνδεση / Αλλαγή )

Φωτογραφία Google+

Σχολιάζετε χρησιμοποιώντας τον λογαριασμό Google+. Αποσύνδεση / Αλλαγή )

Σύνδεση με %s