Domanda

I am looking to use Java servlets on command prompt. This is because I'd like:

  1. to be "in direct touch" with the compiler without another environment on,
  2. to use this on my netbook. Eclipse is very slow on my netbook.

For this, I need HttpServletRequest and HttpServletResponse objects to pass to my doXXX methods. I have Tomcat installed. From what I know, Tomcat fires request/response whenever I invoke the servlets on a web-page(?) .

Which folder should I put my servlets and which URL should I open to use them? This document says the class files should be under \WEB-INF\classes. In this case, what URL should I enter once I start Tomcat?

Note: I am aware that I can code a class to implement HttpServletRequest and HttpServletResponse to instantiate. I am also aware by this question that Spring has classes implementing these two interfaces.

È stato utile?

Soluzione

First of all, for building java code from command line I would suggest you to use Apache Ant™ instead of running javac directly.

For building a web project with java you have to be aware of that every java web project has to respect the standard directory layout described here. The directories described there are used by the web container, for example Apache Tomcat, to locate the resources of your web application so that it can be run correctly.

Now you want to start coding. You need to organize your code and separate java source files, libraries on which your application will depend and static web resources (images, static HTML files, scripts, styles, etc.).

Let's say you have created a project directory MyWebProject, the layout would look something like this:

- MyWebProject
    + src
    + src-web
    + lib

Under src you can put your java classes including your servlets. Be sure to use a clean package structure.

Under src-web you can put your static web resources. The web.xml can also be considered as static resource and can be put there.

Under lib you can put 3rd party libraries (*.jar files) that your application will need at compile and run time. For example your application may need a jdbc-driver for operating on a database.

Now let's say you have created a servlet MyServlet.java

package mwp;

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

@WebServlet("/mas")
public class MyServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.println("<html><head/><body><p>Hello, World Wide Web!</p></body></html>");
    }
}

and configured it (either using the annotation @WebServlet (only 3.0 spec) or using the web.xml file)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:wa="http://java.sun.com/xml/ns/javaee" 
    version="3.0" 
    schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <display-name>My web project</display-name>
    <servlet>
        <display-name>My Servlet</display-name>
        <servlet-name>my_servlet</servlet-name>
        <servlet-class>mwp.MyServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>my_servlet</servlet-name>
        <url-pattern>/myservlet</url-pattern>
    </servlet-mapping>
</web-app>

and you want to compile and deploy it on the web container. You can achieve that by creating a build.xml file and writing the appropriate targets for each step (${...} means the value of a variable/property previously defined (see full build.xml file at the end of the answer)):

Compiling

Setup the classpath for javac so that it can find the servlet api jars and other libraries

<path id="compile.classpath">
    <fileset dir="${lib}">
        <include name="*.jar"/>
    </fileset>
    <fileset dir="${catalina.home}/lib">
        <include name="*.jar"/>
    </fileset>
</path>

run javac

<target name="compile">
    <mkdir dir="${bin}"/>
    <javac srcdir="${src}" destdir="${bin}">
        <classpath refid="compile.classpath"/>
    </javac>
</target>

Bundling

Create the directory structure required for a java web project under a directory named deploy

<target name="prepare">
    <mkdir dir="${deploy}"/>
    <mkdir dir="${deploy}/WEB-INF"/>
    <mkdir dir="${deploy}/WEB-INF/classes"/>
    <mkdir dir="${deploy}/WEB-INF/lib"/>
    <mkdir dir="${dist}"/>
</target>

Copy the binaries (*.class and *.jar files) and static web resources to the appropriate places:

<target name="bundle" depends="prepare,compile">
    <copy todir="${deploy}/WEB-INF">
        <fileset dir="${web-src}"/>
    </copy>
    <copy todir="${deploy}/WEB-INF/classes">
        <fileset dir="${bin}"/>
    </copy>
    <copy todir="${deploy}/WEB-INF/lib">
        <fileset dir="${lib}"/>
    </copy>
</target>

At this point you will be able to run the web application if you setup a <context>.xml file, let's say mwpctx.xml, under

CATALINA_HOME/conf/<engine>/<host>

and let it point to the deploy directory using the attribute docBase (in your case, most likely engine will be Catalina and host will be localhost). The content of such a file could look something like this:

<?xml version='1.0' encoding='utf-8'?>
<Context docBase="C:\Projects\MyWebProject\deploy"
         reloadable="true"
         crossContext="false">
</Context>

Now you can invoke your servlet using an url in the form

http://<host>:<port>/<context>/path

where context is the name of the context file <context>.xml without the extension .xml, thus mwpctx. And path is either the path you specified using @WebServlet or the path specified using the web.xml element <url-pattern/>, thus mas or myservlet.

The url would be

http://localhost:8080/mwpctx/mas

or

http://localhost:8080/mwpctx/myservlet

Another alternative would be to create a war file and just drop it into the directory CATALINA_HOME/webapps. This can also be achieved using some ant tasks:

Creating a war file

<target name="war" depends="bundle">
    <jar jarfile="${dist}/${war}" basedir="${deploy}"/>
</target>

Invoking the above ant target will create a war file under the directory designated by ${dist}. It basically packs the content of the directory deploy into an archive.

Deploying

<target name="deploy" depends="bundle,war">
    <copy file="${dist}/${war}" todir="${catalina.home}/webapps" />
</target>

Now assuming the name of the war file is mwp.war, you will be able to invoke your servlet using an url in the same form as mentioned above, except that this time the name of the context is given by the name of the war file without the extension .war, thus the url will look like this

http://localhost:8080/mwp/mas

or

http://localhost:8080/mwp/myservlet

(Remember, the servlet was configured twice, from where the two paths)

Finally here is the project layout:

- MyWebProject
    - src
        - mwp
            MyServlet.java
    - src-web
        web.xml
    + lib

and here is the full ant build.xml file

<project name="MyWebProject" basedir="." default="deploy">
    <property name="src" location="src" />
    <property name="web-src" location="src-web" />
    <property name="bin" location="bin" />
    <property name="lib" location="lib" />
    <property name="deploy" location="deploy" />
    <property name="dist" location="dist" />
    <property name="war" value="mwp.war" />
    <property name="catalina.home" location="C:/Apache/apache-tomcat-7.0"/>

    <path id="compile.classpath">
        <fileset dir="${lib}">
            <include name="*.jar"/>
        </fileset>
        <fileset dir="${catalina.home}/lib">
            <include name="*.jar"/>
        </fileset>
    </path>

    <target name="deploy" depends="bundle,war">
        <copy file="${dist}/${war}" todir="${catalina.home}/webapps" />
    </target>

    <target name="bundle" depends="prepare,compile">
        <copy todir="${deploy}/WEB-INF">
            <fileset dir="${web-src}"/>
        </copy>
        <copy todir="${deploy}/WEB-INF/classes">
            <fileset dir="${bin}"/>
        </copy>
        <copy todir="${deploy}/WEB-INF/lib">
            <fileset dir="${lib}"/>
        </copy>
    </target>

    <target name="war" depends="bundle">
        <jar jarfile="${dist}/${war}" basedir="${deploy}"/>
    </target>

    <target name="compile">
        <mkdir dir="${bin}"/>
        <javac srcdir="${src}" destdir="${bin}">
            <classpath refid="compile.classpath"/>
        </javac>
    </target>

    <target name="prepare">
        <mkdir dir="${deploy}"/>
        <mkdir dir="${deploy}/WEB-INF"/>
        <mkdir dir="${deploy}/WEB-INF/classes"/>
        <mkdir dir="${deploy}/WEB-INF/lib"/>
        <mkdir dir="${dist}"/>
    </target>

    <target name="clean">
        <delete includeemptydirs="true" verbose="true">
            <fileset dir="${bin}" includes="**/**"/>
            <fileset dir="${deploy}" includes="**/**"/>
            <fileset dir="${dist}" includes="**/**"/>
        </delete>
    </target>

</project>

Altri suggerimenti

To be accessible, a servlet must be mapped to a URL pattern. In servlet 3.0 (tomcat 7 only), it's simply done by annotating the servlet with

@WebServlet("/somePath")

In previous versions of the spec, you must declare the servlet in the WEB-INF/web.xml file, and also declare its mapping using a <servlet-mapping> element. So if the pattern you choose is /somePath, for example, the URL will be

http://localhost:8080/myWebApp/somePath

If the pattern is *.foo you can use any URL in the web app contet (/myWebApp in my example) that ends with .foo.

This is stuff that is covered by every servlet tutorial. Pick one (preferrably something at oracle), and read it.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top