spring boot项目02:Web项目(基础)
Eclipse版本:2021-03 (4.19.0)
Java:8
Spring Boot:spring-boot-starter-parent#2.5.2(对于的spring-core/context/beans的版本为 5.3.8)
工具:Postman
web项目介绍:
提供Web服务——API。
导航:
进入 https://start.spring.io/ 网站;
左边的选择好后,右边选择依赖 Spring Web;
下载后得到:
导入Eclipse:
检查pom.xml依赖:spring-boot-starter-web 和 spring-boot-starter-test。
spring-boot-starter-web 包的依赖包结构如下:包含了 spring-core等基础的spring包,另外新增了 spring-boot-starter-tomcat、spring-web、spring-webmvc等。
运行web项目,启动后,项目没有停止,并监听了8080端口(Tomcat):
由于没有配置API,此时没有任何可访问接口(endpoint):
WebApplication结构:
@SpringBootApplication
public class WebApplication {
public static void main(String[] args) {
SpringApplication.run(WebApplication.class, args);
}
}
run执行后,返回 ConfigurableApplicationContext 对象,可以通过这个对象查看 Spring容器中的Bean。
ConfigurableApplicationContext的信息输出如下:
结果显示 其真是类型我 AnnotationConfigServletWebServerApplicationContext,容器中管理着 137个Bean。
AnnotationConfigServletWebServerApplicationContext 类:
从上面的信息来看,调用SpringApplication.run(...) 执行了很多操作,包括建立 ApplicationContext。
具体怎么实现的,需要检查源码。TODO
使用 @RestController、@GetMapping、@PostMapping、@RequestParam、@RequestBody 等注解。
源码如下:
@RestController
public class HelloController {
@GetMapping(value="hello") // 1、GET请求
public String getHello(@RequestParam String name) {
return "Hello, " + name;
}
@PostMapping(value="calAdd") // 2、POST请求
public Integer calAdd(@RequestBody CalAddDTO dto) {
if (dto.getA() == null || dto.getB() == null) {
throw new RuntimeException("参数a、b不能为空");
}
return dto.getA() + dto.getB();
}
}
测试:使用工具Postman分别调用两个接口
对于POST的接口 /calAdd 中,以下情况会出现异常:
1、请求方式为GET
Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'GET' not supported]
2、a 或 b 任一缺失
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: 参数a、b不能为空] with root cause
java.lang.RuntimeException: 参数a、b不能为空
3、a、b的值超过 Integer的范围
将Integer更改为 BigInteger后,错误3可以避免:
@PostMapping(value="calAdd")
public BigInteger calAdd(@RequestBody CalAddDTO dto) { // CalAddDTO的 a、b 的类型也改了
if (dto.getA() == null || dto.getB() == null) {
throw new RuntimeException("参数a、b不能为空");
}
return dto.getA().add(dto.getB());
}
结果:
上面只是提供了Web项目中的后台接口,Web项目的页面呢?
在上面的项目中,resources目录下有static、templates 两个目录,可以将Web页面、模板建立在这里,然后,在页面中访问后端接口。
除了 @RestController 注解,还有 @Controller注解可以用来提供后端接口,但不止是接口。
web项目默认端口为8080,更改端口的方式如下:
1、修改 application.properties文件
2、在启动参数中设置server.port
注,除了上面两种方式,还有其它修改的方式,这就涉及到配置的优先级了,需要检查 spring boot手册。
对于上面两种方式,第二种的优先级更高。
共有3中Servlet容器可供选择:Tomcat,Jetty,Undertow。
说明,后面两种有什么更优秀的特点,还没搞清楚。TODO
本节介绍替换为Jetty。
默认的包依赖关系:
排除spring-boot-starter-tomcat,引入 spring-boot-starter-jetty包,然后,启动:
使用Poatman测试,两个接口正常。
undertow类似,请看 参考资料 1:依赖包为 spring-boot-starter-undertow。
1、修改 server.servlet.context-path
修改所有URL的前缀。
比如,原链接 为 http://localhost:8080/hello?name=lib ,添加下面的配置:
server.servlet.context-path=/abc
原链接加了前缀后为:
http://localhost:8080/abc/hello?name=lib
此时,原链接已不存在了——HTTP Status 404 – Not Found。
注意,前缀“/abc”前面的 斜杠(/)一定要有,否则启动失败,会提示下面的错误:ContextPath must start with '/' and not end with '/'
也可以配置为 /abc/123:
server.servlet.context-path=/abc/123
注意,这个配置以 server.servlet 开头,修改的是 Web-Servlet应用的潜在,如果是 WebFlux应用,则是其它配置。
类似的配置还有不少,可以在spring boot官方文档查看:
2、HttpServletRequest、HttpServletResponse
1 @RestController 2 class HelloController { 3 4 @Autowired 5 private HttpServletRequest req; 6 7 @Autowired 8 private HttpServletResponse resp; 9 10 ... 11 12 }
Web项目中会 自动生成上面两个 bean,使用 @Autowired 引入使用。
用途:
req 用来获取 一些请求的信息,uri、url等,
resp 用来直接响应内容,比如,下载文件时直接返回文件内容。
参考资料
2、