五.spring boot

通过springboot可以快速的搭建一个基于ssm框架的Java application,简单配置,自动装配

JavaConfiguration用java类来替代xml

Spring boot对常用的第三方的类库提供了方案,可以很好的和spring进行整合,一键搭建功能完备的java企业级的应用

开箱即用是Springboot的特点

优势:

  • 不需要任何的xml配置文件

  • 内嵌了Tomcat,看可以直接的部署

  • 默认转换json数据,不需要转换

  • 支持RESTful

  • 配置文件简单、支持YAM格式

    Spring boot是一种只需要极少配置的,就可以快速搭建spring应用,并且集成了常用的第三方的类库,让开发者可以快速的进行企业级的应用开发

Spring Boot2.x要求碧血基于Spring5.x,spring5.x要求java版本必须是8以上

开发

1.创建handller

package com.southwind.springboot.controller;

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

@RestController
@RequestMapping("/hello")
public class HelloHandler {
    @GetMapping("/index")
    public String index(){
        return "hello spring boot";
    }
}

2.创建启动类

package com.southwind.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringbootApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootApplication.class, args);
    }

}

启动类必须覆盖所有与业务相关的类:启动类所在的包必须是业务类所在的包或者父包,如果没有覆盖业务类就不会自动装配到ioc容器里

springboot的配置文件

1.改端口:

server.port=8181

2.自定义banner.txt

hello spring boot
#设置端口
server.port=8181
#项目访问路径
server.servlet.context-path=/springboot
#cookie失效时间
server.servlet.session.cookie.max-age=100
#session的失效时间
server.servlet.session.timeout=100
#编码格式
server.tomcat.uri-encoding=UTF-8

YAML:

YAML是不同与Properties的另一种形式,他同样可以用来写配置文件,springboot默认支持YAML格式。

优点:

编写简单,结构清晰,利用缩进的形式来表现层级关系

相比Properties更加简单编写,更加方便。

使用YAML格式:

server:
  port: 8181
  servlet:
    context-path: /springboot
    session:
      cookie:
        max-age: 100
      timeout: 100
  tomcat:
    uri-encoding: utf-8

YAML格式的书写规范非常严格,属性名和属性之间必须要有一个空格

如果properties和YAML的优先级谁会更高呢?

properties会更高

配置文件除了可以放在resources路径之外还可以有三个位置

  • 工程根路径

  • resource下

  • resource下的包

  • 项目的src同级下的包内

    优先级

1.项目的src同级下的包内

2.工程根路径

3.resource下的包

4.resource下

可以直接在Handller中读取YAML中的数据,比如我们在业务方法中向客户端返回当前服务的端口的信息

package com.southwind.springboot.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/hello")
public class HelloHandler {

    @Value("${server.port}")
    private String port;
    @GetMapping("/index")
    public String index(){
        return "当前服务的端口是"+this.port;
    }
}

@Value注解同样适用于properties文件

Springboot整合JSP

spring boot与视图层次的整合:

  • JSP 效率低

  • Thymeleaf


java Server page 是Java提供的一种动态的网页技术,低层是Servlet,可以直接在HTML中插入Java代码

JSP的底层的原理:

JSP是一种中间层的组件,开发者可以在这个组件中将java代码,与html代码进行整合,有jsp的引擎组件转为Servlet,再把开发者定义在组件的混合代码翻译成Servlet的相应语句,输出给客户端。

1.创建工程:基于maven的项目

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>
  <!--    Spring boot父依赖-->
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.4.RELEASE</version>
  </parent>
  <dependencies>
<!--    Spring boot-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-jasper</artifactId>
      <version>9.0.26</version>
    </dependency>
  </dependencies>

2.创建Handler

package com.southwind.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
@RequestMapping("/hello")
public class HelloHandler {
    @GetMapping("/index")
    public ModelAndView index(){
        ModelAndView modelAndView =new ModelAndView();
        modelAndView.setViewName("index");
        modelAndView.addObject("mess","hello spring boot");
        return modelAndView;
    }
}

3.JSP

<%--
  Created by IntelliJ IDEA.
  User: 郝泾钊
  Date: 2022-04-10
  Time: 13:34
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@page isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>index</h1>
        ${mess}
</body>
</html>

4.application.yml

server:
  port: 8181
spring:
  mvc:
    view:
      prefix: /
      suffix: .jsp

实际应用时

<!--    JSTL-->
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
<!--    lombok-->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.22</version>
    </dependency>

lombok简化实体类代码的编写工作

常用的方法:getter、setter、toString自动生成lombox的使用要安装插件

实现增删改查(JSP)

1.实体类:User

package com.southwind.entity;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class User {
    private Integer id;
    private  String name;
}

2.控制器:UserHandler

package com.southwind.controller;

import com.southwind.Service.UserService;
import com.southwind.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.List;

@Controller
@RequestMapping("/user")
public class UserMapper {
    @Autowired
    private UserService userService;
    @GetMapping("/findall")
    public ModelAndView findall(){
        ModelAndView modelAndView= new ModelAndView();
        modelAndView.setViewName("index");
        modelAndView.addObject("list",userService.finAll());
        return modelAndView;

    }
    @GetMapping("findbyid/{id}")
    public ModelAndView findById(@PathVariable("id") Integer id){
        ModelAndView modelAndView=new ModelAndView();
        modelAndView.setViewName("update");
        modelAndView.addObject("user",userService.findById(id));
        return  modelAndView;
    }
    @PostMapping("/save")
    public String save(User user){
        userService.save(user);
        return "redirect:/user/findall";
    }
    @GetMapping("/delete/{id}")
    public String deleteById(@PathVariable("id") Integer id){
        userService.delete(id);
        return "redirect:/findall";
    }
    @GetMapping("/update")
    public  String update( User user){
        userService.uodate(user);
        return "redirect:/user/findall";
    }
}

3.业务Service

接口:

package com.southwind.Service;

import com.southwind.entity.User;

import java.util.Collection;

public interface UserService {
    public Collection<User> finAll();
    public User findById(Integer id);
    public void  save(User user);
    public void delete(Integer id);
    public void uodate(User user);
}

实现类:

package com.southwind.Service.impl;

import com.southwind.Reposity.UserReposity;
import com.southwind.Service.UserService;
import com.southwind.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collection;
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserReposity userReposity;
    @Override
    public Collection<User> finAll() {
        return userReposity.finAll();
    }

    @Override
    public User findById(Integer id) {

        return userReposity.findById(id);
    }

    @Override
    public void save(User user) {
        userReposity.save(user);
    }

    @Override
    public void delete(Integer id) {
        userReposity.delete(id);
    }

    @Override
    public void uodate(User user) {
        userReposity.uodate(user);
    }
}

4.业务:Repositort

接口;

package com.southwind.Reposity;

import com.southwind.entity.User;

import java.util.Collection;

public interface UserReposity {
    public Collection<User> finAll();
    public User findById(Integer id);
    public void  save(User user);
    public void delete(Integer id);
    public void uodate(User user);
}

实现类:

package com.southwind.Reposity.impl;

import com.southwind.Reposity.UserReposity;
import com.southwind.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

@Repository
public class UserReposityImpl implements UserReposity {

    private static Map<Integer,User> map;
    static {
        map=new HashMap<>();
        map.put(1,new User(1,"张三"));
        map.put(2,new User(2,"李四"));
        map.put(3,new User(3,"王五"));
    }

    @Override
    public Collection<User> finAll() {
        return map.values();
    }

    @Override
    public User findById(Integer id) {
        return map.get(id);
    }

    @Override
    public void save(User user) {
        map.put(user.getId(),user);
    }

    @Override
    public void delete(Integer id) {
        map.remove(id);
    }

    @Override
    public void uodate(User user) {
    map.put(user.getId(),user);
    }
}

5.视图层JSP

index.jsp

<%--
  Created by IntelliJ IDEA.
  User: 郝泾钊
  Date: 2022-04-10
  Time: 13:34
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@page isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>index</h1>
        ${mess}
    <table>
        <tr>
            <th>编号</th>
            <th>姓名</th>
            <th>操作</th>
        </tr>
        <c:forEach items="${list}" var="user">
            <tr>
                <td>${user.id}</td>
                <td>${user.name}</td>
                <td>
                    <a href="/user/delete/${user.id}">删除</a>
                    <a href="/user/findbyid/${user.id}">修改</a>
                </td>
            </tr>
        </c:forEach>
    </table>
</body>
</html>

save.jsp:

<%--
  Created by IntelliJ IDEA.
  User: 郝泾钊
  Date: 2022-04-10
  Time: 18:24
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form action="/user/save" method="post">
        <input type="text" name="id"/><br>
        <input type="text" name="name"/><br>
        <input type="submit" value="提交">
    </form>
</body>
</html>

update.jsp

<%--
  Created by IntelliJ IDEA.
  User: 郝泾钊
  Date: 2022-04-10
  Time: 18:27
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@page isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="/user/update" method="post">
    <input type="text" name="id" value="${user.id}"/><br>
    <input type="text" name="name" value="${user.name}"/><br>
    <input type="submit" value="提交">
</form>
</body>
</html>

springboot 整合Thymeleaf

Thymeleaf是目前流行的视图层的技术,Spring boot 官方推荐的使用Thymeleaf

什么是Thymeleaf?

Thymeleaf是一个支持原生的THML文件的java末班,可以实现前后端的分离的交互方式,即视图与业务的数据分开响应,他可以直接返回服务端返回的数据生成HTML文件,同时也可以处理XML、javascript、css等格式。

Thymeleaf的最大特点是即可以直接在浏览器打开(静态方式),也可以结合服务器将业务数据填充到HTML之后启动动态的页面(动态方式),Springboot支持Thymeleaf,使用起来非常方便。

1.创建maven工程

<parent>
    <artifactId>spring-boot-dependencies</artifactId>
    <groupId>org.springframework.boot</groupId>
    <version>2.2.4.RELEASE</version>
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
</dependencies>

2.application.yml

spring:
  thymeleaf:
    prefix: classpath:/templates/          #模版的路径
    suffix: .html                           #模版的后缀
    servlet:
      content-type: text/html             #设置Content-type
    encoding: UTF-8                       #编码方式
    mode: HTML5                            #校验H5的格式
    cache: false                          #关闭缓冲 每次都重新修改页面

3.创建Handler

package com.southwind.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
@RequestMapping("/hello")
public class HellloHandler {
    @GetMapping("/index")
    public ModelAndView index(){
        ModelAndView modelAndView =new ModelAndView();
        modelAndView.setViewName("index");
        modelAndView.addObject("mess","张三");
        return modelAndView;
    }
}

4.启动类

package com.southwind;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
    }
}

5.视图:

HTML

<!DOCTYPE html>
<html lang="en">
<html xmlns:th="http://www.thymaleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>index</h1>
    <p th:text="${mess}">hello word</p>
</body>
</html>

需要引入标签

<html xmlns:th="http://www.thymaleaf.org">
  <p th:text="${mess}">hello word</p>

Thymeleaf是直接嵌入到模版标签的内部的,不同于JSTL模版

Thymeleaf常用标签

  • th:text

    th:text用于文本的显示,将业务的值显示到HTML的页面中

  • th:if

    th:if用于条件判断,对业务数据的判断,如果条件成立,则显示内容,否则不显示,具体的使用:

    @GetMapping("/if")
    public ModelAndView ifTest(){
      ModelAndView modelAndView =new ModelAndView();
      modelAndView.setViewName("test");
      modelAndView.addObject("score",90);
      return modelAndView;
    }

    test.html

    <!DOCTYPE html>
    <html lang="en">
    <html xmlns:th="http://www.thymaleaf.org">
    <head>
      <meta charset="UTF-8">
      <title>Title</title>
    </head>
    <body>
      <p th:if="
    不能识别此Latex公式:
    {score>=90}">优秀</p>
      <p th:if="

    {score<90}">良好</p>
    </body>
    </html>

  • th:unless

    th:unless也用作条件判断,逻辑于if恰好相反,如果条件成立不显示,条件不成立显示

    @GetMapping("/unless")
    public ModelAndView unlessTest(){
      ModelAndView modelAndView =new ModelAndView();
      modelAndView.setViewName("test");
      modelAndView.addObject("score",90);
      return modelAndView;
    }

    html</p></li>
    </ul>
    ¨K76K

    ¨K129K


    • th:switch th:case

    th:switch th:case两结合起来使用,用于多条件的等值判断,逻辑于java的switch case一致,当switch中的业务数据等于摸个case时,就显示该case对应的内容。

    @GetMapping("/switch")
    public ModelAndView switchTest(){
        ModelAndView modelAndView =new ModelAndView();
        modelAndView.setViewName("test");
        modelAndView.addObject("mess",1);
        return modelAndView;
    }
    <!--switch-->
        <div th:switch="${mess}">
            <p th:case="1">优秀</p>
            <p th:case="2">良好</p>
        </div>
    • th:action

      用来指定请求的URL,相当于form表单的action属性

      1.写死

      html</p></li>
      </ul>
      ¨K75K

      2.后端传过来

      <form th:action="${url}" method="get">
          <input type="submit" value="提交">
      </form>
      @GetMapping("/redirect/{url}")
      public String redirect(@PathVariable("url") String url, Model model){
          model.addAttribute("url" ,"/hello/action");
          return  url;
      }
      @GetMapping("/action")
      @ResponseBody
      public String actionTest(){
          return "action";
      }
      • th;each

        用来遍历集合

        1.实体类

        package com.southwind.entity;

        import lombok.AllArgsConstructor;
        import lombok.Data;

        @Data
        @AllArgsConstructor
        public class User {
          private  String  name;
          private  Integer id;
        }

        2.Handler

        @GetMapping("/each")
        public ModelAndView each(){
          List<User> users = Arrays.asList(new User("张三",1),new User("李四",2),new User("王五",3));
          ModelAndView modelAndView =new ModelAndView();
          modelAndView.setViewName("test");
          modelAndView.addObject("list",users);
          return modelAndView;
        }

        3.视图

        html</p></li>
        </ul>
        ¨K77K

        ¨K130K


        • th:value

          用来给标签赋值

          @GetMapping("/value")
          public ModelAndView value(){
            ModelAndView modelAndView =new ModelAndView();
            modelAndView.setViewName("test");
            modelAndView.addObject("list","sprngboot");
            return modelAndView;
          }

          html</p></li>
          </ul>
          ¨K78K

          ¨K131K


          • th:src

            用来引入静态资源相当于HTML的原生的img。scrip的src标签

            图片、css、js都必须放在resource下的static中

            @GetMapping("/src")
            public ModelAndView src(){
              ModelAndView modelAndView =new ModelAndView();
              modelAndView.setViewName("test");
              modelAndView.addObject("src","/1.jpg");
              return modelAndView;
            }
          <!--value-->
                  <input type="text" th:value="${list}">
          • th:href

            用来设置超链接的href

            @GetMapping("/href")
            public ModelAndView href(){
              ModelAndView modelAndView =new ModelAndView();
              modelAndView.setViewName("test");
              modelAndView.addObject("src","https://www.baidu.com");
              return modelAndView;
            }

            html</p></li>
            </ul>
            ¨K79K

            ¨K132K


            • th:selected标签

              给html设置选中的元素,条件成立选中,条件不成立不选中

            @GetMapping("/selected")
            public ModelAndView selected(){
                List<User> users = Arrays.asList(new User("张三",1),new User("李四",2),new User("王五",3));
                ModelAndView modelAndView =new ModelAndView();
                modelAndView.setViewName("test");
                modelAndView.addObject("list",users);
                modelAndView.addObject("name","李四");
                return modelAndView;
            }
            <!--selected-->
                    <select>
                        <option
                                th:each="user:${list}"
                                th:value="${user.id}"
                                th:text="${user.name}"
                                th:selected="${user.name==name}"
                        ></option>
                    </select>

            结合th:each来使用,首次遍历list的集合来动态的创建元素,更具每次遍历出的user、name于业务数据中的name是否相等来决定是否要选择。

            • th:attr

              给HTML的任意标签来赋值

              @GetMapping("/attr")
              public ModelAndView attr(){
                ModelAndView modelAndView =new ModelAndView();
                modelAndView.setViewName("test");
                modelAndView.addObject("attr","spring boot");
                return modelAndView;
              }

              html</p></li>
              </ul>
              ¨K80K

              ¨K133K


              Thymeleaf的对象

              Thymeleaf是直接支持访问Servlet web的原生资源,HttpServletRequest HttpServletResponse HttpSession ServletContext.

              #request:获取HttpServletRequest对象
              #response:获取HttpServletResponse 对象
              #session:获取HttpSession 对象
              #servletContext:获取ServletContext对象

              1.Handler

              @GetMapping("/servlet")
              public String servlet(HttpServletRequest request){
                  request.setAttribute("valye","request");
                  request.getSession().setAttribute("valye","request");
                  request.getServletContext().setAttribute("valye","request");
                  return "test";
              }
              <!--request-->
                      <p th:text="${#request.getAttribute('value')}"></p>
                      <p th:text="${#session.getAttribute('value')}"></p>
                      <p th:text="${#servletContext.getAttribute('value')}"></p>
                      <p th:text="${#reponse}"></p>

              Thymeleaf支持直接访问session,相对于

              ${#servletContext.getAttribute('value')}也可以简化为${value}

              Thymeleaf的内置对象

              • dates;日期格式化
              • calendars:日期操作
              • numbers:数字格式化
              • Strings:字符格式化
              • bools:boolean
              • arrays:数组内置对象
              • lists:list集合内置对象
              • sets:set集合内置对象
              • maps;map集合内置对象

                  @GetMapping("/uniltity")
                  public ModelAndView uniltity(){
                      ModelAndView modelAndView =new ModelAndView();
                      modelAndView.setViewName("test");
                      modelAndView.addObject("date",new Date());
                      Calendar calendar =Calendar.getInstance();
                      calendar.set(2020,1,1);
                      modelAndView.addObject("calendar",calendar);
                      modelAndView.addObject("number",0.06);
                      modelAndView.addObject("string","Springboot");
                      modelAndView.addObject("boolean",true);
                      modelAndView.addObject("array",Arrays.asList("张三","李四","王五"));
                      List<User> users = Arrays.asList(new User("张三",1),new User("李四",2),new User("王五",3));
                      modelAndView.addObject("list",users);
                      Set<User> set =new HashSet<>();
                      set.add(new User("张三",1));
                      set.add(new User("李四",2));
                      modelAndView.addObject("set",set);
                      Map<Integer,User> map=new HashMap<>();
                      map.put(1,new User("张三",1));
                      map.put(2,new User("李四",2));
                      modelAndView.addObject("map",map);
                      return modelAndView;
                  }
              date:格式化<span th:text="${#dates.format(date,'yyy-mm-dd')}"></span><br>
              当前时间:<span th:text="${#dates.cteateToday()}"></span><br>
              Calendar格式化:<span th:text="${#calendars.format(calendar,'yyyy-mm-dd')}"></span><br>
              number百分比格式化:<span th:text="${#numbers.formatPercent(number,2,2)}"></span><br>
              name是否为空:<span th:text="${#strings.isTmpty(string)}"></span><br>
              name的长度:<span th:text="${#strings.length(string)}"></span><br>
              name的拼接:<span th:text="${#strings.concat('Good',string)}"></span><br>
              boolen是否为true:<span th:text="${#bools.isTrue(boolean)}"></span><br>
              arrys的长度:<span th:text="${#arrays.length(array)}"></span><br>
              array是否包含张三:<span th:text="${#arrays.contains(array,'张三')}"></span><br>
              list是否为空:<span th:text="${#list.isEmpty(list)}"></span><br>
              list的长度:<span th:text="${#list.size(list)}"></span><br>
              Set是否为空:<span th:text="${#sets.isEmpty(set)}"></span><br>
              Set的长度:<span th:text="${#sets.size(set)}"></span><br>
              Map是否为空:<span th:text="${#maps.isEmpty(map)}"></span><br>
              Map是的长度:<span th:text="${#maps.size(map)}"></span><br>

              Spring boot 整合JDBC Template

              JDBC Template是spring自带的一个JDBC的模版组件,底层实现了对JDBC的封装,用法和Mybatis类似,需要开发者定义SQL语句,JDBC Template帮助我们完成数据库的连接,SQL的执行,结果集的封装

              不足之处灵活性不如Mybatis,因为Mybatis是直接卸载XML王文建中,更有利于扩展和维护,JDBC Template是以硬编码的形式将SQL直接写在java代码中,不利于扩展和维护

              1.pom.xml

              <?xml version="1.0" encoding="UTF-8"?>
              <project xmlns="http://maven.apache.org/POM/4.0.0"
                       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
                  <modelVersion>4.0.0</modelVersion>

                  <groupId>org.example</groupId>
                  <artifactId>soringbootdo</artifactId>
                  <version>1.0-SNAPSHOT</version>
                  <parent>
                      <artifactId>spring-boot-starter-web</artifactId>
                      <groupId>org.springframework.boot</groupId>
                      <version>2.2.4.RELEASE</version>
                  </parent>
                  <dependencies>
                      <dependency>
                          <groupId>org.springframework.boot</groupId>
                          <artifactId>spring-boot-starter-web</artifactId>
                      </dependency>
                      <dependency>
                          <groupId>org.springframework.boot</groupId>
                          <artifactId>spring-boot-starter-jdbc</artifactId>
                      </dependency>
                      <dependency>
                          <groupId>mysql</groupId>
                          <artifactId>mysql-connector-java</artifactId>
                      </dependency>
                      <dependency>
                          <groupId>org.projectlombok</groupId>
                          <artifactId>lombok</artifactId>
                      </dependency>
                  </dependencies>
              </project>

              2.实体类:

              package com.southwind.entity;

              import lombok.Data;

              @Data
              public class User {
                  private Integer id;
                  private  String name;
                  private  Integer money;
              }

              3.Repository

              接口:

              package com.southwind.Repository;

              import com.southwind.entity.User;

              import java.util.List;

              public interface UserRepository {
                  public List<User> findAll();
                  public  User finById(Integer id);
                  public int save (User user);
                  public  int update(User user);
                  public  int delete(Integer id);
              }
              package com.southwind.Repository.impl;

              import com.southwind.Repository.UserRepository;
              import com.southwind.entity.User;
              import org.springframework.beans.factory.annotation.Autowired;
              import org.springframework.jdbc.core.BeanPropertyRowMapper;
              import org.springframework.jdbc.core.JdbcTemplate;
              import org.springframework.stereotype.Repository;

              import java.util.List;
              @Repository
              public class UserRepositoryImpl implements UserRepository {
                  @Autowired
                  private JdbcTemplate jdbcTemplate;
                  public List<User> findAll() {
                      return jdbcTemplate.query(
                              "select * from people",
                              new BeanPropertyRowMapper<>(User.class)
                      );
                  }

                  public User finById(Integer id) {

                      return jdbcTemplate.queryForObject(
                              "select * from people where id=?",
                              new Object[]{id},
                              new BeanPropertyRowMapper<>(User.class)
                      );
                  }

                  public int save(User user) {

                      return jdbcTemplate.update(
                              "insert into people(id,name,money) values (?,?,?)",
                              user.getId(),
                              user.getName(),
                              user.getMoney()

                      );
                  }

                  public int update(User user) {

                      return jdbcTemplate.update(
                              "update people set name=?,money=? where  id=?",
                              user.getName(),
                              user.getMoney(),
                              user.getId()
                      );
                  }

                  public int delete(Integer id) {

                      return jdbcTemplate.update(
                              "delete from people where id=?",
                              id

                      );
                  }
              }

              4.Handeler

              package com.southwind.Controller;

              import com.southwind.Repository.UserRepository;
              import com.southwind.Repository.impl.UserRepositoryImpl;
              import com.southwind.entity.User;
              import org.springframework.beans.factory.annotation.Autowired;
              import org.springframework.stereotype.Controller;
              import org.springframework.web.bind.annotation.*;

              import java.util.List;

              @Controller
              @RequestMapping("/user")
              public class UserHandler {
                  @Autowired
                  private UserRepositoryImpl userRepository;
                  @GetMapping("/findall")
                  @ResponseBody
                  public List<User> findall(){
                      return userRepository.findAll();
                  }

                  @GetMapping("/findbyid/{id}")
                  @ResponseBody
                  public User findbyid(@PathVariable("id")Integer id) {
                      return userRepository.finById(id);
                  }

                  @PostMapping("/save")
                  @ResponseBody
                  public int save(@RequestBody User user){
                      return userRepository.save(user);
                  }
                  @PutMapping("/update")
                  @ResponseBody
                  public int update(@RequestBody User user){
                      return userRepository.update(user);
                  }
                  @DeleteMapping("/delete/{id}")
                  @ResponseBody
                  public int delete(@PathVariable Integer id){
                      return userRepository.delete(id);
                  }
              }

              方法

              query:

              public <T> List<T> query(String sql, RowMapper<T> rowMapper) throws DataAccessException {
                  return (List)result(this.query((String)sql, (ResultSetExtractor)(new RowMapperResultSetExtractor(rowMapper))));
              }

              RowMapper是一个接口,作用是分析结果集,将JDBC查询的ResultSet对象转化成对应的POJO

              queryForObjiect(String sql,Object[] args, RowMapper rowMapper)

              该方法查询一条数据,并将结果封装成一个POJO

              update

              public int update(String sql, @Nullable Object... args) throws DataAccessException {
                  return this.update(sql, this.newArgPreparedStatementSetter(args));
              }

              增加、修改、删除都可以用这个方法

              Springboot Mybatis

              <?xml version="1.0" encoding="UTF-8"?>
              <project xmlns="http://maven.apache.org/POM/4.0.0"
                       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
                  <modelVersion>4.0.0</modelVersion>

                  <groupId>org.example</groupId>
                  <artifactId>soringbootdo</artifactId>
                  <version>1.0-SNAPSHOT</version>
                  <parent>
                      <artifactId>spring-boot-starter-web</artifactId>
                      <groupId>org.springframework.boot</groupId>
                      <version>2.2.4.RELEASE</version>
                  </parent>
                  <dependencies>
                      <dependency>
                          <groupId>org.springframework.boot</groupId>
                          <artifactId>spring-boot-starter-web</artifactId>
                      </dependency>
                      <dependency>
                          <groupId>org.springframework.boot</groupId>
                          <artifactId>spring-boot-starter-jdbc</artifactId>
                      </dependency>
                      <dependency>
                          <groupId>mysql</groupId>
                          <artifactId>mysql-connector-java</artifactId>
                      </dependency>
                      <dependency>
                          <groupId>org.projectlombok</groupId>
                          <artifactId>lombok</artifactId>
                      </dependency>
              <!--        Mybatis-->
                      <dependency>
                          <groupId>org.mybatis</groupId>
                          <artifactId>mybatis-spring</artifactId>
                          <version>1.3.1</version>
                      </dependency>
                      <dependency>
                          <groupId>org.mybatis.spring.boot</groupId>
                          <artifactId>mybatis-spring-boot-starter</artifactId>
                          <version>1.3.1</version>
                      </dependency>
                  </dependencies>
              </project>

              2.实体类

              package com.southwind.entity;

              import lombok.Data;

              @Data
              public class User {
                  private Integer id;
                  private  String name;
                  private  Integer money;
              }

              3.创建Repository

              package com.southwind.mybatis.Repository;

              import com.southwind.entity.User;

              import java.util.List;

              public interface UserRepository {
                  public List<User> findAll();
                  public  User finById(Integer id);
                  public int save (User user);
                  public  int update(User user);
                  public  int delete(Integer id);
              }
              <?xml version="1.0" encoding="UTF-8"?>
              <!DOCTYPE mapper
                      PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                      "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
              <mapper namespace="com.southwind.mybatis.Repository.UserRepository">
                <select id="findAll" resultType="User">
                    select * from people
                </select>

                  <select id="finById" parameterType="java.lang.Integer" resultType="User">
                      select * from  people where id=#{id}
                  </select>

                  <insert id="save" parameterType="User">
                      insert  into people(id,name,money) values(#{id},#{name},#{money})
                  </insert>

                  <update id="update" parameterType="User">
                      update people set name=#{name},money=#{name} where id=#{id}
                  </update>

                  <delete id="delete" parameterType="java.lang.Integer">
                      delete from people where id=#{id}
                  </delete>
              </mapper>

              4.Hnadelri

              package com.southwind.Controller;

              import com.southwind.entity.User;
              import com.southwind.mybatis.Repository.UserRepository;
              import org.springframework.beans.factory.annotation.Autowired;
              import org.springframework.stereotype.Controller;
              import org.springframework.web.bind.annotation.*;

              import java.util.List;

              @Controller
              @RequestMapping("mbuser")
              public class MuserHandler {
                  @Autowired
                  private UserRepository userRepository;

                  @GetMapping("/findall")
                  @ResponseBody
                  public List<User> findall(){
                      return userRepository.findAll();
                  }

                  @GetMapping("/findbyid/{id}")
                  @ResponseBody
                  public User findbyid(@PathVariable("id")Integer id) {
                      return userRepository.finById(id);
                  }

                  @PostMapping("/save")
                  @ResponseBody
                  public int save(@RequestBody User user){
                      return userRepository.save(user);
                  }
                  @PutMapping("/update")
                  @ResponseBody
                  public int update(@RequestBody User user){
                      return userRepository.update(user);
                  }
                  @DeleteMapping("/delete/{id}")
                  @ResponseBody
                  public int delete(@PathVariable Integer id){
                      return userRepository.delete(id);
                  }
              }

              5.配置文件:

              spring:
                datasource:
                  url:  jdbc:mysql://localhost:3306/text?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
                  driver-class-name: com.mysql.cj.jdbc.Driver
                  username: root
                  password: 123456
              mybatis:
                mapper-locations: classpath:/mapping/*.xml
                type-aliases-package: com.southwind.entity

              6.启动类

              package com.southwind;

              import org.mybatis.spring.annotation.MapperScan;
              import org.springframework.boot.SpringApplication;
              import org.springframework.boot.autoconfigure.SpringBootApplication;

              @SpringBootApplication
              @MapperScan("com.southwind.mybatis.Repository")
              public class Application {
                  public static void main(String[] args) {
                      SpringApplication.run(Application.class,args);
                  }
              }

              Springboot 整合 Spring Data JPA

              Spring Data JPA是Spring Data大家族的一员

              JPA和Spring Data JPA的关系

              JPA(Java Persistence API)java持久层的约束,定义了一系列的ORM接口,他本身不能直接使用,接口的必须实现才能使用,Hibernate框架实现了JPA规范的框架

              Spring Data JPA是Spring框架提供的对JPA规范的抽象,通过约定的命名规范完成持久层接口的编写,在不需要实现接口的情况下,就可以完成对数据库的操作。

              简单理解,通过Spring Data JPA只需要定义接口而不需要实现,就能完成CRUD操作

              Spring Data JPA本身并不是一个具体的实现,他只是一个抽象层,底层还是需要Hibernate这样的JPA来提供支持。

              Spring Data JPA和Spring JDBC Template的关系

              JDBC Template是spring自带的一个JDBC的模版组件,底层实现了对JDBC的封装,用法和Mybatis类似,需要开发者定义SQL语句,JDBC Template帮助我们完成数据库的连接,SQL的执行,结果集的封装

              Spring Data JPA是JPA的抽象

              1.pom.xml

              <?xml version="1.0" encoding="UTF-8"?>
              <project xmlns="http://maven.apache.org/POM/4.0.0"
                       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
                  <modelVersion>4.0.0</modelVersion>

                  <groupId>org.example</groupId>
                  <artifactId>soringbootdo</artifactId>
                  <version>1.0-SNAPSHOT</version>
                  <parent>
                      <artifactId>spring-boot-starter-web</artifactId>
                      <groupId>org.springframework.boot</groupId>
                      <version>2.2.4.RELEASE</version>
                  </parent>
                  <dependencies>
              <!--        -->
                      <dependency>
                          <groupId>org.springframework.boot</groupId>
                          <artifactId>spring-boot-starter-web</artifactId>
                      </dependency>
                      <!--        springboot 集成jdbcTenplate-->
                      <dependency>
                          <groupId>org.springframework.boot</groupId>
                          <artifactId>spring-boot-starter-jdbc</artifactId>
                      </dependency>
                      <dependency>
                          <groupId>mysql</groupId>
                          <artifactId>mysql-connector-java</artifactId>
                      </dependency>
                      <dependency>
                          <groupId>org.projectlombok</groupId>
                          <artifactId>lombok</artifactId>
                      </dependency>
              <!--        springboot 集成Mybatis-->
                      <dependency>
                          <groupId>org.mybatis.spring.boot</groupId>
                          <artifactId>mybatis-spring-boot-starter</artifactId>
                          <version>1.3.1</version>
                      </dependency>
              <!--        springboot 集成JPA-->
                      <dependency>
                          <groupId>org.springframework.boot</groupId>
                          <artifactId>spring-boot-starter-data-jpa</artifactId>
                      </dependency>
                  </dependencies>
              </project>

              2.实体类:完成实体类于表的映射

              package com.southwind.entity;

              import lombok.Data;

              import javax.persistence.*;

              @Data
              @Entity(name = "people")
              public class User {
                  @Id
                  @GeneratedValue(strategy = GenerationType.IDENTITY)
                  private Integer id;
                  @Column
                  private  String name;
                  @Column
                  private  Integer money;
              }
              • @Entity将实体类与数据表进行映射
              • @Id将实体类中的成员变量于数据表的主键进行映射,一般是id
              • @GeneratedValue(strategy = GenerationType.IDENTITY)自动生成主键,strategy为主键选择的生成策略
              • @Column将实体类中的成员变量与数据表的普通字段进行映射

              3.创建Repository

              //
              // Source code recreated from a .class file by IntelliJ IDEA
              // (powered by Fernflower decompiler)
              //

              package org.springframework.data.jpa.repository;

              import java.util.List;
              import org.springframework.data.domain.Example;
              import org.springframework.data.domain.Sort;
              import org.springframework.data.repository.NoRepositoryBean;
              import org.springframework.data.repository.PagingAndSortingRepository;
              import org.springframework.data.repository.query.QueryByExampleExecutor;

              @NoRepositoryBean
              public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
                  List<T> findAll();

                  List<T> findAll(Sort var1);

                  List<T> findAllById(Iterable<ID> var1);

                  <S extends T> List<S> saveAll(Iterable<S> var1);

                  void flush();

                  <S extends T> S saveAndFlush(S var1);

                  void deleteInBatch(Iterable<T> var1);

                  void deleteAllInBatch();

                  T getOne(ID var1);

                  <S extends T> List<S> findAll(Example<S> var1);

                  <S extends T> List<S> findAll(Example<S> var1, Sort var2);
              }
              package com.southwind.mybatis.Repository;

              import com.southwind.entity.User;
              import org.springframework.data.jpa.repository.JpaRepository;

              public interface JpaUserRepository extends JpaRepository<User,Integer> {
              }

              4.创建Handler

              package com.southwind.Controller;

              import com.southwind.entity.User;
              import org.springframework.beans.factory.annotation.Autowired;
              import org.springframework.data.jpa.repository.JpaRepository;
              import org.springframework.web.bind.annotation.*;

              import java.util.List;

              @RestController("/jpaHandler")
              @RequestMapping("/JpaUser")
              public class JpaUserHandler {
                  @Autowired
                  private JpaRepository jpaRepository;
                  @GetMapping("/findall")
                  public List<User> findall(){
                      return jpaRepository.findAll();
                  }

                  @GetMapping("/findbyid/{id}")
                  @ResponseBody
                  public User findbyid(@PathVariable("id")Integer id) {
                      return (User) jpaRepository.findById(id).get();
                  }

                  @PostMapping("/save")
                  @ResponseBody
                  public void save(@RequestBody User user){
                       jpaRepository.save(user);
                  }
                  @PutMapping("/update")
                  @ResponseBody
                  public Object update(@RequestBody User user){
                      return jpaRepository.save(user);
                  }
                  @DeleteMapping("/delete/{id}")
                  @ResponseBody
                  public void delete(@PathVariable("id") Integer id){
                       jpaRepository.deleteById(id);
                  }
              }

              5.配置application.yml

              spring:
                datasource:
                  url:  jdbc:mysql://localhost:3306/text?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
                  driver-class-name: com.mysql.cj.jdbc.Driver
                  username: root
                  password: 123456
                jpa:
                  show-sql: true
                  properties:
                    hibernate:
                      format_sql: true
              mybatis:
                mapper-locations: classpath:/mapping/*.xml
                type-aliases-package: com.southwind.entity

              6.在继承员原来的基础上增加新的方法

              package com.southwind.jpa.Repository;

              import com.southwind.entity.User;
              import org.springframework.data.jpa.repository.JpaRepository;

              public interface JpaUserRepository extends JpaRepository<User,Integer> {
                  public User findByName(String name);
              }

              Spring Boot 整合Spring Seccurity

              1.创建maven工程

              <?xml version="1.0" encoding="UTF-8"?>
              <project xmlns="http://maven.apache.org/POM/4.0.0"
                       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
                  <modelVersion>4.0.0</modelVersion>

                  <groupId>org.example</groupId>
                  <artifactId>springsecurity</artifactId>
                  <version>1.0-SNAPSHOT</version>
                  <parent>
                      <artifactId>spring-boot-starter-web</artifactId>
                      <groupId>org.springframework.boot</groupId>
                      <version>2.2.4.RELEASE</version>
                  </parent>
                  <dependencies>
                      <dependency>
                          <groupId>org.springframework.boot</groupId>
                          <artifactId>spring-boot-starter-web</artifactId>
                      </dependency>
                      <dependency>
                          <groupId>org.springframework.boot</groupId>
                          <artifactId>spring-boot-starter-thymeleaf</artifactId>
                      </dependency>
                      <dependency>
                          <groupId>org.springframework.boot</groupId>
                          <artifactId>spring-boot-starter-security</artifactId>
                      </dependency>
                  </dependencies>
              </project>

              权限管理的开发

              权限付给角色,角色付给用户

              2.Handler

              package com.southwind.controller;

              import org.springframework.stereotype.Controller;
              import org.springframework.web.bind.annotation.GetMapping;

              @Controller
              public class SecurtyHandler {
                  @GetMapping("/index")
                  public String index(){
                      return "index";
                  }
              }

              3.HTML

              <!DOCTYPE html>
              <html lang="en">
              <head>
                  <meta charset="UTF-8">
                  <title>Title</title>
              </head>
              <body>
                  <p>idnex</p>
                  <form method="post" action="/login">
                      <input type="submit" value="退出">
                  </form>
              </body>
              </html>

              4.配置文件

              spring:
                thymeleaf:
                  suffix: .html
                  prefix: classpath:/templates/

              5.启动类

              package com;

              import org.springframework.boot.SpringApplication;
              import org.springframework.boot.autoconfigure.SpringBootApplication;
              import org.springframework.context.annotation.ComponentScan;

              @SpringBootApplication
              public class Application {
                  public static void main(String[] args) {
                      SpringApplication.run(Application.class,args);
                  }
              }

              用户名默认user

              密码:默认随机

              自定义:

              spring:
                thymeleaf:
                  suffix: .html
                  prefix: classpath:/templates/
                security:
                  user:
                    name: admin
                    password: 123456

              权限管理

              定义两个资源:

              • index.html

                package com.southwind.Config;

                import org.springframework.context.annotation.Configuration;
                import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
                import org.springframework.security.config.annotation.web.builders.HttpSecurity;
                import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
                @Configuration
                public class SecurityConfig extends WebSecurityConfigurerAdapter {
                  /**
                   * 角色和资源
                   * @param http
                   * @throws Exception
                   */
                  @Override
                  protected void configure(HttpSecurity http) throws Exception {
                      http.authorizeRequests()
                              .antMatchers("/admin").hasRole("ADMIN")
                              .antMatchers("/index").access("hasRole('ADMIN') or hasRole('USER')")
                              .anyRequest().authenticated()
                              .and()
                              .formLogin()
                              .loginPage("/login")
                              .permitAll()
                              .and()
                              .logout()
                              .permitAll()
                              .and()
                              .csrf()
                              .disable();
                  }

                  /**
                   * 用户和角色
                   * @param auth
                   * @throws Exception
                   */
                  @Override
                  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
                     auth.inMemoryAuthentication().passwordEncoder(new MypasswordEncoder())
                             .withUser("user").password(new MypasswordEncoder()
                             .encode("000")).roles("USER")
                             .and()
                             .withUser("admin").password(new MypasswordEncoder()
                             .encode("123")).roles("ADMIN","uSER");
                  }
                }
              • admin.html

              定义两个角色:

              • ADMIN访问index.html
              • USER访问index.html

              1.创建SecurityConfig

              2.自定义MypasswordEncoder类

              package com.southwind.Config;

              import org.springframework.security.crypto.password.PasswordEncoder;

              public class MypasswordEncoder implements PasswordEncoder {

                  @Override
                  public String encode(CharSequence charSequence) {
                      return charSequence.toString();
                  }

                  @Override
                  public boolean matches(CharSequence charSequence, String s) {
                      return s.equals((charSequence.toString()));
                  }
              }

              3.

              package com.southwind.Config;

              import org.springframework.context.annotation.Configuration;
              import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
              import org.springframework.security.config.annotation.web.builders.HttpSecurity;
              import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
              @Configuration
              public class SecurityConfig extends WebSecurityConfigurerAdapter {
                  /**
                   * 角色和资源
                   * @param http
                   * @throws Exception
                   */
                  @Override
                  protected void configure(HttpSecurity http) throws Exception {
                      http.authorizeRequests()
                              .antMatchers("/admin").hasRole("ADMIN")
                              .antMatchers("/index").access("hasRole('ADMIN') or hasRole('USER')")
                              .anyRequest().authenticated()
                              .and()
                              .formLogin()
                              .loginPage("/login")
                              .permitAll()
                              .and()
                              .logout()
                              .permitAll()
                              .and()
                              .csrf()
                              .disable();
                  }

                  /**
                   * 用户和角色
                   * @param auth
                   * @throws Exception
                   */
                  @Override
                  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
                     auth.inMemoryAuthentication().passwordEncoder(new MypasswordEncoder())
                             .withUser("user").password(new MypasswordEncoder()
                             .encode("000")).roles("USER")
                             .and()
                             .withUser("admin").password(new MypasswordEncoder()
                             .encode("123")).roles("ADMIN","uSER");
                  }
              }

              4.Handler

              package com.southwind.controller;

              import org.springframework.stereotype.Controller;
              import org.springframework.web.bind.annotation.GetMapping;

              @Controller
              public class SecurtyHandler {
                  @GetMapping("/index")
                  public String index(){
                      return "index";
                  }
                  @GetMapping("/admin")
                  public String admin(){
                      return "adimin";
                  }
                  @GetMapping("/login")
                  public String login(){
                      return "login";
                  }
              }

              5.HTML

              <!DOCTYPE html>
              <html lang="en">
              <head>
                  <meta charset="UTF-8">
                  <title>Title</title>
              </head>
              <body>
                  <p>后台管理系统</p>
                  <form method="post" action="/logout">
                      <input type="submit" value="退出">
                  </form>
              </body>
              </html>
              <!DOCTYPE html>
              <html lang="en">
              <head>
                  <meta charset="UTF-8">
                  <title>Title</title>
              </head>
              <body>
                  <p>欢迎回来</p>
                  <form method="post" action="/logout">
                      <input type="submit" value="退出">
                  </form>
              </body>
              </html>
              <!DOCTYPE html>
              <html lang="en">
              <html xmlns:th="http://www.thymeleaf.org">
              <head>
                  <meta charset="UTF-8">
                  <title>Title</title>
              </head>
              <body>
                  <p th:if="%{param.error}">
                      用户名或密码错误
                  </p>
                  <form th:action="@{/login}" method="post">
                     用户名:<input type="text" name="username"><br>
                      密码:<input type="password" name="password"><br>
                      <input type="submit" value="登录">
                  </form>
              </body>
              </html>

最新文章

  1. [转]ORACLE中Like与Instr模糊查询性能大比拼
  2. React 学习,需要注意几点
  3. 封装tip控件
  4. vim linux SecureCRT vim颜色的设置
  5. Microsoft.DirectX.DirectSound.dll和Microsoft.DirectX.dll引用,导致项目无法调试问题
  6. Eclipse用Tomcat插件部署Java Web项目
  7. GPUImage的简单使用
  8. JS+CSS+HTML简单计算器
  9. java基础阅读卷1整理(待更新)
  10. mySql一个字段的值模糊匹配多表多列的查询
  11. idea的spring boot项目,运行时不要显示在dashboard中
  12. WPF中textBlock 变色功能
  13. 简单读!Mybatis源码(一)一条select的一生
  14. .NET Core 配置GC工作模式与内存的影响
  15. 在高并发情况nginx的作用
  16. luogu1975 [国家集训队]排队
  17. 场景调研 persona
  18. 在正文部分操作accordion内容展开和闭合
  19. java android 读写西门子PLC数据,包含S7协议和Fetch/Write协议,s7支持200smart,300PLC,1200PLC,1500PLC
  20. 【转】IDEA中xml文件头报错:URI is not registered (Settings | Languages &amp; Frameworks | Schemas and DTDs)

热门文章

  1. 【深入浅出 Yarn 架构与实现】4-1 ResourceManager 功能概述
  2. C温故补缺(十三):可变参数
  3. 树莓派蓝牙rfcomm协议通信
  4. day09 常用工具类&amp;包装类&amp;集合——List、Set
  5. 基于jenkins+kubernetes的cicd流程实践一:环境搭建及方案原理实现
  6. Windows10下python3和python2同时安装(一)安装python3和python2
  7. 使用JavaScript制作一个页面的电子时钟
  8. .netcore项目docker化,以及docker之间通信
  9. [python]《Python编程快速上手:让繁琐工作自动化》学习笔记2
  10. [OpenCV实战]5 基于深度学习的文本检测