java web 基础 ---- servlet

文章目录

  • [Servlet 介绍](#Servlet 介绍)
  • 创建web项目
    • [基于Servlet 创建简单的web项目](#基于Servlet 创建简单的web项目)
      • 软件版本
      • 目录结构
      • [pom.xml 配置](#pom.xml 配置)
      • [UserModel 类](#UserModel 类)
      • [UserService 类](#UserService 类)
      • [UserController 类](#UserController 类)
  • [tomcat 开源服务器](#tomcat 开源服务器)
  • 运行web应用程序

Servlet 介绍

  • 服务器端用于处理Http 协议的组件,接收http请求,处理http请求,渲染动态html页面并返回响应;

创建web项目

  • Servlet3.0 以前的传统项目中,标准做法的目录结构src/main/webapp/WEB-INF/web.xml ;Servlet3.0以后就非必需,可选,完全可以依赖注解的方式定义Servlet组件;
  • 传统项目中,需要将web项目部署到独立的tomcat服务中,则maven 配置pom.xml 中packaging -> war 是必须的,会打包为 .war 包;

基于Servlet 创建简单的web项目

软件版本

  • jdk8;
  • maven 工程化管理;
  • tomcat 9.0.118
  • javax.servlet 4.0.1
  • freemarker 2.3.31 模板引擎
    前后端不分离,MVC架构

目录结构

pom.xml 配置

maven 自动从中心仓库拉取依赖包;

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<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>Ilearning</artifactId>
    <version>1.0-SNAPSHOT</version>
<!--    web app -->
    <packaging>war</packaging>

    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.31</version>
        </dependency>
    </dependencies>
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

</project>

UserModel 类

数据模型,用于与数据库交互,封装数据对象;

java 复制代码
// UserModel.java
package org.example.model;


import java.util.Map;   //
import java.util.HashMap;

// 默认私有类,仅包内使用,一个类文件中可以定义多个私有类
class BaseModel{

    // private 私有成员属性,仅类内部访问,子类可以继承,但不能类内访问
    // 为了可以被子类继承,这里使用protected 权限修饰符
    protected int id;
    protected String name;
    protected int age;
    protected String address;

    // 默认有一个无参构造方法

    // 定义getter setter
    public int getId(){ return id;} // 省略了this
    public void setId(int id){this.id = id;}

    public String getName(){return name;}
    public void setName(String name){this.name = name;}

    public int getAge(){return this.age;}
    public void setAge(int age){this.age = age;}

    public String getAddress(){return this.address;}
    public void setAddress(String addr){this.address=addr;}


}


// 至多一个public 类
public class UserModel extends BaseModel {  // 仅支持单继承, C++ 、python 则支持多继承

    // 继承父类BaseModel的 protected 成员属性 , public的成员方法

    // 定义构造方法,实现实例对象的初始化
    public UserModel(int id, String name, int age, String addr){
        this.id = id;
        this.name = name;
        this.address = addr;
        this.age = age;
    }

    // 返回Hash类型, key is String , value is only support Object
    public Map<String, Object> toMap(){
        Map<String, Object> userData = new HashMap<>();
        // 存入key-value
        userData.put("id", this.id); // this 表示当前类的实例对象
        userData.put("name", this.name);
        userData.put("age", this.age);
        userData.put("address", this.address);

        return userData;
    }
}

UserService 类

处理业务逻辑

java 复制代码
package org.example.service;


import org.example.model.UserModel;
import java.util.Map;
import java.util.HashMap;


// 可有多个私有类
// 【默认为私有类】,仅在当前包内使用
class BaseService {
    protected String serverName;

}


// 类文件中至多有一个public 公有类,且源文件名必须与该public类同名
public class UserService extends BaseService{ // 单继承
    // 初始化用户数据
    private static Map<Integer, UserModel> data = new HashMap<>();

    static {
        // 静态代码块,类加载时执行
        data.put(1, new UserModel(1, "jack", 15, "beijing")); // new 创建对象,存储在堆内存
        data.put(2, new UserModel(2, "tom", 20, "zhengzhou"));
    }

    // 根据id 查询用户对象, 没有权限修饰符时,默认私有, 类也不可直接调用
    public static UserModel getUserById(int id){
        // static的方法中仅能访问静态的成员
        return data.get(id);
    }

}

UserController 类

自定义的Servlet组件,处理请求,渲染动态html页面,返回响应

java 复制代码
package org.example.controller; // 声明所属的包

import org.example.model.UserModel;
import org.example.service.UserService;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;

import java.io.IOException;
import java.util.Map; // 接口,用于向上造型,声明变量
import java.util.HashMap; // key-value 存储的实现类
import java.lang.String;
import java.io.StringWriter;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;


@WebServlet("/users/user/*") // WebServlet注解,实现url到servlet组件的映射
public class UserController extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        // throws 表示可能抛出的异常

        // 解析请求url中的id
        String uri = request.getRequestURI();
        String[] parts = uri.split("/");
        int userId = Integer.parseInt(parts[parts.length-1]);

        UserModel user = UserService.getUserById(userId);
        Map<String, Object> data = user.toMap();

        try {
            // 创建freemarker 模板配置对象
            Configuration config = new Configuration(Configuration.VERSION_2_3_31);
            // 设置加载模板的路径
            config.setClassForTemplateLoading(UserController.class, "/templates"); // classpath
            // 加载模板
            Template tpl = config.getTemplate("user.ftl");
            StringWriter writer = new StringWriter();
            tpl.process(data, writer);

            // 写入响应数据
            response.setContentType("text/html;charset=UTF-8");
            response.getWriter().write(writer.toString());

        }catch (TemplateException e){
            e.printStackTrace();
        }

    }
}

开发完成后,可以基于tomcat服务器启动自己的web应用程序;

tomcat 开源服务器

介绍

  • tomcat 是一个开源的 java 服务器,也是Servlet 容器;
  • 是web 服务器,
    • 可以监听http端口,接收http请求,返回http响应;
    • 可以处理静态资源,html/css/js/图片等;
    • 类似apache http server,nginx等;
  • 是应用服务器
    • 可以启动java的应用程序,提供服务;
    • 类似python中的uWSGI, uvicorn,Gunicorn 等网关服务;
  • 启动扫描
扫描类型 目的 说明
注解扫描 发现通过注解定义的Servlet组件 例如 @WebServlet、@WebListener、@WebFilter 等。这是最耗时的操作,因为需要解析每个类文件。
ServletContainerInitializer (SCI) 扫描 支持框架的插件化 通过SPI机制加载第三方库的启动类,例如Spring就是通过这种方式实现无web.xml配置的。
Web片段扫描 模块化配置 扫描JAR包中META-INF/web-fragment.xml文件,允许模块提供自己的部分配置。
TLD扫描 发现JSP标签库 扫描META-INF/*.tld文件,这是JSP技术需要的。

下载安装

tomcat 下载地址

解压后即可在bin目录下通过startup.bat / startup.sh 启动;

环境配置:

  1. 需要安装jdk,并配置环境变量path;

    • windows, 命令行 setx path "C:\Program Files\Java\jdk1.8.0_291\bin;%path%"
      ui操作: 我电脑-右键-属性-高级系统设置
    • linux, 编辑~/.bashrc, export PATH=/xx/jdk1.8.0_291\bin:$PATH
  2. 需要配置环境变量JAVA_HOME,告诉IDE、tomcat等工具jdk的安装目录;

    windows 【不区分大小写】,setx java_home "C:\Program Files\Java\jdk1.8.0_291"

    linux 【区分大小写】, export JAVA_HOME=/xxx/xx/Java/jdk1.8.0_291

  3. 配置环境变量classpath,编译器搜索类、资源文件的若干路径;

  4. 执行startup.bat / startup.sh 启动tomcat 服务器 【也是Servlet容器】

    windows,命令行执行 start startup.bat,或者双击

    linux,命令行 ./startup.sh

  5. 启动后,浏览器访问localhost:8080,看到如下页面表示成功;

  6. 关闭tomcat web服务器,通过如下命令或者杀掉进程;

IDE中配置tomcat

Intelli Idea 社区版

  • 安装Smart Tomcat插件,并重启IDE;

  • run > 编辑配置

  • 运行

Eclipse IDE 配置tomcat

pending

运行web应用程序

Idea IDE 运行服务;

浏览器中访问/users/user/1

Tomcat单独部署

  1. maven 构建,在命令行下执行mvn clean package,在 target 目录下生成的WAR文件;
  2. 将生成的 myapp.war 文件复制到 Tomcat安装目录/webapps/ 下,
    Tomcat会自动解压该文件并部署应用;
  3. 访问 http://localhost:8080/myapp 进行验证;

管理界面中部署:

使用Tomcat Manager管理界面,适合需要远程上传或管理多个应用的情况。

配置管理员账户:编辑 Tomcat安装目录/conf/tomcat-users.xml 文件,在 tomcat-users标签内添加以下内容,用户名和密码请自行修改:

xml 复制代码
<role rolename="manager-gui"/>
<user username="admin" password="your_password" roles="manager-gui"/>

重启Tomcat,使配置生效。

访问 http://localhost:8080/manager/html,输入你刚才设置的用户名和密码。

在管理界面,找到 "WAR file to deploy" 区域,点击"选择文件"并选中你的 .war 文件,然后点击"Deploy"即可。

相关推荐
程序猿乐锅1 小时前
【苍穹外卖|Day01】项目初识:从多模块结构到 OpenAPI 接口文档踩坑
java·spring·maven·mybatis
李白的天不白1 小时前
针对你遇到的 Client.Timeout exceeded 问题,我判断是防火墙拦截了 HTTPS 流量
java
linweidong1 小时前
Java 后端开发面试 50 个高频易混淆知识点详解
java·spring boot·spring·spring cloud·面试·mybatis·spring事务
码语智行1 小时前
应用启动和关闭监听器功能分析
java·spring boot
Resky08181 小时前
什么是 Spring IOC:倒过来让容器帮你 new,而不是你到处 new
java·spring
AutumnWind04201 小时前
【JDK动态代理源码梳理】
java·后端·spring
暗夜猎手-大魔王1 小时前
转载--Hermes Agent 10 | 7 层安全防线:从用户授权到输入净化
java·数据库·安全
idolao3 小时前
Oligo 7.60 安装教程:引物设计+Java 环境配置
java·开发语言
做个文艺程序员6 小时前
第04篇:K8s 弹性伸缩实战:HPA、VPA、KEDA——Java SaaS 应对流量洪峰的秘密武器
java·容器·kubernetes·弹性伸缩·自动扩容·ai 推理伸缩