仓库地址

w4ngzhen/springboot-simple-guide: This is a project that guides SpringBoot users to get started quickly through a series of examples (github.com)

Chapter03-基于SpringBoot的Web服务

前言

终于,我们的教程来到了SpringBoot核心功能的介绍。对于本章,各位读者至少具备以下的知识:

  1. maven的使用
  2. HTTP

SpringBoot的maven配置介绍

对于一个简单的maven结构的项目来说,以下结构:

${basedir}
|-- pom.xml
|-- src
|-- main
|-- java
|| com.xxx.xxx 项目源码
|-- resources
|| 项目配置文件 .xml等
|-- test
|-- java
|-- resources

在我们前面的教程中,我们都是在编写着代码,从未关注过maven的pom.xml究竟是如何配置的,因为项目脚手架已经配置完成了,也许有细心的同学已经看过了pom.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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <!-- ... 省略了当前项目本身信息的配置,如有需要,请读者查看源码 --> <!-- 当前pom的父级 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent> <dependencies>
<!-- springboot框架web功能starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- springboot框架的测试依赖starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies> <!-- 构建流程使用SpringBoot的maven插件 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> </project>

对于一个普通的maven项目,其实核心的就是dependencies节点-dependency节点了。通过dependency节点,我们可以GAV坐标(Group-Artifact-Version)引入不同的库jar包,便于我们的项目使用这些库。

那么为什么在上面的pom出现了一个parent节点呢?实际上,pom允许所谓的继承:我们可以把一堆的pom依赖和配置,放到一个公共的pom里面,然后各个项目通过parent节点去引用这个公共的pom文件。由于SpringBoot并不是一个单一的jar包构成的框架,它的内部其实依赖了下面的核心库:

spring-core
spring-beans
spring-context
...还有很多

如果手动一项又一项编写dependency来使用Spring框架,不仅仅容易遗漏,而且十分不方便进行这些依赖库的版本管理。基于此,SpringBoot官方提供了父级pom:

    <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.3</version> <!-- 2021/08/09最新 -->
<relativePath/> <!-- lookup parent from repository -->
</parent>

那么再看我们的pom文件中,还依赖了spring-boot-starter-web,这又是什么呢?难道有一个jar包叫做spring-boot-starter-web吗?其实不然。我们上面提到了parent POM,但是Spring框架下的依赖包特别多,并且有些包是核心的包,有些包则是在某些功能需要的情况下才依赖的包。如果一股脑的全部通过parent引入会让你的项目依赖十分臃肿,所以Spring官方再次按照包的功能进行了一定的组合,形成了所谓的starter,如果你只是想做web API的服务开发,用spring-boot-starter-web就可以了,要是需要使用AOP(面向切面编程,作切面开发),加上spring-boot-starter-aop依赖即可。

一个简单的Controller

// 使用注解 @RestController,表明当前类是一个基于REST 规范的HTTP API Controller
@RestController
// @RequestMapping 注解放在Controller上,用于标记 HTTP url的路径入口,
// 例如 http://localhost:8080/hello/xxx 才会进入当前Controller
@RequestMapping("hello")
public class HelloController { // @RequestMapping 注解放在Controller的里面的方法上,
// 将会与Controller上的RequestMapping组合成:"/hello/say"
// method用于指示通过何种HTTP方法访问
// 在程序启动后,我们可以使用GET方法访问:http://localhost:8080/hello/say
@RequestMapping(value = "say", method = RequestMethod.GET)
public String say() {
return "hello, world";
} }

编写启动类,启动我们的SpringBoot程序:

@SpringBootApplication
public class Chapter03App { public static void main(String[] args) {
SpringApplication.run(Chapter03App.class, args);
} }

启动成功后,通过HTTP访问:

http://localhost:8080/hello/say
# 输出:hello, world

关于Controller需要注意的点

上面的例子中,我们使用注解@RestController来标记了我们的Controller类,会有初学者使用@Controller来标记Controller,让我们改成它试试:

@Controller // 改成使用 @Controller注解,其他不变,再次访问,看看有什么问题
@RequestMapping("hello")
public class HelloController {
// ...
}

重启启动应用后再次访问对应地址。如果是在浏览器中,你会看到:

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback. Mon Aug 09 10:16:59 CST 2021
There was an unexpected error (type=Not Found, status=404).

type=Not Found, status=404,404!为什么会这样呢?

  1. 如果使用@Controller标记,那么将使用SpringMVC架构(自行了解),如果对应的方法返回的是字符串,则这个字符串表明需要查找对应的视图(View)名称,并将对应的视图通过视图解析器(InternalResourceViewResolver)解析修改为前端web页面。
  2. 如果使用@RestController注解Controller,则Controller中的方法无法返回jsp页面,或者html,配置的视图解析器不起作用,返回的内容就是return里的内容。

针对情况1,解决方法就是在方法的返回上加上注解:@ResponseBody

    @ResponseBody // 如果当前Controller被@Controller注解,又想返回字符串或其他原始数据
@RequestMapping(value = "say", method = RequestMethod.GET)
public String say() {
return "hello, world";
}

Controller如何被加载的?

在之前的文章,我们已经介绍了SpringBoot是如何初始化Bean并且将其放在IOC容器的。我们提到了三种方式:1、@Component;2、Java配置类;3、XML配置。对于第2、3点,好像目前我们的样例中并没有做手动配置的事情。那么是不是我们的Controller已经被@Component标记了呢?

查看@RestController的定义:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller // 原来你RestController也是一个Controller注解啊!
@ResponseBody // 并且,已经添加了@ResponseBody
public @interface RestController {
@AliasFor(
annotation = Controller.class
)
String value() default "";
}

@RestController其实组合了@Controller@ResponseBody两个注解了。我们再看看@Controller的定义:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component // 原来你Controller注解也组合了Component注解
public @interface Controller {
@AliasFor(
annotation = Component.class
)
String value() default "";
}

原来@Controller也已经组合了@Component注解啊,难怪我们的定义的Controller能被加载。

Controller如何处理HTTP请求的?

要回答这个问题,需要你有一定的关于Java Tomcat Web容器的知识。本系列主要是对SpringBoot的快速入门,不便于讲的过细。简单一点就是:

  1. Tomcat是一个用Java编写的Web容器,可以接受HTTP请求。
  2. SpringBoot内置了Tomcat容器,并且对于HTTP请求,转到了内部处理
  3. 对于这些HTTP请求,根据请求的路径等上下文,匹配Bean容器中的Controller进行处理

极简SpringBoot指南-Chapter03-基于SpringBoot的Web服务的更多相关文章

  1. 黑科技抢先尝(续2) - Windows terminal中Powershell Tab的极简美化指南

    目录 安装python 安装git 安装powerline字体 主题定制 安装oh-my-posh 查看策略组的执行权限 使用choco 安装终端模拟器 - ConEmu 优化 PowerShell ...

  2. 基于 REST 的 Web 服务:基础

    代表性状态传输(Representational State Transfer,REST)在 Web 领域已经得到了广泛的接受,是基于 SOAP 和 Web 服务描述语言(Web Services D ...

  3. 超级好用的前端开发测试Chrome插件-基于REST的Web服务客户端

    基于REST的Web服务客户端是一款功能强大的谷歌浏览器插件,使用基于REST的Web服务客户端(模拟REST客户端)可以让用户使用谷歌浏览器模拟REST请求来测试REST风格. 基于REST的Web ...

  4. 在chrome中安装基于REST的web服务客户端

    基于REST的Web服务客户端的使用方法 点击转到基于REST的Web服务客户端下载页面 chrome浏览器如果安装扩展程序点击chrome浏览器右上角,选择“设置在“设置”对话框里选择“扩展程序”然 ...

  5. 基于Socket创建Web服务

    基于Socket创建Web服务 为什么要使用Socket呢,我们来看下图

  6. 极简SpringBoot指南-Chapter04-基于SpringBoot的书籍管理Web服务

    仓库地址 w4ngzhen/springboot-simple-guide: This is a project that guides SpringBoot users to get started ...

  7. Spring boot构建基于rest的Web服务

    一.介绍:使用Spring Boot我们可以很容易的创建一个可独立运行的Rest web服务,其中内嵌tomact,我们只需“run”就可以查看效果了. Spring Boot利用Gradle或Mav ...

  8. Web Service 实例基于Socket创建Web服务

    ServerSocket服务器端代码如下: public static void main(String[] args) throws IOException { // 1:建立服务器端的tcp so ...

  9. 极简SpringBoot指南-Chapter00-学习SpringBoot前的基本知识

    仓库地址 w4ngzhen/springboot-simple-guide: This is a project that guides SpringBoot users to get started ...

随机推荐

  1. ARP协议工作原理实验

    一.实验目的 验证"在向目的主机发送数据包时会先查询ARP高速缓存,如果ARP高速缓存中已保存了目的主机的MAC地址,不进行ARP查询,使用ARP高速缓存中的MAC地址:如果缓存中没有IP对 ...

  2. 微信公众号授权回调用户信息,获取openid

    1.--------------------用户授权登录并获取code 授权登录方式有两个,一种为静默授权登录(scope=snsapi_base),一种为非静默授权登录(scope=snsapi_u ...

  3. Red Hat Enterprise Linux 7.2修改主机名(hostname)

    Red Hat Enterprise Linux 7.2在安装的时候,会默认生成主机名:localhost. 那么如何修改成自己想要的自己名? //格式为:用户名@主机名 比如: [root@loca ...

  4. MySQL的几种锁机制的使用介绍

    锁 在日常的开发过程中,为了控制线程的并发肯定会用到锁机制.对于数据库而言,锁机制就是数据库为了保证数据的一致性,而使各种共享资源在被并发访问变得有序所设计的一种规则.当然MySQL也不例外,根据不同 ...

  5. VMware 部署虚拟环境

    2021-08-23 1. 版本介绍 本地主机操作系统:windows 10虚拟软件版本:VMware workstation 14centos镜像版本:centos 7.5 2. 设置 2.1 基础 ...

  6. Linux centos7 pstree

    2021-08-12 1.命令简介pstree (display a tree of processes) 命令用于查看进程树之间的关系,即哪个进程是父进程,哪个是子进程,可以直观地看出是谁创建了谁. ...

  7. 微信小程序 image 组件 src 请求不能设置 header 的问题

    只能先 wx.downloadFile 得到 tempFilePath,然后设置 src = tempFilePath

  8. vue ele table表格 设置只能勾选一个

    table 更改属性设置: <el-table ref="multipleTable" :data="tableData" tooltip-effect= ...

  9. CSS实用技巧(中)

    前言 我们经常使用CSS,但是却不怎么了解CSS,本文主要对vertical-align.BFC.position中开发过程不怎么注意的特性进行简要总结,从本文中,你将了解到以下内容: vertica ...

  10. 性能测试必备命令(3)- lscpu

    性能测试必备的 Linux 命令系列,可以看下面链接的文章哦 https://www.cnblogs.com/poloyy/category/1819490.html 介绍 显示有关CPU架构的信息 ...