前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[ 成为架构师系列 ] 1. 第一个 Java Web 程序

[ 成为架构师系列 ] 1. 第一个 Java Web 程序

作者头像
一个会写诗的程序员
发布2019-11-27 22:09:28
6160
发布2019-11-27 22:09:28
举报
文章被收录于专栏:一个会写诗的程序员的博客

[ 成为架构师系列 ] 1. 第一个 Java Web 程序

1.新建 maven webapp 工程

打开 idea, New Project, 选择 Maven, 从 maven-archetype 创建, 找到 maven-archetype-webapp:

创建 maven 项目

-DgroupId=com.light.sword -DartifactId=simple-javaweb -Dversion=1.0-SNAPSHOT -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-webapp -DarchetypeVersion=RELEASE org.apache.maven.plugins:maven-archetype-plugin:RELEASE:generate

得到项目文件目录如下

代码语言:javascript
复制
$ tree
.
├── pom.xml
├── simplejavaweb.iml
└── src
    └── main
        └── webapp
            ├── WEB-INF
            │   └── web.xml
            └── index.jsp

4 directories, 4 files

2. maven-archetype-webapp 是什么?

Maven Webapp Archetype: http://maven.apache.org/archetypes/maven-archetype-webapp/

Maven Webapp Archetype

maven-archetype-webapp is an archetype which generates a sample Maven webapp project:

代码语言:javascript
复制
project
|-- pom.xml
`-- src
    `-- main
        `-- webapp
            |-- WEB-INF
            |   `-- web.xml
            `-- index.jsp

Usage

To generate a new project from this archetype, type:

代码语言:javascript
复制
mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-webapp -DarchetypeVersion=1.4

3. Servlet 是什么?

Servlet 本质上就是一个java类:

  • A servlet is a small Java program that runs within a Web server.
  • Servlets receive and respond to requests from Web clients, usually across HTTP, the HyperText Transfer Protocol.
代码语言:javascript
复制
/**
 * Defines methods that all servlets must implement.
 *
 * <p>
 * A servlet is a small Java program that runs within a Web server. Servlets
 * receive and respond to requests from Web clients, usually across HTTP, the
 * HyperText Transfer Protocol.
 *
 * <p>
 * To implement this interface, you can write a generic servlet that extends
 * <code>javax.servlet.GenericServlet</code> or an HTTP servlet that extends
 * <code>javax.servlet.http.HttpServlet</code>.
 *
 * <p>
 * This interface defines methods to initialize a servlet, to service requests,
 * and to remove a servlet from the server. These are known as life-cycle
 * methods and are called in the following sequence:
 * <ol>
 * <li>The servlet is constructed, then initialized with the <code>init</code>
 * method.
 * <li>Any calls from clients to the <code>service</code> method are handled.
 * <li>The servlet is taken out of service, then destroyed with the
 * <code>destroy</code> method, then garbage collected and finalized.
 * </ol>
 *
 * <p>
 * In addition to the life-cycle methods, this interface provides the
 * <code>getServletConfig</code> method, which the servlet can use to get any
 * startup information, and the <code>getServletInfo</code> method, which allows
 * the servlet to return basic information about itself, such as author,
 * version, and copyright.
 *
 * @see GenericServlet
 * @see javax.servlet.http.HttpServlet
 */

public interface Servlet {

    /**
     * Called by the servlet container to indicate to a servlet that the servlet
     * is being placed into service.
     *
     * <p>
     * The servlet container calls the <code>init</code> method exactly once
     * after instantiating the servlet. The <code>init</code> method must
     * complete successfully before the servlet can receive any requests.
     *
     * <p>
     * The servlet container cannot place the servlet into service if the
     * <code>init</code> method
     * <ol>
     * <li>Throws a <code>ServletException</code>
     * <li>Does not return within a time period defined by the Web server
     * </ol>
     *
     *
     * @param config
     *            a <code>ServletConfig</code> object containing the servlet's
     *            configuration and initialization parameters
     *
     * @exception ServletException
     *                if an exception has occurred that interferes with the
     *                servlet's normal operation
     *
     * @see UnavailableException
     * @see #getServletConfig
     */
    public void init(ServletConfig config) throws ServletException;

    /**
     *
     * Returns a {@link ServletConfig} object, which contains initialization and
     * startup parameters for this servlet. The <code>ServletConfig</code>
     * object returned is the one passed to the <code>init</code> method.
     *
     * <p>
     * Implementations of this interface are responsible for storing the
     * <code>ServletConfig</code> object so that this method can return it. The
     * {@link GenericServlet} class, which implements this interface, already
     * does this.
     *
     * @return the <code>ServletConfig</code> object that initializes this
     *         servlet
     *
     * @see #init
     */
    public ServletConfig getServletConfig();

    /**
     * Called by the servlet container to allow the servlet to respond to a
     * request.
     *
     * <p>
     * This method is only called after the servlet's <code>init()</code> method
     * has completed successfully.
     *
     * <p>
     * The status code of the response always should be set for a servlet that
     * throws or sends an error.
     *
     *
     * <p>
     * Servlets typically run inside multithreaded servlet containers that can
     * handle multiple requests concurrently. Developers must be aware to
     * synchronize access to any shared resources such as files, network
     * connections, and as well as the servlet's class and instance variables.
     * More information on multithreaded programming in Java is available in <a
     * href
     * ="http://java.sun.com/Series/Tutorial/java/threads/multithreaded.html">
     * the Java tutorial on multi-threaded programming</a>.
     *
     *
     * @param req
     *            the <code>ServletRequest</code> object that contains the
     *            client's request
     *
     * @param res
     *            the <code>ServletResponse</code> object that contains the
     *            servlet's response
     *
     * @exception ServletException
     *                if an exception occurs that interferes with the servlet's
     *                normal operation
     *
     * @exception IOException
     *                if an input or output exception occurs
     */
    public void service(ServletRequest req, ServletResponse res)
            throws ServletException, IOException;

    /**
     * Returns information about the servlet, such as author, version, and
     * copyright.
     *
     * <p>
     * The string that this method returns should be plain text and not markup
     * of any kind (such as HTML, XML, etc.).
     *
     * @return a <code>String</code> containing servlet information
     */
    public String getServletInfo();

    /**
     * Called by the servlet container to indicate to a servlet that the servlet
     * is being taken out of service. This method is only called once all
     * threads within the servlet's <code>service</code> method have exited or
     * after a timeout period has passed. After the servlet container calls this
     * method, it will not call the <code>service</code> method again on this
     * servlet.
     *
     * <p>
     * This method gives the servlet an opportunity to clean up any resources
     * that are being held (for example, memory, file handles, threads) and make
     * sure that any persistent state is synchronized with the servlet's current
     * state in memory.
     */
    public void destroy();
}

Tomcat与Servlet的关系

Servlet运行在Tomcat中

Servlet与普通的Java程序的区别

Servlet本质上就是一个Java类 Servlet类必须实现接口javax.servlet.Servlet接口 运行在Web容器中,tomcat就是一个Web容器。 能够接收浏览器发送的请求,并且做出响应给浏览器。

4. 编写自己的 Servlet

pom.xml中添加 servlet-api 依赖

代码语言:javascript
复制
<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>servlet-api</artifactId>
    <version>6.0.53</version>
</dependency>

写一个类继承 HttpServlet

HttpServlet是个抽象类它已经实现了Servlet接口。

我们写一个 HelloServlet 类继承 HttpServlet:

代码语言:javascript
复制
package com.light.sword;

import javax.servlet.http.HttpServlet;

/**
 * @author: Jack
 * 2019-11-23 22:50
 */
public class HelloServlet extends HttpServlet {
    
}

重写 doGetdoPost 方法,分别处理表单的get或post请求。

代码语言:javascript
复制
package com.light.sword;

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;
import java.util.Date;

/**
 * @author: Jack
 * 2019-11-23 22:50
 */
public class HelloServlet extends HttpServlet {

    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");
        resp.setCharacterEncoding("UTF8");
        PrintWriter writer = resp.getWriter();
        writer.println(new Date() + ", Hello World, by Servlet.");
    }
}

如果直接在浏览器输入地址访问,使用的是get方法。

Note: Get 方法是幂等的,无状态,无副作用的. The GET method should be safe, that is, without any side effects

5. 编写web.xml配置文件

完成 Servlet 的编写, 还要配置一下 web.xml 文件,对Servlet进行配置,才能通过浏览器来访问。

配置 web.xml

代码语言:javascript
复制
<!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 xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
         http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <display-name>Hello World, Archetype Created Web Application</display-name>
    <description>
        This is a simple web application with a source code organization
        based on the recommendations of the Application Developer's Guide.
    </description>

    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.light.sword.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>

6. war 打包配置

http://maven.apache.org/plugins/maven-war-plugin/examples/adding-filtering-webresources.html

maven 打 war包配置:

代码语言:javascript
复制
   <build>
        <finalName>simple-javaweb</finalName>
        <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
                <configuration>
                    <!-- 指定JDK版本 -->
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.4</version>
            </plugin>
        </plugins>
    </build>

工程目录规范:

代码语言:javascript
复制
/simplejavaweb$ tree
.
├── README.md
├── package.sh
├── pom.xml
├── simplejavaweb.iml
└── src
    └── main
        ├── java
        │   └── com
        │       └── light
        │           └── sword
        │               └── HelloServlet.java
        └── webapp
            ├── WEB-INF
            │   └── web.xml
            ├── hello.jsp
            └── index.html

8 directories, 8 files

Including and Excluding Files From the WAR: http://maven.apache.org/plugins/maven-war-plugin/examples/including-excluding-files-from-war.html

7. Tomcat 启动部署

代码语言:javascript
复制
apache-tomcat-7.0.82$ ./bin/startup.sh 
Using CATALINA_BASE:   /Users/jack/soft/apache-tomcat-7.0.82
Using CATALINA_HOME:   /Users/jack/soft/apache-tomcat-7.0.82
Using CATALINA_TMPDIR: /Users/jack/soft/apache-tomcat-7.0.82/temp
Using JRE_HOME:        /Library/Java/JavaVirtualMachines/jdk1.8.0_40/Contents/Home
Using CLASSPATH:       /Users/jack/soft/apache-tomcat-7.0.82/bin/bootstrap.jar:/Users/jack/soft/apache-tomcat-7.0.82/bin/tomcat-juli.jar
Tomcat started.

上传 war 包, 然后 deploy .

8. 运行测试

访问 http://localhost:8080/simple-javaweb/

点击 To a JSP page. http://localhost:8080/simple-javaweb/hello.jsp

代码语言:javascript
复制
<%@ page import="java.util.Date" %>
<%@ page session="false" pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %>
<!DOCTYPE html>
<html>
<body>
<h2>
    <%= new Date() + ", Hello World, by JSP." %>
</h2>
</body>
</html>

点击 To a Servlet. http://localhost:8080/simple-javaweb/hello

代码语言:javascript
复制
package com.light.sword;

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;
import java.util.Date;

/**
 * @author: Jack
 * 2019-11-23 22:50
 */
public class HelloServlet extends HttpServlet {

    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");
        resp.setCharacterEncoding("UTF8");
        PrintWriter writer = resp.getWriter();
        writer.println(new Date() + ", Hello World, by Servlet.");
    }
}

9. FAQ 问题

HTTP Status 500 - Error instantiating servlet class

用maven打了war包之后部署到tomcat下居然无法执行,看了一下原来没有任何编译的.class文件. 这个问题通常是打 war 包,没有把编译好的类文件打进去.

配置 build 标签下面的sourceDirectory:

代码语言:javascript
复制
<build>
        <finalName>simple-javaweb</finalName>
        <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
                <configuration>
                    <!-- 指定JDK版本 -->
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.4</version>
            </plugin>
        </plugins>
    </build>
代码语言:javascript
复制
#!/usr/bin/env bash
mvn clean compile package

.gitignore

代码语言:javascript
复制
*.iml
.idea

工程源码

https://github.com/to-be-architect/simple-javaweb

参考资料

https://blog.csdn.net/RookiexiaoMu_a/article/details/89254719

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • [ 成为架构师系列 ] 1. 第一个 Java Web 程序
  • 1.新建 maven webapp 工程
  • 2. maven-archetype-webapp 是什么?
    • Maven Webapp Archetype
      • Usage
      • 3. Servlet 是什么?
        • Tomcat与Servlet的关系
          • Servlet与普通的Java程序的区别
      • 4. 编写自己的 Servlet
        • pom.xml中添加 servlet-api 依赖
          • 写一个类继承 HttpServlet
          • 5. 编写web.xml配置文件
          • 6. war 打包配置
          • 7. Tomcat 启动部署
          • 8. 运行测试
          • 9. FAQ 问题
            • HTTP Status 500 - Error instantiating servlet class
              • .gitignore
              • 工程源码
              • 参考资料
              相关产品与服务
              容器服务
              腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档