The foreword 0.

A large proportion of enterprises use the Java language to implement server-side applications, especially at a time when Web applications are exploding. Mastering Java development can help you advance your career as a Web front-end developer. To get you started on Java, today’s Nunato is going to share how to quickly develop and deploy a simple Java Web back end application.

Article outline:

  • Develop products and write Java code
  • Artifacts build, packaging Java code
  • Deploy artifacts, deploy Java code

1. How to develop products

A Web application simply consists of three parts: the browser as the client, the Java application as the server, and the communication protocol is HTTP. What we want to achieve is: in the browser address bar, visit the application address, and print “Hello, Naluduo” on the page. To do this, we need to write an HTTP server in Java that responds to the browser’s access request.

1.1 introduction to the Servlet

It is not difficult to write an HTTP server. In Java, you only need to write a TCP server that gives multithreading, and then read HTTP requests in a TCP connection and send HTTP responses. You can see the communication structure between the client application and the server application in the following figure:

┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ │ Application │ │ Application │ ├ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┤ ├ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┤ │ Socket │ │ Socket │ ├ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┤ ├ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┤ TCP │ │ │ │ TCP ├ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┤ ┌ ─ ─ ─ ─ ─ ─ ┐ ┌ ─ ─ ─ ─ ─ ─ ┐ ├ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┤ │ │ IP < ─ ─ ─ ─ > │ Router │ < ─ ─ ─ ─ ─ > │ Router │ < ─ ─ ─ ─ > │ IP │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ └ ─ ─ ─ ─ ─ ─ ┘ └ ─ ─ ─ ─ ─ ─ ┘ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘Copy the code

Now we write an HTTP server using Java code that understands the traditional development process, relatively at the bottom. If you don’t want to see it, you can skip it.

import java.io.BufferedReader; // Buffer read
import java.io.BufferedWriter; // Buffer write
import java.io.IOException; / / exception
import java.io.InputStream;  / / input stream
import java.io.InputStreamReader; // Input stream reads
import java.io.OutputStream; / / the output stream
import java.io.OutputStreamWriter; / / output
import java.net.ServerSocket; / / socket package
import java.net.Socket;
import java.nio.charset.StandardCharsets;

public class Server {
	public static void main(String[] args) throws IOException {
		ServerSocket ss = new ServerSocket(5050); // Listen on the specified port
		System.out.println("server is running...");
		for (;;) {
			Socket sock = ss.accept();
			System.out.println("connected from " + sock.getRemoteSocketAddress());
			Thread t = new Handler(sock); // Create a threadt.start(); }}}class Handler extends Thread {
	Socket sock;

	public Handler(Socket sock) {
		this.sock = sock;
	}

	@Override
	public void run(a) {
		try (InputStream input = this.sock.getInputStream()) {
			try (OutputStream output = this.sock.getOutputStream()) { handle(input, output); }}catch (Exception e) {
			try {
				this.sock.close();
			} catch (IOException ioe) {
			}
			System.out.println("client disconnected."); }}private void handle(InputStream input, OutputStream output) throws IOException {
		System.out.println("Process new http request...");
		var reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
		var writer = new BufferedWriter(new OutputStreamWriter(output, StandardCharsets.UTF_8));
		// Read the HTTP request:
		boolean requestOk = false;
		String first = reader.readLine();
		if (first.startsWith("GET / HTTP/1.")) {
			requestOk = true;
		}
		for (;;) {
			String header = reader.readLine();
			if (header.isEmpty()) { // The HTTP Header is finished when an empty line is read
				break;
			}
			System.out.println(header);
		}
		System.out.println(requestOk ? "Response OK" : "Response Error");
		if(! requestOk) {// Send an error response:
			writer.write("404 Not Found\r\n");
			writer.write("Content-Length: 0\r\n");
			writer.write("\r\n");
			writer.flush();
		} else {
			// Send a successful response:
			String data = "

Hello, Jecyu!

"
; int length = data.getBytes(StandardCharsets.UTF_8).length; writer.write("HTTP / 1.0 200 OK \ r \ n"); writer.write("Connection: close\r\n"); writer.write("Content-Type: text/html\r\n"); writer.write("Content-Length: " + length + "\r\n"); writer.write("\r\n"); // A blank line identifies the Header and Body separationwriter.write(data); writer.flush(); }}}Copy the code

As you can see from the above code, to write a full-fledged HTTP server, using HTTP/1.1 as an example, you need to consider the following:

  • Identify correct and incorrect HTTP requests
  • Identify correct and incorrect HTTP headers
  • Multiplexing TCP connections
  • Reuse threads
  • I/O Exception Handling
  • .

For the sake of simplicity, we can leave all the low-level work of handling TCP connections and parsing HTTP to an off-the-shelf server and simply run our application on a Web server. To achieve this, JavaEE provides a Servlet API that you can use to write your own servlets to handle HTTP requests. Web servers implement the Servlet API interface (such as the Tomcat server). Implement the underlying functions:

┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ │ My Servlet │ ├ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┤ │ │ the Servlet API ┌ ─ ─ ─ ─ ─ ─ ─ ┐ HTTP ├ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┤ │ Browser │ < ─ ─ ─ ─ ─ ─ > Web Server │ │ └ ─ ─ ─ ─ ─ ─ ─ ┘ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘Copy the code

To sum up, our overall development and deployment steps are as follows:

  • Write Servlet code.
  • Package as a WAR file, or Java Web Application Archive.
  • Copy it to the Tomcat webapps directory.
  • Start the Tomcat server and enter the application address in the browser.

Before doing this, make sure you have the Java runtime environment installed on your computer, downloaded the IntelliJ IDEA editor, and configured the Java version environment.

1.2 Using Maven to Build a Development Environment

Before writing the Servlet code, we can use Maven to build the development environment for efficiency.

Maven is an excellent project building tool that makes it easy to build projects into modules, making it much more efficient when developing and testing packages for deployment. Second, Maven manages dependencies. It can centrally manage dependencies of different systems and transfer and inherit dependencies between them.

Maven is responsible for the automated construction of projects. For example, to automate the compilation, Maven must know where the Java source files are stored. This way, after the convention, Maven knows the location without us manually specifying the location. This will help us complete automatic compilation.

  • Maven usepom.xmlDefine project content and use a default directory structure;
  • Declaring a dependency in Maven automatically downloads and imports the classpath;
  • Maven usegroupId.artifactIdandversionUniquely locate a dependency.
  1. Install Maven

To install Maven, download the latest Maven 3.6.x from the Maven website, unzip it locally, and set a few environment variables:

M2_HOME = / path/to/maven - 3.6 x path = $path: $M2_HOME/binCopy the code

Then, open the command line window and type MVN -version. You should see the version information for Maven:

Java Version: 1.8.0_251, Vendor: Oracle Corporation, Runtime: / Library/Java/JavaVirtualMachines jdk1.8.0 _251. JDK/Contents/Home/jre Default locale: zh_CN, platform encoding: UTF-8 OS name:"mac os x", version: "10.15.7", arch: "x86_64", family: "mac"
Copy the code
  1. Set the directory according to Maven’s protocol:
  • /src/main/java/ Java source code.
  • /src/main/resource: Java configuration file, resource file.
  • /src/test/java/: Java test code.
  • /src/test/resource : Java test configuration file, resource file.
  • /targetThe.class files, jars, wars, and so on that are generated during compilation.
  • pom.xml: Configuration file
  1. Using the IntelliJ IDEA compiler and selecting Maven when creating a new project, you can automatically generate the following directories for us:

  1. After the directory is generated, we write the pom.xml file to fill in the dependencies and build configurations required for the project, where Maven uniquely locates a dependency using groupId, artifactId, and Version.

In this application, the API is javax.servlet 4.0.0, and the Java version is 1.8. Note that

is specified as provided, which is used at compile time but not packaged into a.war file, because the runtime Web server itself already provides jar packages associated with the Servlet API.


      
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>spring-framework-projects</artifactId>
    <version>1.0 the SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.0</version>
            <scope>provided</scope> 
        </dependency>
    </dependencies>
</project>
Copy the code

1.3 Writing Servlet code

Introduce the corresponding servlet package and write the code as follows. You can see that the code is much cleaner than before without servlets.

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 java.io.IOException;
import java.io.PrintWriter;

// the WebServlet annotation indicates that this is a Servlet and maps to the address /:
@WebServlet(urlPatterns = "/")
public class HelloServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        // Set the response type:
        resp.setContentType("text/html");
        // Get the output stream:
        PrintWriter pw = resp.getWriter();
        // Write response:
        pw.write("

Hello, naluduo!

"
); // Finally, don't forget to flush the force output:pw.flush(); }}Copy the code

A Servlet always inherits from HttpServlet and overrides the doGet() or doPost() methods. Notice that the doGet() method passes in two objects, HttpServletRequest and HttpServletResponse, representing the HTTP request and response, respectively. When we use the Servlet API, we don’t interact directly with the underlying TCP and we don’t need to parse the HTTP protocol because HttpServletRequest and HttpServletResponse already encapsulate the request and response. In the case of sending the response, we just set the correct response type, get the PrintWriter, and write the response.

2. How to build artifacts

2.1 Tomcat Deployment Specifications

Our WAR package can run on any server that supports Servlet API 4.0 (since the Servlet version we introduced was 4.0), and here we use the open source, free Tomcat server.

2.1.1 Tomcat Installation starts

Click on the Tomcat official website and select the corresponding installation package to download it. Since I have already installed a Version of Tomcat 10 on my computer, I will not reinstall it.

After Tomcat is installed, only the bin, webapps, and conf directories are required for this guide.

  • BUILDING.txt

  • NOTICE

  • RUNNING.txt

  • Lib: Contains more resources to add on the classpath.

    • In most servlet containers, Tomcat also supports a mechanism to install library JAR files (or unzipped classes) once and make them visible to all installed Web applications (they don’t have to be included in the Web application itself). Details about how Tomcat finds and shares this class are provided in the “Class loader Methods” documentation. In a Tomcat installation, the common location for shared code is $CATALINA_HOME/lib. The JAR files placed here are visible to both the Web application and the internal Tomcat code. This is a good place to put the JDBC drivers needed for your application or internal Tomcat use, such as JDBCRealm.

      The standard Tomcat installation out of the box includes a variety of pre-installed shared library files, including: Servlet 4.0 and JSP 2.3 apis are the basis for writing servlets and JavaServer Pages.

  • Webapps: Tomcat’s main Web publishing directory, where Web application files are stored by default

  • CONTRIBUTING.md

  • README.md

  • Bin: stores the scripts for starting and stopping Tomcat on Windows or Linux

  • Logs: Stores log files during Tomcat execution

  • Work: Store the class file generated after JSP compilation

  • LICENSE

  • RELEASE-NOTES

  • Conf: Stores the global configuration files of the Tomcat server, the most important of which are server.xml and web.xml.

  • Temp: Directory where the JVM is used for temporary files

First grant permission to start Catalia, then start the Tomcat server.

$ cd bin
  chmod +x catalina.sh
  sh startup.sh
Copy the code

If there are no accidents, you can visit the following page at http://localhost:8080/ :

Next, we’ll look at the specification of the deployed container.

A standard application directory is as follows:

  • *.html,*.jsp: HTML and JSP pages, as well as other files (such as JavaScript, stylesheet files, and images) that must be visible to the application’s client browser. In larger applications, you can choose to divide these files into subdirectory hierarchies, but for smaller applications, it is often much simpler to maintain a directory just for these files
  • /WEB-INF/web.xml: This is an XML file that describes the servlets and other components that make up your application, as well as all the initialization parameters and container-managed security constraints that you want the server to enforce for you.
  • /WEB-INF/classes/: This directory contains all the Java class files (and related resources) required by the application, including servlets and non-servlet classes, that are not incorporated into the JAR files. If classes are organized as Java packages, they must be in/WEB-INF/classes/Is reflected in the directory hierarchy under. For example, one namedcom.mycompany.mypackage.MyServletThe Java classes will need to be stored in a/WEB-INF/classes/com/mycompany/mypackage/MyServlet.class“.
  • /WEB-INF/lib/: This directory contains JAR files that contain Java class files (and related resources) required by your application, such as third-party class libraries or JDBC drivers.

Using Maven, you can package the source code and export it to the above file.

2.2 Packaged Build

  1. inpom.xmlAdd a declaration under the Project TAB in the war package
<packaging>war</packaging> <! -- Package as war -->
Copy the code
  1. insrc/main/webappnewWEB-INFFolder, and then create a new fileweb.xmlEnter the application information for packaging
<! DOCTYPEweb-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>
</web-app>
Copy the code
  1. Execute pack command

    mvn clean package
    Copy the code
  2. The packaged files are as follows:

3. Practice of deploying artifacts

3.1 Deploying the WAR Application

3.1 Using the GUI
  1. Enter Tomcat address http://localhost:8080/manager/html, if there is a need to login password and account, you need to configure, into the second step.

  2. Navigate to the Tomcat directory folder, enter /conf/tomcat-users. XML, and add the manager-gui role and account password.


      
<tomcat-users xmlns="http://tomcat.apache.org/xml"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
              version="1.0">

  <role rolename="manager-gui"/>
     <user username="admin" password="admin" roles="manager-gui"/>
</tomcat-users>
Copy the code
  1. Enter the manager page again, and enter the correct account and password just configured, navigate to the deployment bar, select the WAR file to upload, and click Deploy to access.

  1. Access in the browser as shown below:

3.1.2 Manually Copying the WAR file to the Webapps

Dropping the WAR package directly into webapps automatically decompresses it into the project condition server.xml.

<Host name="localhost"  appBase="webapps"
 unpackWARs="true" autoDeploy="true">
Copy the code

3.2 Solving the Tomcat Deployment War 404 Problem

With 3.1 deployment, this is normally fine. But lu more or the stepped on a hole, in a manual copying war file webapps, 404 problems and visit http://localhost:8080/spring-framework-projects-1.0-SNAPSHOT/, after screening, It was found that the Tomcat version 10 that I installed did not support javax. servlet 4.0 interface specification, resulting in access failure.

Solution: Reinstall Tomcat 9: Apache-tomcat-9.0.4 and deploy it again.

4. Summary

This article provides you with a quick understanding of the simplest process of developing, building, and deploying a Java Web application by implementing a Hello level application to help you open the door to server-side development.

The resources

  • Liao Xuefeng’s Java tutorial is highly recommended.
  • N ways to deploy the Tomcat WAR package
  • Springboot war package deployment, and the cause of 404 error
  • Deploying a WAR file gives me a 404 Status Code on Tomcat?