零基础学Java——第十一章:实战项目 - Web应用开发

第十一章:实战项目 - Web应用开发

在现代软件开发中,Web应用占据了举足轻重的地位。本章将引导你入门Java Web应用开发,从基础概念到构建一个简单的Web应用。

1. Web 应用基础

1.1 什么是 Web 应用?

Web应用是一种可以通过Web浏览器访问的应用程序。用户通过互联网与服务器上的应用进行交互,服务器处理请求并返回结果(通常是HTML页面、数据等)。

生活中的例子:你每天使用的在线购物网站(淘宝、京东)、社交媒体(微博、微信朋友圈网页版)、搜索引擎(百度、Google)都是Web应用。

1.2 Web 应用的工作原理

  1. 客户端(浏览器):用户在浏览器中输入URL或点击链接,发起一个HTTP请求到服务器。
  2. 服务器:Web服务器(如Tomcat, Jetty)接收到请求,并将请求交给相应的Web应用处理。
  3. Web应用:Java Web应用(通常是Servlet、JSP或基于Spring/SpringBoot的应用)处理请求,可能需要访问数据库、调用其他服务等。
  4. 服务器:Web应用将处理结果(如生成的HTML页面)返回给Web服务器。
  5. 客户端(浏览器):Web服务器将HTTP响应发送回浏览器,浏览器解析并显示内容给用户。

1.3 核心技术

  • HTML (HyperText Markup Language):定义网页的结构和内容。
  • CSS (Cascading Style Sheets):描述网页的样式和布局。
  • JavaScript (JS):实现网页的交互功能和动态效果。
  • HTTP (HyperText Transfer Protocol):客户端和服务器之间通信的协议。
  • 后端语言:如Java、Python、Node.js等,用于处理业务逻辑和数据。
  • Web服务器:如Apache Tomcat, Jetty, Nginx等,用于托管和运行Web应用。
  • 数据库:如MySQL, PostgreSQL, MongoDB等,用于存储和管理数据。

2. Java Web 技术栈概览

Java在Web开发领域有着成熟且强大的生态系统。

2.1 Servlet

Servlet是运行在Web服务器上的Java程序,用于处理客户端请求并生成动态内容。它是Java Web开发的核心基础。

  • 生命周期init(), service(), destroy()
  • 处理请求:通过doGet(), doPost()等方法处理不同类型的HTTP请求。

2.2 JSP (JavaServer Pages)

JSP允许你在HTML页面中嵌入Java代码,从而动态生成网页内容。JSP最终会被编译成Servlet。

  • 优点:将表现逻辑与业务逻辑分离(理论上),简化动态页面开发。
  • 缺点:过度使用Java代码会导致JSP页面难以维护。现代开发中,JSP更多地被模板引擎(如Thymeleaf, FreeMarker)或前后端分离架构所取代。

2.3 MVC 模式 (Model-View-Controller)

MVC是一种常用的软件设计模式,用于将应用程序分为三个核心组件:

  • Model (模型):应用程序的核心,处理数据和业务逻辑。例如,一个用户对象,一个订单处理服务。
  • View (视图):用户界面,负责展示数据。例如,HTML页面,JSP页面。
  • Controller (控制器):接收用户输入,调用模型进行处理,并选择合适的视图来展示结果。例如,Servlet。

2.4 Spring 框架

Spring是一个开源的Java应用框架,提供了全面的基础设施支持,用于构建健壮、可维护的企业级应用。Spring MVC是Spring框架中用于构建Web应用的部分。

  • 核心特性:依赖注入 (DI),面向切面编程 (AOP)。
  • Spring MVC:提供了强大的MVC实现,简化了Web开发。

2.5 Spring Boot

Spring Boot是基于Spring框架的约定优于配置的快速开发框架。它极大地简化了Spring应用的初始搭建以及开发过程。

  • 主要优点:自动配置、嵌入式服务器(如Tomcat, Jetty)、简化的依赖管理、生产就绪特性(监控、健康检查)。

3. 搭建第一个 Java Web 应用 (使用 Spring Boot)

Spring Boot是目前Java Web开发的主流选择,因为它上手快,配置简单。

3.1 环境准备

  • JDK 8 或更高版本。
  • Maven 或 Gradle (构建工具)。
  • IDE (IntelliJ IDEA, Eclipse, VS Code)。

3.2 使用 Spring Initializr 创建项目

Spring Initializr 是一个快速创建Spring Boot项目的Web工具。

  1. 访问 start.spring.io
  2. Project: 选择 Maven Project (或 Gradle Project)。
  3. Language: 选择 Java
  4. Spring Boot: 选择一个稳定的版本 (如 2.7.x 或 3.x.x)。
  5. Project Metadata:
    • Group: 例如 com.example
    • Artifact: 例如 mywebapp
    • Name: 例如 mywebapp
    • Description: 项目描述
    • Package name: 例如 com.example.mywebapp
  6. Packaging: 选择 Jar (Spring Boot推荐的方式,内嵌服务器)。
  7. Java: 选择你安装的JDK版本。
  8. Dependencies: 点击 ADD DEPENDENCIES...
    • 搜索并添加 Spring Web (用于构建Web应用,包括RESTful应用)。
    • (可选) 搜索并添加 Thymeleaf (一个现代的服务端Java模板引擎,用于创建动态HTML页面)。
  9. 点击 GENERATE 下载项目压缩包。
  10. 解压项目并在IDE中导入。

3.3 创建一个简单的 Controller

src/main/java/com/example/mywebapp (根据你的包名调整) 目录下创建一个新的Java类,例如 HelloController.java

package com.example.mywebapp;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller // 标记这是一个控制器类
public class HelloController {

    // 处理对 "/hello" 路径的GET请求
    @GetMapping("/hello")
    @ResponseBody // 表示返回的内容直接作为HTTP响应体,而不是视图名
    public String sayHello() {
        return "Hello, Spring Boot Web App!";
    }

    // 处理对 "/greet" 路径的GET请求,并接收一个名为 "name" 的参数
    // 例如: /greet?name=World
    @GetMapping("/greet")
    @ResponseBody
    public String greet(@RequestParam(name = "name", defaultValue = "World") String name) {
        return "Hello, " + name + "!";
    }

    // 如果你添加了Thymeleaf依赖,可以创建一个返回视图的处理器
    // 需要在 src/main/resources/templates/ 目录下创建一个HTML文件,例如 greeting.html
    @GetMapping("/greeting-page")
    public String greetingPage(@RequestParam(name = "visitor", defaultValue = "Guest") String visitorName, Model model) {
        model.addAttribute("visitorName", visitorName); // 将数据传递给视图
        return "greeting"; // 返回视图名 (greeting.html)
    }
}

3.4 (可选) 创建 Thymeleaf 模板

如果在上一步添加了 Thymeleaf 依赖,并在 HelloController 中创建了 greetingPage 方法,那么在 src/main/resources/templates/ 目录下创建 greeting.html 文件:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Greeting Page</title>
</head>
<body>
    <h1>Hello, <span th:text="${visitorName}">Default Visitor</span>!</h1>
    <p>Welcome to our Spring Boot Web Application with Thymeleaf!</p>
</body>
</html>
  • xmlns:th="http://www.thymeleaf.org":引入Thymeleaf命名空间。
  • <span th:text="${visitorName}">Default Visitor</span>th:text 是Thymeleaf的属性,它会用模型中 visitorName 属性的值替换 <span> 标签内的文本。如果模型中没有 visitorName,则显示默认的 “Default Visitor”。

3.5 运行应用

  • 找到Spring Boot的主应用类(通常是带有 @SpringBootApplication 注解的类,例如 MywebappApplication.java)。
  • 运行该类的 main 方法。
  • 应用启动后,默认会运行在 8080 端口。

3.6 测试应用

打开浏览器,访问:

  • http://localhost:8080/hello (应该显示 “Hello, Spring Boot Web App!”)
  • http://localhost:8080/greet?name=JavaLearner (应该显示 “Hello, JavaLearner!”)
  • http://localhost:8080/greeting-page (应该显示一个HTML页面,内容为 “Hello, Guest!”)
  • http://localhost:8080/greeting-page?visitor=Alice (应该显示一个HTML页面,内容为 “Hello, Alice!”)

4. RESTful API 设计入门

REST (Representational State Transfer) 是一种用于设计网络应用的软件架构风格。RESTful API 通常使用HTTP方法 (GET, POST, PUT, DELETE) 对资源进行操作。

4.1 什么是资源 (Resource)?

在REST中,任何可以被命名的信息都可以是资源。例如,一个用户、一篇博客、一个商品。

4.2 HTTP 方法

  • GET:获取资源。
  • POST:创建新资源。
  • PUT:更新或替换现有资源。
  • DELETE:删除资源。
  • PATCH:部分更新现有资源。

4.3 示例:创建一个简单的用户API

假设我们要管理用户数据。

创建 User 类 (POJO - Plain Old Java Object):

package com.example.mywebapp.model;

public class User {
    private long id;
    private String name;
    private String email;

    // 构造函数 (无参和全参)
    public User() {}

    public User(long id, String name, String email) {
        this.id = id;
        this.name = name;
        this.email = email;
    }

    // Getters and Setters
    public long getId() { return id; }
    public void setId(long id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
}

创建 UserRestController:

package com.example.mywebapp.controller;

import com.example.mywebapp.model.User;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

@RestController // 标记这是一个REST控制器,@ResponseBody默认应用于所有方法
@RequestMapping("/api/users") // 所有请求路径都以 /api/users 开头
public class UserRestController {

    // 使用ConcurrentHashMap作为内存中的简单数据存储
    private final Map<Long, User> users = new ConcurrentHashMap<>();
    private final AtomicLong counter = new AtomicLong(); // 用于生成唯一ID

    // 初始化一些数据
    public UserRestController() {
        users.put(counter.incrementAndGet(), new User(1L, "Alice", "alice@example.com"));
        users.put(counter.incrementAndGet(), new User(2L, "Bob", "bob@example.com"));
    }

    // GET /api/users - 获取所有用户
    @GetMapping
    public List<User> getAllUsers() {
        return new ArrayList<>(users.values());
    }

    // GET /api/users/{id} - 根据ID获取用户
    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        User user = users.get(id);
        if (user != null) {
            return ResponseEntity.ok(user); // 返回 200 OK 和用户数据
        } else {
            return ResponseEntity.notFound().build(); // 返回 404 Not Found
        }
    }

    // POST /api/users - 创建新用户
    // 请求体中应包含JSON格式的用户数据 (不含id)
    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody User user) {
        long newId = counter.incrementAndGet();
        user.setId(newId);
        users.put(newId, user);
        return ResponseEntity.status(HttpStatus.CREATED).body(user); // 返回 201 Created 和创建的用户数据
    }

    // PUT /api/users/{id} - 更新用户
    // 请求体中应包含JSON格式的完整用户数据
    @PutMapping("/{id}")
    public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User updatedUser) {
        if (!users.containsKey(id)) {
            return ResponseEntity.notFound().build();
        }
        updatedUser.setId(id); // 确保ID一致
        users.put(id, updatedUser);
        return ResponseEntity.ok(updatedUser);
    }

    // DELETE /api/users/{id} - 删除用户
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        if (users.remove(id) != null) {
            return ResponseEntity.noContent().build(); // 返回 204 No Content
        } else {
            return ResponseEntity.notFound().build();
        }
    }
}

测试 RESTful API:

你可以使用 Postman、curl 或浏览器插件(如 Talend API Tester)来测试这些API端点。

  • GET http://localhost:8080/api/users
  • GET http://localhost:8080/api/users/1
  • POST http://localhost:8080/api/users (请求体: {"name":"Charlie", "email":"charlie@example.com"})
  • PUT http://localhost:8080/api/users/1 (请求体: {"name":"Alice Smith", "email":"alice.smith@example.com"})
  • DELETE http://localhost:8080/api/users/2

5. 前后端分离开发模式

在现代Web开发中,前后端分离是一种非常流行的架构模式。

  • 前端 (Frontend):负责用户界面和用户交互,通常使用HTML, CSS, JavaScript以及React, Vue, Angular等框架开发。前端通过API与后端通信。
  • 后端 (Backend):负责业务逻辑、数据处理、API接口等,使用Java (Spring Boot), Python (Django/Flask), Node.js (Express) 等技术开发。

优点

  • 职责分离:前端和后端团队可以独立开发和部署。
  • 技术选型灵活:前后端可以根据各自需求选择最合适的技术栈。
  • 更好的用户体验:前端框架通常能提供更流畅的单页应用 (SPA) 体验。
  • API复用:后端提供的API可以被Web前端、移动App、桌面应用等多种客户端共用。

6. 总结与下一步

本章我们初步了解了Java Web应用开发的基础知识,并通过Spring Boot构建了一个简单的Web应用和RESTful API。Web开发是一个广阔的领域,有很多值得深入学习的内容。

下一步可以探索的内容

  • 数据库集成:学习如何使用Spring Data JPA或MyBatis将你的Web应用连接到数据库。
  • 安全性:学习Spring Security,为你的Web应用添加认证和授权功能。
  • 模板引擎:深入学习Thymeleaf或其他模板引擎(如FreeMarker)。
  • 前端框架:学习React, Vue或Angular,构建现代化的前端界面。
  • 部署:学习如何将你的Spring Boot应用部署到云平台(如AWS, Azure, Heroku)或Docker容器中。
  • 测试:学习为你的Web应用编写单元测试和集成测试。

继续实践,尝试构建更复杂的Web应用,例如一个简单的博客系统、待办事项列表应用等。祝你学习愉快!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值