构建一个简单的 Java Spring Boot 项目-简单万能API请求器

摘要

在这篇博客中,我们将学习如何构建一个简单的 Java Spring Boot 项目。我们将创建一个 API 服务,包含控制器、服务层和数据访问层。通过这个项目,你将了解如何组织 Spring Boot 项目结构,并实现基本的 API 功能。本文适合初学者,提供详细的代码示例和解释。

引言

Spring Boot 是一个流行的 Java 框架,用于快速构建基于 Spring 的应用程序。它提供了开箱即用的配置,简化了项目的开发和部署。在本教程中,我们将创建一个简单的 API 服务,演示如何使用 Spring Boot 构建一个结构化的项目。

博主 默语带您 Go to New World.
个人主页—— 默语 的博客👦🏻 优秀内容
《java 面试题大全》
《java 专栏》
《idea技术专区》
《spring boot 技术专区》
《MyBatis从入门到精通》
《23种设计模式》
《经典算法学习》
《spring 学习》
《MYSQL从入门到精通》数据库是开发者必会基础之一~
🍩惟余辈才疏学浅,临摹之作或有不妥之处,还请读者海涵指正。☕🍭
🪁 吾期望此文有资助于尔,即使粗浅难及深广,亦备添少许微薄之助。苟未尽善尽美,敬请批评指正,以资改进。!💻⌨


默语是谁?

大家好,我是 默语,别名默语博主,擅长的技术领域包括Java、运维和人工智能。我的技术背景扎实,涵盖了从后端开发到前端框架的各个方面,特别是在Java 性能优化、多线程编程、算法优化等领域有深厚造诣。

目前,我活跃在CSDN、掘金、阿里云和 51CTO等平台,全网拥有超过15万的粉丝,总阅读量超过1400 万。统一 IP 名称为 默语 或者 默语博主。我是 CSDN 博客专家、阿里云专家博主和掘金博客专家,曾获博客专家、优秀社区主理人等多项荣誉,并在 2023 年度博客之星评选中名列前 50。我还是 Java 高级工程师、自媒体博主,北京城市开发者社区的主理人,拥有丰富的项目开发经验和产品设计能力。希望通过我的分享,帮助大家更好地了解和使用各类技术产品,在不断的学习过程中,可以帮助到更多的人,结交更多的朋友.


我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。

默语:您的前沿技术领航员

👋 大家好,我是默语
📱 全网搜索“默语”,即可纵览我在各大平台的知识足迹。

📣 公众号“默语摸鱼”,每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。

💬 微信端添加好友“Solitudemind”,与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。

📅 最新动态:2025 年 1 月 2 日

快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!


构建一个简单的 Java Spring Boot 项目

正文

项目结构

首先,我们需要定义项目的基本结构。一个典型的 Spring Boot 项目通常包含以下几个部分:

  • Controller 层:处理 HTTP 请求。
  • Service 层:包含业务逻辑。
  • DAO 层:处理数据访问。

我们的项目结构如下:

src/main/java/com/example/yanwc_api/
    ├── controller/
    │   ├── ApiController.java
    │   └── TestApiController.java
    ├── service/
    │   ├── ApiService.java
    │   └── TestService.java
    ├── dao/
    │   └── TestDao.java

使用demo

http://localhost:8080/api/add_get?num1=1&num2=2

在这里插入图片描述

http://localhost:8080/api/add_post

在这里插入图片描述

代码实现

1. Controller 层

TestApiController 负责处理 HTTP 请求,并调用 TestService

package com.example.yanwc_api.controller;

import com.example.yanwc_api.service.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
public class TestApiController {

    @Autowired
    private TestService testService;

    // 处理GET请求,路径为/api/add_get
    @GetMapping("/add_get")
    public TestService.Result addGet(@RequestParam(required = false, defaultValue = "0") int num1,
                                     @RequestParam(required = false, defaultValue = "0") int num2) {
        System.out.println("GET请求: num1=" + num1 + ", num2=" + num2);
        return testService.add(num1, num2);
    }

    // 处理POST请求,路径为/api/add_post
    @PostMapping(value = "/add_post", consumes = "application/json")
    public TestService.Result addPost(@RequestBody TestService.RequestData requestData) {
        System.out.println("POST请求: num1=" + requestData.getNum1() + ", num2=" + requestData.getNum2());
        return testService.add(requestData.getNum1(), requestData.getNum2());
    }
}
2. Service 层

TestService 包含业务逻辑,计算两个数字的和。

package com.example.yanwc_api.service;

import org.springframework.stereotype.Service;

@Service
public class TestService {

    public Result add(int num1, int num2) {
        int result = num1 + num2;
        System.out.println("计算结果: " + result);
        return new Result(result);
    }

    public static class Result {
        private int result;

        public Result(int result) {
            this.result = result;
        }

        public int getResult() {
            return result;
        }

        public void setResult(int result) {
            this.result = result;
        }
    }

    public static class RequestData {
        private int num1;
        private int num2;

        public int getNum1() {
            return num1;
        }

        public void setNum1(int num1) {
            this.num1 = num1;
        }

        public int getNum2() {
            return num2;
        }

        public void setNum2(int num2) {
            this.num2 = num2;
        }
    }
}
3. DAO 层

TestDao 是数据访问层的占位符,当前没有实际的数据库操作。

package com.example.yanwc_api.dao;

import org.springframework.stereotype.Repository;

@Repository
public class TestDao {
    // 这里可以实现数据访问逻辑,例如数据库操作
    // 当前示例中没有实际的数据库操作
}

前端页面

我们还创建了一个简单的前端页面,允许用户通过表单发送请求。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>默语-API Caller - 万能API调用器</title>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet">
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background-image: url('https://b0.bdstatic.com/ugc/rXSwF5RsFjjbFyCf4JVLxQ29b789622f8fbf23a252827554c12c51.jpg@h_1280'); /* 确保URL有效 */
            background-size: cover;
            background-position: center;
            background-repeat: no-repeat;
            margin: 0;
            padding: 20px 0;
            color: #e0e0e0;
            display: flex;
            justify-content: center;
            align-items: flex-start;
            min-height: 100vh;
            box-sizing: border-box;
        }
        .container {
            background-color: rgba(255, 255, 255, 0.1);
            border-radius: 12px;
            box-shadow: 0 8px 16px rgba(0, 0, 0, 0.5);
            padding: 30px;
            width: 90%;
            max-width: 600px;
            backdrop-filter: blur(15px);
            margin: 0 auto;
        }
        h1 {
            font-size: 2.5em;
            color: #00d4ff;
            text-align: center;
            margin-bottom: 20px;
            text-shadow: 0 0 10px #00d4ff;
        }
        label {
            font-weight: bold;
            margin-top: 15px;
            display: block;
            color: #b0b0b0;
        }
        input, select, textarea {
            width: 100%;
            padding: 10px;
            margin-top: 5px;
            border: 1px solid #00d4ff;
            border-radius: 4px;
            box-sizing: border-box;
            background-color: rgba(255, 255, 255, 0.1);
            color: #e0e0e0;
            transition: border-color 0.3s, background-color 0.3s;
        }
        input:focus, select:focus, textarea:focus {
            border-color: #00d4ff;
            outline: none;
            background-color: rgba(255, 255, 255, 0.2);
        }
        select {
            background: linear-gradient(135deg, #ff7e5f, #feb47b, #86a8e7, #91eae4);
            color: #e0e0e0;
            transition: background 0.3s;
        }
        select:hover {
            background: linear-gradient(135deg, #86a8e7, #91eae4, #ff7e5f, #feb47b);
        }
        select:focus {
            background: linear-gradient(135deg, #91eae4, #ff7e5f, #feb47b, #86a8e7);
        }
        option {
            background-color: #2c5364;
            color: #e0e0e0;
        }
        button {
            background-color: #00d4ff;
            color: white;
            padding: 12px 20px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            margin-top: 20px;
            width: 100%;
            font-size: 16px;
            transition: background-color 0.3s, transform 0.3s;
        }
        button:hover {
            background-color: #00a3cc;
            transform: translateY(-2px);
        }
        pre {
            background-color: rgba(255, 255, 255, 0.05);
            padding: 15px;
            border-radius: 4px;
            border: 1px solid #00d4ff;
            margin-top: 25px;
            white-space: pre-wrap;
            word-wrap: break-word;
            color: #e0e0e0;
        }
        .header-row {
            display: flex;
            margin-bottom: 5px;
        }
        .header-row input {
            margin-right: 5px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1><i class="fas fa-network-wired"></i>默语- API Caller - 万能API调用器</h1>
        <form id="apiForm">
            <label for="url">URL:</label>
            <input type="text" id="url" name="url" required><br><br>

            <label for="method">Method:</label>
            <select id="method" name="method">
                <option value="GET">GET</option>
                <option value="POST">POST</option>
                <option value="PUT">PUT</option>
                <option value="DELETE">DELETE</option>
            </select><br><br>

            <label for="parseJson">Parse JSON (for GET requests):</label>
            <input type="checkbox" id="parseJson" name="parseJson" checked><br><br>

            <h3>Headers</h3>
            <div id="headers">
                <div class="header-row">
                    <input type="text" placeholder="Header Name" class="header-name">
                    <input type="text" placeholder="Header Value" class="header-value">
                    <button type="button" onclick="removeHeader(this)">Remove</button>
                </div>
            </div>
            <button type="button" onclick="addHeader()">Add Header</button><br><br>

            <h3>Body</h3>
            <label for="contentType">Content Type:</label>
            <select id="contentType" name="contentType">
                <option value="application/json">JSON</option>
                <option value="text/plain">Text</option>
                <option value="application/xml">XML</option>
                <option value="application/x-www-form-urlencoded">Form URL Encoded</option>
                <option value="multipart/form-data">Multipart Form Data</option>
            </select><br><br>

            <textarea id="body" name="body" placeholder="Request Body"></textarea><br><br>

            <button type="submit"><i class="fas fa-paper-plane"></i> Send Request</button>
        </form>

        <h2>Response</h2>
        <pre id="response"></pre>
    </div>

    <script>
        function addHeader() {
            const headersDiv = document.getElementById('headers');
            const newHeaderRow = document.createElement('div');
            newHeaderRow.className = 'header-row';
            newHeaderRow.innerHTML = `
                <input type="text" placeholder="Header Name" class="header-name">
                <input type="text" placeholder="Header Value" class="header-value">
                <button type="button" onclick="removeHeader(this)">Remove</button>
            `;
            headersDiv.appendChild(newHeaderRow);
        }

        function removeHeader(button) {
            button.parentElement.remove();
        }

        document.getElementById('apiForm').addEventListener('submit', function(event) {
            event.preventDefault();

            const url = document.getElementById('url').value;
            const method = document.getElementById('method').value;
            const contentType = document.getElementById('contentType').value;
            const body = document.getElementById('body').value;
            const parseJson = document.getElementById('parseJson').checked;

            const headers = {};
            document.querySelectorAll('.header-row').forEach(row => {
                const name = row.querySelector('.header-name').value;
                const value = row.querySelector('.header-value').value;
                if (name && value) {
                    headers[name] = value;
                }
            });
            headers['Content-Type'] = contentType;

            fetch(url, {
                method: method,
                headers: headers,
                body: method !== 'GET' ? body : undefined
            })
            .then(response => {
                const contentType = response.headers.get('content-type');
                if (parseJson && contentType && contentType.includes('application/json')) {
                    return response.json();
                } else {
                    return response.text();
                }
            })
            .then(data => {
                document.getElementById('response').textContent = typeof data === 'string' ? data : JSON.stringify(data, null, 2);
            })
            .catch(error => {
                document.getElementById('response').textContent = 'Error: ' + error;
            });
        });
    </script>
</body>
</html> 

代码资源:https://download.csdn.net/download/qq_42055933/90287877

总结

通过本教程,我们学习了如何使用 Spring Boot 构建一个简单的 API 服务。我们创建了一个结构化的项目,包含控制器、服务层和数据访问层。通过这个项目,你可以了解如何组织 Spring Boot 项目,并实现基本的 API 功能。

参考资料

如果你对本教程有任何疑问,或者想了解更多关于 Spring Boot 的信息,欢迎添加我的微信:Solitudemind。我们可以一起交流学习!


如对本文内容有任何疑问、建议或意见,请联系作者,作者将尽力回复并改进📓;( 联系微信:Solitudemind )

点击下方名片,加入 IT 技术核心学习团队。一起探索科技的未来,共同成长。

为了让您拥有更好的交互体验,特将这行文字设置为可点击样式:点击下方名片,加入 IT
技术核心学习团队。一起探索科技的未来,共同成长。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

默 语

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值