跨境派

跨境派

跨境派,专注跨境行业新闻资讯、跨境电商知识分享!

当前位置:首页 > 卖家故事 > SpringBootWeb最新相关技术(上接maven):IDEA2023-Spring环境,http协议复习概览,web服务器Tomcat,请求响应java服务器项目编写(BS模型,IOC,DI等)

SpringBootWeb最新相关技术(上接maven):IDEA2023-Spring环境,http协议复习概览,web服务器Tomcat,请求响应java服务器项目编写(BS模型,IOC,DI等)

时间:2024-04-16 07:30:42 来源:网络cs 作者:康由 栏目:卖家故事 阅读:

标签: 服务  响应  请求  项目  模型  编写  技术  相关  协议 
阅读本书更多章节>>>>

Spring

官网HTTPs://spring.io
spring生态(全家桶)基于Spring Framework基础框架。但如果我们基于该基础框架开发,会面临配置繁琐,入门难度大的问题,SpringBoot则可以快速开发(简化配置,快速开发)。

1.SpringBootWeb入门

使用SpringBoot开发一个Web应用,浏览器发起请求/hello之后,给浏览器返回字符串"hello world~"

步骤:

创建SpringBoot工程,并勾选web开发相关依赖(New Project/Module的时候Spring Initializer)。
在这里插入图片描述

在这里插入图片描述

定义HelloController类,添加方法hello,并添加注解

@RestControllerpublic class HelloController {    @RequestMapping("/hello")    public String hello(){        System.out.println("Hello World~");        return "Hello World~";    }}

运行测试

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

2.HTTP协议

2.1HTTP概述(简略)

规定了浏览器与服务器之间数据传输的规则
基于tcp面向连接;

基于请求响应模型:一次请求一次响应;

http是无状态的协议:对事物处理没有记忆能力。每一次请求响应都是独立的(优点:速度快;缺点:多次请求之间不能共享数据)——可以通过web会话技术解决记忆问题(比如用户是否处于登录状态)。

2.2HTTP请求协议

GET /hello HTTP/1.1  请求行:方式,路径,协议以下为请求头Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 浏览器接受的资源类型:text/*表示文本,image/*表示图片,*/*表示所有Accept-Encoding: gzip, deflate, br 浏览器支持的压缩类型Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6 浏览器偏好的语言Cache-Control: max-age=0Connection: keep-aliveHost: localhost:8080 主机名Sec-Fetch-Dest: documentSec-Fetch-Mode: navigateSec-Fetch-Site: noneSec-Fetch-User: ?1Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0 浏览器类型sec-ch-ua: "Chromium";v="122", "Not(A:Brand";v="24", "Microsoft Edge";v="122"sec-ch-ua-mobile: ?0sec-ch-ua-platform: "Windows"

常见的请求头还包括:content-length请求主体大小,content-type请求主题数据类型,例如json

请求体是post请求特有的部分,post分为请求行,请求头,请求体;而get只有前两个部分?k=v&k=v

2.3HTTP响应协议

HTTP/1.1 200 相应行,响应状态码Content-Type: text/html;charset=UTF-8Content-Length: 12Date: Mon, 25 Mar 2024 06:48:18 GMTKeep-Alive: timeout=60Connection: keep-alive

2.4HTTP协议解析

协议解析(浏览器作为客户端是不需用我们去解析协议的,而服务端则需要按照请求格式对http协议进行解析,并按照响应格式,对http协议进行响应)

服务端开发工程师用serverSocket接收请求,按照字符串组成规则进行解析。手写解析http的代码IO加socket是可以实现的,但很复杂。由于格式固定,就可以用jetty,weblogic以及tomcat等写好的软件进行解析。

3.Web服务器-Tomcat

web服务器是一个软件程序,对http协议的操作进行封装,使程序员不必直接对协议进行操作,使web开发更搞笑。主要功能是提供网上信息浏览服务

springboot已经内置了tomcat

3.1 tomcat简介

apache
支持少量javaEE规范servlet/jsp
也被成为web容器,servlet容器

3.2 基本使用

官网安装绿色版本之后改成gbk编码(conf/logging)
startup.bat双击就可以运行脚本文件/停止的话shutdown.bat

想要改端口号(conf/server.xml)端口号改为80(http默认端口的话,输入url就不用输入端口号了)
将项目放在webapps目录下

不用安装了,因为SpringBoot已经内置了

3.3 入门程序解析

maven有许多起步依赖starter,比如spring-boot-starter-aop,spring-boot-starter-web等(其余许多被依赖传递,而web就依赖了内嵌的tomcat)

本来只是自己编写一个Controller类,tomcat不识别;但是tomcat识别servlet(一项javaEE规范里的技术)DispatcherServlet(SpringBoot底层支持的一个核心的Servlet接口的实现类,称之为核心控制器或者前端控制器)

请求响应都会先经过Dispatcher:tomcat将接受到的协议信息进行解析,并将结果封装在一个httpServletRequest对象中,应用程序就可通过该对象获取请求数据了,然后对于该数据进行处理,处理完了之后再响应httpServletResponse。

BS架构(broswer-server)用户只要一个browser
CS架构,需要安装客户端。

4.请求响应

4.1请求

controller中获取请求数据(参数)


接口测试工具,postman。前后端分离之后,后端接口测试需求,浏览器直接地址测试只能get,又得单独去写前端post。
postman是一款功能强大的网页调试与发送网页http请求的chrome插件;作用:常用于进行接口测试(有一些apipost以及apifox的衍生大差不差)
可以下载vscode同名插件,可以用网页版(注意网页版访问本地地址需要下载代理),也可以下载到本地。


简单参数:

原始方式接收

@RestControllerpublic class RequestController {    @RequestMapping("/simpleParam")    public String simpleParameter(HttpServletRequest request){        String name = request.getParameter("name");        String age = request.getParameter("age");        System.out.println("name:"+name+"&"+"age:"+age);        return "ok";    }}

在这里插入图片描述

get方式request的时候
在这里插入图片描述

post方式request的时候
在这里插入图片描述

如果想操作上述获得的数据,还需要手动类型转换和分开写接受,比较麻烦;但是有更为简单的方式:基于SpringBoot框架。

@RestControllerpublic class RequestController {    @RequestMapping("/simpleParam")    public String simpleParameter(String name,Integer age){//注意参数名与请求数据名保持一致!!!    //参数名对应不上的话,不会报错,但是值为null    //参数名不一致想要修改,需要使用@RequestParam(name = "name")String username来进行映射    //@RequestParam的属性required默认为true,表示参数必须传递,否则会报错        //age是Integer会自动类型转换        System.out.println("name:"+name+"&"+"age:"+age);        return "ok";    }}

实体参数(将上述参数封装到一个对象中去),要求对象属性名与参数名保持一致

    @RequestMapping("/simplePO")    public String simplePO(User user){        System.out.println(user);        return "OK";    }
public class User {    String name;    int age;    public User(String name, int age) {        this.name = name;        this.age = age;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    @Override    public String toString() {        return "User{" +                "name='" + name + '\'' +                ", age=" + age +                '}';    }}

在之前的类中写方法并写对应User类。
注意:如果是复杂实体,一个对象的属性就是对象,例如user有属性是Address类的实体address;则需要按照address.province,address.city传递


数组集合参数(B端传递的时候如果有多选,例如hobby可以勾选java以及game,就可以是?hobby=java&hobby=game)
服务器端就使用数组集合来接收(默认用数组接收,但是如果要用集合来接受的话就需要用注解@RequestParam)

@RequestMapping("/arrayParam")    public String arrayParam(String[] hobby){        System.out.println(Arrays.toString(hobby));        return "OK";    }
    @RequestMapping("/listParam")    public String listParam(@RequestParam List<String> hobby){        System.out.println(hobby);        return "OK";    }

时期时间类,封装到Date或1.8之后提供的LocalDateTime中由于前端日期格式也多种多样,则需要通过注解@DateTimeFormat(pattern = …)
注意:同样要求名字一致。

    @RequestMapping("/dateParam")    public String dateParam(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime time){        System.out.println(time);        return "OK";    }

json格式
B端效果如下:

在这里插入图片描述

S端则需要通过对象接收,接收对象属性名需要与key保持一致,同时需要加注解@RequestBody

    @RequestMapping("/jsonParam")    public String jsonParam(@RequestBody User user){        System.out.println(user);        return "OK";    }

路径参数,既是路径的一部分也是参数(like:localhost:8080/path/1),S端需要使用@PathVariable注解

//like:localhost:8080/path/1@RequestMapping("/path/{id}")//用id来接收    public String pathParam(@PathVariable Integer id){//上面是id,这里就业的事id        System.out.println(id);        return "OK";    }

注意如果想要多个路径,like:localhost:8080/path/1/marc

//like:localhost:8080/path/1/marc@RequestMapping("/path/{id}/{name}")//用id来接收    public String pathParam(@PathVariable Integer id,@PathVariable String name){//上面是id,这里就业的事id        System.out.println(id+","+name);        return "OK";    }

4.2响应

controller程序中获取响应数据


关键:ResponseBody注解
类型:类注解,方法注解
作用:将方法的返回值直接返回给B端,如果方法的返回值类型是对象或者是集合,将会先将其转换为json格式的数据再响应给客户端浏览器

注意:@RestController=@Controller+@ResponseBody(这也是在之前写请求代码的时候,类前面加了RestController就没加ResponseBody注解还依旧可以响应的原因),@RestController源码如下:

@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Controller@ResponseBodypublic @interface RestController {    @AliasFor(        annotation = Controller.class    )    String value() default "";}

响应示例:

    @RestControllerpublic class ResponseController {    @RequestMapping("/helloResp")    public String hello(){        System.out.println("Hello World~");        return "HelloWorld~";    }}

响应体:

HTTP/1.1 undefinedContent-Type: text/plain;charset=UTF-8Content-Length: 11Date: Mon, 25 Mar 2024 16:56:51 GMTKeep-Alive: timeout=60Connection: keep-alive HelloWorld~

注意:如果返回值是一个实体,则会转为json格式再返回;返回集合的话,如list,和返回数组的json格式一样,这里就不举例了。

4.2.1统一响应

如果按照之前每个函数作为api,api的返回值各不相同,且自由度太高,会造成项目管理难度太大。
故而想出一种统一的返回值

public class Result{    //响应码,1代表成功,0代表失败    private Integer code;    //提示信息    private String msg;    //返回的数据    private Object data;    //...}//然后把所有方法的返回值统一为result

改造如下:

public class ResponseController {    @RequestMapping("/helloResp")    public Result hello(){        System.out.println("Hello World~");        return new Result(1,"success","Hello World");//可以在Result里面加静态方法返回new Result    }}

4.3分层解耦

依照上述方式写代码(如果要,将前后端分离+dom4j解析xml中的数据)依旧复用性差。难以维护。
->分层解耦

4.3.1 web开发三层架构

数据访问;逻辑处理;接受请求,响应数据
->分开(单一职责原则)

Controller:控制层,接收前端发送的请求,对请求进行处理,并响应数据Service:业务逻辑层,处理具体的业务逻辑Dao:数据访问层(持久层),负责数据访问操作,包括数据的增删改查(面向接口编程,获取不同类型的数据)

1->2->3->db/file
1<-2<-3<-db/file

4.3.2 IOC & DI入门

内聚:指的是软件中各个功能模块内部的功能联系。
耦合:衡量软件中各个层、模块之间的依赖关联程度。

controller层调用service层的实现类,所以一旦其类名发生变化就程序整体就会出错,称之为耦合。
设计原则是高内聚低耦合(模块内部功能联系越紧密越好,但是模块之间、层与层之间的耦合降低->最好是解除耦合

设置一个容器,把所需对象放在容器中,容器再为依赖提供所需资源。(实现起来需要用到Spring中两个重要的概念-控制反转/依赖注入)

IOC:inversion of control,控制反转。把对象的创建控制权由程序自身转移到 外部(IOC容器或者叫Spring容器)DI:dependency injection,依赖注入。容器为应用程序提供运行时,所需要依赖的资源。Bean对象:IOC容器中创建、管理的对象,称之为Bean。

将service以及dao的实现类交给IOC管理->加上类注解@Component;删掉Controller以及Service对于Service和Dao实现类的new(只声明,不实例化)然后在成员变量上加上Autowired注解,表示运行时,IOC容器会提供该类型的bean对象,并赋值给该变量,称之为依赖注入。

这样是实现解耦的好处是,如果要切换Service实现类,主需要给新的类前面加Component注解,并注释掉之前的

4.3.3 IOC

Spring框架为了更好地标识bean对象到底归属于哪一层,还提供了Component的三个衍生注解——@Controller,@Service,@Repository(一般不属于三层的时候,用Component,一般是一些工具类;且Repository用得少了,与MyBatis整合)

(Service等衍生注解都只是封装了一个Component。)

bean对象命名
bean对象默认为类名首字母小写,也是可以人为规定名字like:@Repository(value="daoA")// or @Repository("daoA")->可以通过IDEA 的Actuator->Beans查看(老版本为Endpoints->Beans)

注意
注意之前提到的RestController等价于ResponseBody和Controller两个注解;注意四个注解都可以声明bean,但是在SpringBoot集成Web中,声明控制器bean只能用@Controller.

组件扫描注解
声明的bean,不一定会生效,涉及bean组件扫描。想要生效,还需要被组件扫描注解@ComponentScan扫描(Spring框架提供的用来扫描前面所说的四个注解的)
之前没有显示配置ComponentScan注解是因为已经被包含在了启动类声明注解@SpringBootApplication中,默认扫描范围是启动类所在包及其子包。

也就是说,如果一个IOC注解写在了包外,就需要,自己在启动类前加ComponentScan注解,该注解是可以通过数组表示路径,来确定包名(但是要注意如果自己加了ComponentScan,原有的隐式就被覆盖,还需要再加包名)。
例如@ComponentScan({"dao","com.javaLearning"})

4.3.4 DI

对于autowired自动装配,默认按照类型装配,如果有多个类型的bean在容器中且类型符合要求,就会报错。解决方案有三种:

@Primary:设置bean的优先级,谁优先,给谁加,在component处。@Qualifier:在装配处Autowired前面加的注解,指定bean对象名赋给value,like:@Qualifier("serviceValName")@Resource:去掉Autowired注解,直接@Resource(name = "beanName")->前面的注解都是有Spring提供的,本注解是由jdk提供;与Autowired的不同是,Resource默认按照名称注解,而Autowired默认是按照类型注解。 阅读本书更多章节>>>>

本文链接:https://www.kjpai.cn/gushi/2024-04-16/159274.html,文章来源:网络cs,作者:康由,版权归作者所有,如需转载请注明来源和作者,否则将追究法律责任!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。

文章评论