学Javaweb第四天——springboot入门

一、springboot介绍

现在的项目基本都是基于springboot来开发的,springboot就是简单化的spring框架。

1.1 简单的springboot应用

以前创建Java的普通项目模块时,如图:

现在创建springboot,如图:

之后next---------选版本都可以,就是不选快照版本------------依赖项选择web spring。

左侧进行删除,只剩这几个部分:如图:

打开该springboot的项目模块,发现:

父工程,version是springboot的版本,下面是该模块的坐标。这个pom.xml不用改动。

  1. 并且,main下面的java包下面有一个启动类,就是用来启动项目的,当该项目模块写好后,就可以运行这个启动类,来运行整个项目。
  2. **static包里面是静态资源,是HTML、CSS、JS等。**templates是模板。下面的application.properties是配置文件。

前面说:浏览器访问网页,都是从tomcat这个web服务器请求网页的,现在电脑上没有安装tomcat,为什么依旧能运行呢?

起步依赖,会将tomcat服务器内嵌进来,这个main方法运行后,将启动内嵌进来的TomCat服务器,会将我们所编写的项目代码部署在这个tomcat服务器当中,之后就可以用浏览器来访问所制作的页面。

所以我们不用在电脑上单独安装tomcat服务器,因为有起步依赖,已经将tomcat服务器内嵌进来了。

代码示例:

java 复制代码
package com.itheima.springbootquickstart;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class helloProject {
    @RequestMapping("/hello")
    public String hello(String name){
        System.out.println("hello"+name);
        return "hello,"+name+"~";
    }
}

name形参接收的就是搜索的网址上写的name值。return 返回的是网页中会显示的字符。

输出结果:

类的注解(处理请求)和方法的注解(请求路径)一定要写,方法的注解requestmapping(" "),括号里面写网址信息,代表:这个方法要处理哪一个网址的请求。

1.2 HTTP协议

1.2.1 HTTP请求协议

请求数据格式
服务器是如何获取请求数据的?

把浏览器发送来的请求数据都封装在了HttpServletRequest这个类的某个对象中,并把这个对象传递给了请求处理类中的方法,供这些方法调用。

代码示例:

1.2.2 HTTP响应协议

响应数据
状态码
1)状态码3XX:重定向解释:

一开始浏览器向A 请求资源,但是资源不在A服务器,所以A响应 "3XX"状态码来重定向,浏览器就去B服务器去找资源,最后得到资源。

2)状态码404解释:找一个不存在的网页资源。

因为在本机并没有创建一个/request2的请求处理类,所以会返回404:找不到资源。

3)"状态码500"解释------服务器端错误

让服务器端的请求处理类的代码发生错误。

4)这三个状态码要掌握
响应头
响应数据设置

方式一:

**理解:**响应数据是自己写的,因为我们现在写的代码就是web服务器里面要存储的资源,我们现在就是服务器,在浏览器上访问对应网址,返回什么内容,由我们写的getwrite.write()方法来实现。

**问题:****两个请求处理类的请求地址一样,如果运行启动类了,会不会两个类的方法都运行?**比如及获取请求数据、简单的hello案例?

------------答案:不能,每个请求处理类中的方法的请求地址都不能一样,因为如果一样了,那就不知道调用哪个方法了。

输出结果:

方式二:

输出结果:

响应数据总结:

二、Springboot简单案例

代码:

要利用糊涂包这个依赖来使用工具,便捷地读取文件中的数据

请求处理类:

java 复制代码
package com.itheima;

import cn.hutool.core.io.IoUtil;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

@RestController
public class collol {
    @RequestMapping("/list")
    public List<User> list() throws FileNotFoundException {

        //1.要先把user.txt的文档数据给读取到一个集合当中list
          //先得到user.txt的输入流

        InputStream in = this.getClass().getClassLoader().getResourceAsStream("user.txt");
        ArrayList<String> list = IoUtil.readLines(in, "utf-8", new ArrayList<>());

        //2.把list集合中的数据变为user类的对象,进行封装
           //用stream流
        List<User> userlist =  list.stream().map(u -> {
            String[] str = u.split(",");
            System.out.println(str);
            Integer id = Integer.parseInt(str[0]);
            String username = str[1];
            String password = str[2];
            String name = str[3];
            Integer age = Integer.parseInt(str[4]);
            LocalDateTime updateTime = LocalDateTime.parse(str[5], DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            return new User(id, username, password, name, age, updateTime);
        }).collect(Collectors.toList());
        System.out.println(userlist);

        return userlist;


    }
}

User类:

java 复制代码
package com.itheima;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;



public class User {
    private Integer id;
    private String username;
    private String password;
    private String name;
    private Integer age;
    private LocalDateTime updateTime;

    public User(Integer id, String username, String password, String name, Integer age, LocalDateTime updateTime) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.name = name;
        this.age = age;
        this.updateTime = updateTime;
    }

    public User() {
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", updateTime=" + updateTime +
                '}';
    }

    /**
     * 获取
     * @return id
     */
    public Integer getId() {
        return id;
    }

    /**
     * 设置
     * @param id
     */
    public void setId(Integer id) {
        this.id = id;
    }

    /**
     * 获取
     * @return username
     */
    public String getUsername() {
        return username;
    }

    /**
     * 设置
     * @param username
     */
    public void setUsername(String username) {
        this.username = username;
    }

    /**
     * 获取
     * @return password
     */
    public String getPassword() {
        return password;
    }

    /**
     * 设置
     * @param password
     */
    public void setPassword(String password) {
        this.password = password;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public Integer getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(Integer age) {
        this.age = age;
    }

    /**
     * 获取
     * @return updateTime
     */
    public LocalDateTime getUpdateTime() {
        return updateTime;
    }

    /**
     * 设置
     * @param updateTime
     */
    public void setUpdateTime(LocalDateTime updateTime) {
        this.updateTime = updateTime;
    }
}

用lombok注解的User类:

java 复制代码
package com.itheima;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Integer id;
    private String username;
    private String password;
    private String name;
    private Integer age;
    private LocalDateTime updateTime;


}

前端:

前端使用ajax请求的地址/list 要和请求处理类的requestMapping的地址一样。

注:lombok注解无法使用,用的ptg成功了。之后把ptg删了,又用的注解,又成功了!???

运行结果:

总结:

三、分层解耦

3.1 三层架构

代码:

代码目录以后都这样写:

一个包里面先写接口--------再写实现类的包impl---------再写实现类XXXImpl。

java 复制代码
package com.itheima.service.impl;

import com.itheima.dao.UserDao;
import com.itheima.dao.impl.UserDaoImpl;
import com.itheima.pojo.User;
import com.itheima.service.UserService;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;

public class UserServiceImpl implements UserService {
    private UserDao userDao=new UserDaoImpl();

    @Override
    public List<User> findAll() {

        List<String> list = userDao.findAll();

        //2.把list集合中的数据变为user类的对象,进行封装
        //用stream流
        List<User> userlist = list.stream().map(u -> {
            String[] str = u.split(",");
            System.out.println(str);
            Integer id = Integer.parseInt(str[0]);
            String username = str[1];
            String password = str[2];
            String name = str[3];
            Integer age = Integer.parseInt(str[4]);
            LocalDateTime updateTime = LocalDateTime.parse(str[5], DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            return new User(id, username, password, name, age, updateTime);
        }).collect(Collectors.toList());

        return userlist;
    }
}
java 复制代码
package com.itheima.service;

import com.itheima.pojo.User;

import java.util.List;

public interface UserService {
    public List<User> findAll();
}
java 复制代码
package com.itheima.controller;

import com.itheima.pojo.User;
import com.itheima.service.UserService;
import com.itheima.service.impl.UserServiceImpl;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class UserControl {

    private UserService userService=new UserServiceImpl();

    @RequestMapping("/list")
    public List<User> list(){

        List<User> userlist = userService.findAll();

        return userlist;


    }
}

访问顺序图:

拆分前后对比:

总结:

3.2 分层解耦

controller和service之间通过创建对象,调用对象的方法来关联(耦合),为了以后在更新类service时,改动代码不那么复杂,就开始了解耦。

解耦的方法是:不在原来的地方new XXX来创建对象,调用对象方法。而是:

  1. 控制反转IOC:把创建对象的控制权由程序的new 类名------>>>由IOC容器创建。
  2. 依赖注入DI:容器为程序提供其运行时所需要的对象。
  3. Bean对象:IOC容器内的对象就是Bean对象。

3.3 分层解耦代码实现

代码:

UserDaoImpl类 和 UserServiceImpl类 上面加一个注解@component

原来new 对象的成员变量上面加一个注解@Autowired

3.4 IOC详解

  1. 控制层、业务层和数据访问层的IOC注解都不一样,要规范使用。
  2. 控制层的@resControl注解已经包含了@Controller注解,不用再写了。

所以在写web应用时,一定要注意模块代码的结构:启动类一定要在com.itheima下面。这样才能扫描IOC的四大注解。这些IOC的注解(把类的对象都放到容器中)才能生效。

3.5 DI详解

需要使用对象的时候,用到@Autowired给成员变量。

DI要做的就是给类的成员变量赋值,只不过这个成员变量不是基本数据类型,而是我们自己定义的业务逻辑类、数据访问类等。所以,我们的目的是让 对象类型的成员变量被赋值。

一般情况下,给成员变量赋值有三种方法:1)直接赋值-------属性注入 2)构造方法赋值-------构造函数注入 3)set方法赋值---------setter注入

IOC容器里都是各种类型的对象值,DI要做的就是把对应类型的对象值捞出来,通过这三种方法的其中一种给成员变量赋上值。

常用的是 属性注入 和 构造函数注入。90%的项目用属性注入,因为代码简单;构造函数注入更加规范。setter注入很少用。

代码示例:

构造方法注入

setter注入

3.5.1 DI注意事项

当存在多个相同接口类型的实现类时,此时IOC容器有多个相同类型的对象,直接运行会报错。

有以下三个方法来解决:@primary @Qualifier @Resource

@primary:

@Qualifier:

理解:

  1. return返回的是前端ajax请求所需要的数据,因为有RestController注解,所以响应给前端的数据就会自动变成json格式给前端。
  2. 后端启动类的这些代码,其实就是与数据库交互数据、指令来完成前端的需要。
  3. 前端可以通过浏览器直接打开,但是后端必须要启动类启动之后,被动地等待前端的请求才能返回数据。
相关推荐
毕设源码-赖学姐2 小时前
【开题答辩全过程】以 基于Springboot的球场管理平台的设计与实现为例,包含答辩的问题和答案
java·spring boot·后端
C雨后彩虹2 小时前
HashMap的线程安全问题:原因分析与解决方案
java·数据结构·哈希算法·集合·hashmap
有趣灵魂2 小时前
Java-Spingboot根据HTML模板和动态数据生成PDF文件
java·pdf·html
BIBI20492 小时前
Windows 上配置 Nacos Server 3.x.x 使用 MySQL 5.7
java·windows·spring boot·后端·mysql·nacos·配置
一雨方知深秋2 小时前
面向对象高级语法 1-- 继承、多态
java·方法重写·继承extends·子类构造器调用父类构造器·兄弟构造器this·对象、行为多态·解耦合父类变量为形参接子类对象
月明长歌2 小时前
【码道初阶】Leetcode771 宝石与石头:Set 判成员 vs List 判成员(同题两种写法的差距)
java·数据结构·leetcode·list·哈希算法·散列表
xiaoyustudiowww2 小时前
Jakarta EE 12(JAVA EE12)平台包含规范版本
java·java-ee
wniuniu_2 小时前
ceph的参数
java·数据库·ceph
AC赳赳老秦2 小时前
DeepSeek-Coder vs Copilot:嵌入式开发场景适配性对比实战
java·前端·后端·struts·mongodb·copilot·deepseek