Kaze
Kaze
Published on 2023-10-20 / 18 Visits
0
0

Spring Web 全栈(一)

  • Maven

    • Maven 是一个项目管理和构建自动化工具

    • Maven项目结构

      目录目的
      ${basedir}存放 pom.xml 和所有的子目录
      ${basedir}/pom.xmlMaven 的项目配置文件
      ${basedir}/src/main/java项目的 java 源代码
      ${basedir}/src/main/resources项目的资源,比如说 property 文件
      ${basedir}/src/test/java项目的测试类,比如说 JUnit 代码
      ${basedir}/src/test/resources测试使用的资源
    • Maven命令

      mvn clean compile编译
      mvn clean package编译并打包
      mvn clean install编译、打包并安装到本地的 Maven 仓库目录里
      mvn compile exec:java -Dexec.mainClass=${main}编译并执行
      
    • Maven配置文件pom.xml

      1、Maven 坐标

      2、Maven 工程属性

      3、Maven 依赖

      4、Maven 插件

  • Java 注解(Annotation)

    • 和普通的注释的区别是Annotation 是可以在编译、运行阶段读取的,Annotation 是一个特殊的 Java 类

    • @Service注解源码

      img

  • Spring Bean

    • 所有的 Java 对象都会通过 IoC 容器转变为 Bean

    • 启动IoC容器

      ApplicationContext context = 
          new AnnotationConfigApplicationContext("fm.douban");
      在fm.douban这个包下所有引用了 Spring 注解的类都会被加载
          //获取一个实例
          context.getBean(类名.class)
      
    • 声明为 Spring Bean 的注解

      @Component注解是通用的 Bean 注解,其余三个注解都是扩展自Component
      @Service正如这个名称一样,代表的是 Service Bean
      @Controller作用于 Web Bean
      @Repository作用于持久化相关 Bean
      
    • 加注解的作用,是让 Spring 系统 自动 管理 各种实例。

      所谓 管理 ,就是用 @Service 注解把 SubjectServiceImplSongServiceImpl 等等所有服务实现,都标记成 Spring Bean ;然后,在任何需要使用服务的地方,用 @Autowired 注解标记,告诉 Spring 这里需要注入实现类的实例。项目启动过程中,Spring自动 实例化服务实现类,然后 自动 注入到变量中

      @Autowired
      private SongService songService;
      
    • 读取jar内部文件

      • 依赖

        <dependency>
          <groupId>commons-io</groupId>
          <artifactId>commons-io</artifactId>
          <version>2.6</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>5.2.1.RELEASE</version>
        </dependency>
        
      • //在 Spring Resource 当中,把本地文件、classpath文件、远程文件都封装成 Resource 对象来统一加载
        @Autowired
            private ResourceLoader loader;
        
            @Override
            public String getContent(String name) {
                try {
                    InputStream in = loader.getResource(name).getInputStream();
                    return IOUtils.toString(in,"utf-8");
                } catch (IOException e) {
                   return null;
                }
            }
        name="classpath:data/urls.txt"
            or"file:mywork/readme.md"
            or"https://www.zhihu.com/question/34786516/answer/822686390"
        
      • //常规方法读取jar内部文件
        public class Test {
        
          public static void main(String[] args) {
            // 读取 classpath 的内容
            InputStream in = Test.class.getClassLoader().getResourceAsStream("data.json");
            // 使用 commons-io 库读取文本
            try {
              String content = IOUtils.toString(in, "utf-8");
              System.out.println(content);
            } catch (IOException e) {
              // IOUtils.toString 有可能会抛出异常,需要我们捕获一下
              e.printStackTrace();
            }
          }
        
        }
        
      • 初始化Bean

        //只要在方法上添加@PostConstruct注解,就代表该方法在 Spring Bean 启动后会自动执行
        @PostConstruct
          public void init(){
              System.out.println("启动啦");
          }
        // @PreDestroy 在Bean销毁前执行
        
  • SpringMVC

    • 快速创建springboot工程:https://start.spring.io/

    • Spring Controller 本身也是一个 Spring Bean,只是它多提供了 Web 能力,只需要在类上提供一个 @Controller 注解就可以,若只返回数据不渲染网页可以用@RestController这样就不用写@ResponseBody了

    • 在 Spring Boot 应用中,一般把网页存放在 src/main/resources/static,在 controller 中,会自动加载 static 下的 html 内容

    @Controller
    public class HelloControl {
    
        public String say(){
            return "hello.html";//返回的是 html 文件路径
        }
    
    }
    
    • 对于 Web 服务器来说,必须要实现的一个能力就是解析 URL,并提供资源内容给调用者。这个过程一般我们称为路由,Spring MVC 完美的支持了路由能力,并且简化了路由配置,只需要在需要提供 Web 访问的 方法上添加一个 @RequestMapping 注解就可以完成配置
    @Controller
    public class HelloControl {
    
        @RequestMapping("/hello")
        public String say(){
            return "html/hello.html";
        }
    
    }
    
    • 一般情况下,我们会把 controller 类存放在 control子包里

    • 定义URL参数

    @Controller
    public class SongListControl {
    
        @RequestMapping("/songlist")
        public String index( @RequestParam("id") String id){
            return "html/songList.html";
        }
    
    }
    //多参数
    public String index(@RequestParam("id") String id,  @RequestParam("pageNum") int pageNum)
    
    • @RequestMapping默认是支持所有的 Http Method的,放开所有的 Http Method 这样不是很安全,所以get请求要使用@GetMapping

    • 非必须传递参数

    public String index(@RequestParam(name="pageNum",required = false) int pageNum,@RequestParam("id") String id)
    
    • 输出JSON数据
    @GetMapping("/api/foos")
    @ResponseBody
    public String getFoos(@RequestParam("id") String id) {
      return "ID: " + id;
    }
    
    • 输出对象
    @GetMapping("/api/user")
      @ResponseBody
      public User getUser(@RequestParam("id") String id) {
        return users.get(id);
      }
    }
    //Spring MVC 会自动的把对象转化成 JSON 字符串输出到网页
    //一般我们会把这种输出JSON数据的方法称为 API
    
  • Thymeleaf

    • 依赖:

      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
      </dependency>
      
    • 数据传递:只需要我们在方法参数里引入一个Model对象,就可以通过这个 Model 对象传递数据到页面中了。

      @Controller
      public class SongListControl {
      
        @Autowired
        private SongListService songListService;
      
        @RequestMapping("/songlist")
        public String index(@RequestParam("id")String id,Model model){
      
          SongList songList = songListService.get(id);
          //传递歌单对象到模板当中
          //第一个 songList 是模板中使用的变量名
          // 第二个 songList 是当前的对象实例
          model.addAttribute("songList",songList);
      
          return "songList";
        }
      }
      
    • 模板文件:模板文件是有固定的存放位置,放置在工程的 src/main/resources/templates

      <!DOCTYPE html>
      <html lang="en" xmlns:th="http://www.thymeleaf.org">
        <head>
          <meta charset="UTF-8" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <meta http-equiv="X-UA-Compatible" content="ie=edge" />
          <link rel="stylesheet" href="/css/songList.css" />
          <title>豆瓣歌单</title>
        </head>
        <body>
          <h1 th:text="${songList.name}"></h1>
        </body>
      </html>
      //xmlns:th="http://www.thymeleaf.org" 的作用是,在写代码时,让软件能识别 thymeleaf 语法
      
    • 语法:

      • 变量:

        • th:text 语法的作用就是会动态替换掉 html 标签的内部内容
        • 模板的变量都是会存放在模板上下文中,所以我们如果想要调用变量,就需要先设置变量到模板上下文中去,你只需要像上节课一样model.addAttribute("songList",songList);就可以完成上下文变量的设置
        • 模板语言还可以支持复杂对象的输出,我们完全可以使用 . 把属性调用出来
      • 条件语句:

        • if:<span th:if="${user.sex == 'male'}">男</span>

        • else:<span th:unless="${user.sex == 'male'}">女</span>

        • if 表达式的值是 ture 的情况下就会执行渲染

        • 如下表达式为true

          值非空
          值是非0数字
          值是字符串,但是不是 false, off or no
          值不是 boolean 值,数字,character 或 字符串
          
      • 循环:

        • <ul>
            <li th:each="song,it: ${songs}">
              <span th:text="${it.count}"></span>
              <span th:text="${song.name}"></span>
            </li>
          </ul>
          //
          
        • it 是作为可选参数出现,如果定义了就可以通过这个 it 对象来获取更多关于统计的需求

          • it.index
            

            当前迭代对象的 index(从 0 开始计算),如果想从 0 开始显示行数用这个就可以了

          • it.count
            

            当前迭代对象的 index(从 1 开始计算),如果显示行数用这个就可以了

          • it.size
            

            被迭代对象的大小,如果想获取列表长度,用这个就可以了

          • it.current
            

            当前迭代变量,等同与上面的 song

          • it.even/odd
            

            布尔值,当前循环是否是偶数/奇数(从 0 开始计算)

          • it.first
            

            布尔值,当前循环是否是第一个

          • it.last
            

            布尔值,当前循环是否是最后一个

      • 表达式:

        • 字符串拼接:

          <span th:text="'00:00/'+${totalTime}"></span>
          
          <span th:text="|00:00/${totalTime}|"></span>
          
        • 内联表达式:

          <span>Hello [[${msg}]]</span> //[[变量]]
          
        • 数据转化:

          • Date:工具类temporals:处理LocalDateLocalDateTime类,处理日期类型到字符串的转化

            • 依赖:

              <dependency>
                <groupId>org.thymeleaf.extras</groupId>
                <artifactId>thymeleaf-extras-java8time</artifactId>
                <version>3.0.4.RELEASE</version>
              </dependency>
              
            • <p th:text="${#temporals.format(dateVar, 'yyyy-MM-dd')}"></p>
              <p th:text="${#temporals.format(dateVar, 'yyyy年MM月dd日')}"></p>
              
            • 变量使用的是 ${变量名},工具类使用的是#{工具类}

          • string:

            • ${#strings.contains(name,'abc')}
              检查字符串变量是否包含片段
              
              ${#strings.containsIgnoreCase(name,'abc')}
              先忽略大小写字母,然后去判断是否包含指定的字符串
              
              ${#strings.startsWith(name,'abc')}
              判断字符串是不是以 abc 开头的
              
              ${#strings.endsWith(name,'abc')}
              判断字符串是不是以 abc 结束的
              
            • 检查字符串变量是否为空(或者为 null),在检查之前会先执行 trim() 操作,去掉空格

              ${#strings.isEmpty(name)}
              

              数组也适用 isEmpty

              ${#strings.arrayIsEmpty(name)}
              

              集合类也适用 isEmpty

              ${#strings.listIsEmpty(name)}
              
            • ${#strings.toUpperCase(name)}
              

              把字符串改成全大写

            • ${#strings.toLowerCase(name)}
              

              把字符串改成全小写

            • ${#strings.arrayJoin(array,',')}
              

              把字符串数组合并成一个字符串,并以,连接,比如["a","b"]执行后会变成a,b

            • ${#strings.arraySplit(str,',')}
              

              把字符串分隔成一个数组,并以,作为分隔符,比如a,b执行后会变成["a","b"];如果abc没有匹配到,执行后会变成["abc"]

            • ${#strings.trim(str)}
              

              把字符串去空格,左右空格都会去掉

            • ${#strings.length(str)}
              

              得到字符串的长度,也支持获取集合类的长度

            • ${#strings.equals(str1,str2)}
              

              比较两个字符串是否相等

            • ${#strings.equalsIgnoreCase(str1,str2)}
              

              忽略大小写后比较两个字符串是否相等

          • //完整的内置对象
            #messages
            #urls/uris
            #conversions
            #dates
            #calendars
            #numbers
            #strings
            #objects
            #bools
            #arrays
            #lists
            #sets
            #maps
            #aggregates
            #ids
            

Comment