Bootstrap

Web day04 SpringBoot

目录

1.Spring概念:

2. spring程序快速入门:

3.HTTP协议:

特点:

基于TCP 协议:

基于请求响应模型:

HTTP协议是无状态协议:

请求协议:为浏览器向服务器发出的消息

获取请求数据:

响应协议:为服务器向浏览器发出的消息

4.Spring 三层架构:

controller层:

service层:

dao层:

hutool:

IOC & DI  :

1). 将Service及Dao层的实现类,交给IOC容器管理

2). 为Controller 及 Service注入运行时所依赖的对象

替代方式:

组件扫描:

DI详解:

1). 属性注入(使用的最多)

2). 构造函数注入

3). setter注入

IOC 中存在多个类型相同的 bean 对象的问题:


1.Spring概念:

Spring是多个框架的集合,一种生态圈

提供了非常多的子项目 用于解决不同的问题 

SpringBoot 是 spring 提供的 用于快速构建 spring项目的一个子项目 

spring freamwork 是 spring 众多子项目 中的 基础核心项目 

2. spring程序快速入门:

在点击 creat创建项目之后

会自动生成 开始 类

自定义一个请求处理类:

spring框架会根据注解 和 tocat用tcp传输 socket接受到的 值做比较 如果 根据反射创造 请求类 

如果请求类中 方法上注解的值 和 socket 接受到的值一样 则 利用反射 执行这个方法 

3.HTTP协议:

特点:

基于TCP 协议:

基于请求响应模型:

相应和请求时一一对应的

HTTP协议是无状态协议:
 

对于数据没有记忆功能 每次请求-相应都是独立的

请求协议:为浏览器向服务器发出的消息

只有post请求才有请求体

get 的请求参数在请求行中

  • GET方式的请求协议:

POST方式的请求协议:

举例说明:服务端可以根据请求头中的内容来获取客户端的相关信息,有了这些信息服务端就可以处理不同的业务需求。

比如:

  • 不同浏览器解析HTML和CSS标签的结果会有不一致,所以就会导致相同的代码在不同的浏览器会出现不同的效果

  • 服务端根据客户端请求头中的数据获取到客户端的浏览器类型,就可以根据不同的浏览器设置不同的代码来达到一致的效果(这就是我们常说的浏览器兼容问题)

  • 请求体 :存储请求参数

    • GET请求的请求参数在请求行中,故不需要设置请求体

获取请求数据:

 url 统一资源定位符: 需要通过该符号定位到网络上唯一的资源

uri 统一资源表示符: 可以标识某台服务器中唯一的资源

当tomcat接收到浏览器的请求后, 会把请求消息解析, 并封装到一个HttpServletRequest对象中, 反射执行方法时,会自动传入

@RestController
public class RequestController {

    /**
     * 请求路径 http://localhost:8080/request?name=Tom&age=18
     * @param request
     * @return
     */
    @RequestMapping("/request")
    public String request(HttpServletRequest request){
        //1.获取请求参数 name, age
        String name = request.getParameter("name");
        String age = request.getParameter("age");
        System.out.println("name = " + name + ", age = " + age);
        
        //2.获取请求路径
        String uri = request.getRequestURI();
        String url = request.getRequestURL().toString();
        System.out.println("uri = " + uri);
        System.out.println("url = " + url);
        
        //3.获取请求方式
        String method = request.getMethod();
        System.out.println("method = " + method);
        
        //4.获取请求头
        String header = request.getHeader("User-Agent");
        System.out.println("header = " + header);
        return "request success";
    }

}

响应协议:为服务器向浏览器发出的消息

  • 响应协议:服务器将数据以响应格式返回给浏览器。包括:响应行 、响应头 、响应体

 

相应状态码:

4xx 为客户端 访问资源不存在 客户端问题

5xx 为服务端抛出异常 服务端问题

200 为客户端请求成功

响应状态码 和 响应头如果没有特殊要求的话,通常不手动设定。服务器会根据请求处理的逻辑,自动设置响应状态码和响应头。

4.Spring 三层架构:

@RestController 由两个注解组成  @Controller 、@ResponseBody

@Controller 为标识 这个 类是 一个请求处理的类

@ResponseBody:   返回的内容可以根据请求的 Accept 头自动转换为 JSON、XML 等不同格式的数据

三层架构:


controller :控制层: 接受请求, 给出响应

service :业务层: 处理业务逻辑

dao :数据层: 文件/数据库的操作

controller层:

@RestController
//包含 @Controller 和 @ResponseBody
public class UserController {


    @Autowired
    private UserSerivice userSerivice;
    @RequestMapping("/list")
    public List<User> list(HttpServletRequest request){

        String name = request.getParameter("name");
        System.out.println(name);
        String age = request.getParameter("age");
        System.out.println(age);
        List<User> finalList = new ArrayList<>();
        List<User> collect = userSerivice.list();
        if ((name==null)||(name.equals(""))&&((age==null) || age.equals(""))){
            finalList = collect;
        }else if ((name != null)&&(age == null || age.equals(""))){
            finalList = collect.stream().filter((user) -> user.getName().equals(name)).collect(Collectors.toList());
        } else if ((name == null || name.equals(""))&&(age != null)) {
            finalList = collect.stream().filter((user) -> user.getAge() == Integer.parseInt(age)).collect(Collectors.toList());
        }else{
            finalList = collect.stream().filter((user) -> user.getName().equals(name)&&user.getAge() == Integer.parseInt(age)).collect(Collectors.toList());
        }
        return finalList;
    }
}

service层:

//@Component 或 @Service 都可以
@Service
public class UserServiceImpl implements UserSerivice{

    @Autowired
    UserDao users;
    @Override
    public List<User> list() {
        List<String> list = users.list();

        List<User> collect = list.stream().map((s) -> {
            String[] split = s.split(",");
            User user = new User(Integer.parseInt(split[0]), split[1], split[2], split[3], Integer.parseInt(split[4]), LocalDateTime.parse(split[5], DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            return user;
        }).collect(Collectors.toList());

        return collect;
    }
}

dao层:

//@Component 或 @Repository 都可以
@Repository
public class UserDaoImpl implements UserDao {
    @Override
    public List<String> list() {
        InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("user.txt");
        ArrayList<String> strings = IoUtil.readLines(resourceAsStream, "UTF-8", new ArrayList<>());
        return strings;
    }
}

classLoader.getResource()  默认从类路径下获取内容 类路径为:java文件夹下的和resources文件夹下的

getResourceAsStream()可以得到一个文件或网络的 输入流对象 

url :获取的为文件的绝对路径   在请求协议的 获取相应数据中url可以 定位到 网络上的唯一资源

 

hutool:

IoUtil 为hutool 工具包下的类 

hutool的 坐标为:

IoUtil.readLines(输入流,编码格式,Collection集合)   :可以一起读取多行数据

Collection 为单链集合 包括 list 和 set 接口

https://blog.csdn.net/moskidi/article/details/143693695?spm=1001.2014.3001.5501

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.27</version>
        </dependency>

IOC & DI  :

 

把三层架构中的每一层进行结构 sercvice层需要数据时之间 从 容器中 获取dao对象

controller 需要获取 结果时 从 容器中创建 service对象 

IOC容器中的对象 被称为 been对象 

1). 将Service及Dao层的实现类,交给IOC容器管理

在实现类加上 @Component 注解,就代表把当前类产生的对象交给IOC容器管理。

2). 为Controller 及 Service注入运行时所依赖的对象

@Autowired 为自动 在容器中寻找对应对象 并且依赖注入 

替代方式:

 那么此时,我们就可以使用 @Service 注解声明Service层的bean。 使用 @Repository 注解声明Dao层的bean。

@RestController 中已经包含了@Controller

注意:

明bean的时候,可以通过注解的value属性指定bean的名字,如果没有指定,默认为类名首字母小写。

组件扫描:

使用前面学习的四个注解声明的bean不一定会生效  bean想要生效,还需要被组件扫描

注意 : 默认扫描的 范围时 启动类 所在的包 及其子包

DI详解:

@Autowired 进行依赖注入,常见的方式,有如下三种:

1). 属性注入(使用的最多)

  • 优点:代码简洁、方便快速开发。

  • 缺点:隐藏了类之间的依赖关系、可能会破坏类的封装性。

2). 构造函数注入

  • 注意:如果只有一个构造函数,@Autowired注解可以省略。(通常来说,也只有一个构造函数)

3). setter注入

IOC 中存在多个类型相同的 bean 对象的问题:

那如果在IOC容器中,存在多个相同类型的bean对象,会出现什么情况呢?

如何解决上述问题呢?Spring提供了以下几种解决方案:

  • @Primary

  • @Qualifier

  • @Resource

方案一:使用@Primary注解

当存在多个相同类型的Bean注入时,加上@Primary注解,来确定默认的实现。

有多个UserService 类型的 bean 是 可以 用  @Primary 来 指定注入的bean 对象

@Primary
@Service
public class UserServiceImpl implements UserService {
}

 

方案二:使用@Qualifier注解

指定当前要注入的bean对象。 在@Qualifier的value属性中,指定注入的bean的名称。 @Qualifier注解不能单独使用,必须配合@Autowired使用。

 

在DI 注入 时 可以用@Qulifier 指定注入 bean 的名称

@RestController
public class UserController {

    @Qualifier("userServiceImpl")
    @Autowired
    private UserService userService;

 

方案三:使用@Resource注解

是按照bean的名称进行注入。通过name属性指定要注入的bean的名称。

注意:@Resource 注解 由 jdk 提供 而不是spring

注解中没有 value 属性名 所以需要 用 name = 指定 属性值

@RestController
public class UserController {
        
    @Resource(name = "userServiceImpl")
    private UserService userService;

面试题:@Autowird 与 @Resource的区别

  • @Autowired 是spring框架提供的注解,而@Resource是JDK提供的注解

  • @Autowired 默认是按照类型注入,而@Resource是按照名称注入

;