Spring Boot 是一个快速开发框架,可以迅速搭建出一套基于 Spring 框架体系的应用,是 Spring Cloud 的基础。
Spring Boot 开启了各种自动装配,从而简化代码的开发,不需要编写各种配置文件,只需要引入相关依赖就可以迅速搭建一个应用。
1、不需要 web.xml
2、不需要 springmvc.xml
3、不需要 tomcat,Spring Boot 内嵌了 tomcat
4、不需要配置 JSON 解析,支持 REST 架构
5、个性化配置非常简单
1、创建 Maven 工程,导入相关依赖。
xxxxxxxxxx<!-- 继承父包 --><parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.7.RELEASE</version></parent><dependencies> <!-- web启动jar --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.6</version> <scope>provided</scope> </dependency></dependencies>2、创建 Student 实体类
xxxxxxxxxxpackage com.southwind.entity;import lombok.Data;public class Student { private long id; private String name; private int age;}3、StudentRepository
xxxxxxxxxxpackage com.southwind.repository;import com.southwind.entity.Student;import java.util.Collection;public interface StudentRepository { public Collection<Student> findAll(); public Student findById(long id); public void saveOrUpdate(Student student); public void deleteById(long id);}4、StudentRepositoryImpl
xxxxxxxxxxpackage com.southwind.repository.impl;import com.southwind.entity.Student;import com.southwind.repository.StudentRepository;import org.springframework.stereotype.Repository;import java.util.Collection;import java.util.HashMap;import java.util.Map;public class StudentRepositoryImpl implements StudentRepository { private static Map<Long,Student> studentMap; static{ studentMap = new HashMap<>(); studentMap.put(1L,new Student(1L,"张三",22)); studentMap.put(2L,new Student(2L,"李四",23)); studentMap.put(3L,new Student(3L,"王五",24)); } public Collection<Student> findAll() { return studentMap.values(); } public Student findById(long id) { return studentMap.get(id); } public void saveOrUpdate(Student student) { studentMap.put(student.getId(),student); } public void deleteById(long id) { studentMap.remove(id); }}5、StudentHandler
xxxxxxxxxxpackage com.southwind.controller;import com.southwind.entity.Student;import com.southwind.repository.StudentRepository;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;import java.util.Collection;("/student")public class StudentHandler { private StudentRepository studentRepository; ("/findAll") public Collection<Student> findAll(){ return studentRepository.findAll(); } ("/findById/{id}") public Student findById(("id") long id){ return studentRepository.findById(id); } ("/save") public void save( Student student){ studentRepository.saveOrUpdate(student); } ("/update") public void update( Student student){ studentRepository.saveOrUpdate(student); } ("/deleteById/{id}") public void deleteById(("id") long id){ studentRepository.deleteById(id); }}6、application.yml
xxxxxxxxxxserver port90907、启动类
xxxxxxxxxxpackage com.southwind;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;public class Application { public static void main(String[] args) { SpringApplication.run(Application.class,args); }}@SpringBootApplication 表示当前类是 Spring Boot 的入口,Application 类的存放位置必须是其他相关业务类的存放位置的父级。
xxxxxxxxxx<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.7.RELEASE</version></parent><dependencies> <!-- web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 整合JSP --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> </dependency> <!-- JSTL --> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.6</version> <scope>provided</scope> </dependency></dependencies>xxxxxxxxxxserver port8181spring mvc view prefix/ suffix.jspxxxxxxxxxxpackage com.southwind.controller;import com.southwind.entity.Student;import com.southwind.repository.StudentRepository;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;("/hello")public class HelloHandler { private StudentRepository studentRepository; ("/index") public ModelAndView index(){ ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("index"); modelAndView.addObject("list",studentRepository.findAll()); return modelAndView; } ("/deleteById/{id}") public String deleteById(("id") long id){ studentRepository.deleteById(id); return "redirect:/hello/index"; } ("/save") public String save(Student student){ studentRepository.saveOrUpdate(student); return "redirect:/hello/index"; } ("/update") public String update(Student student){ studentRepository.saveOrUpdate(student); return "redirect:/hello/index"; } ("/findById/{id}") public ModelAndView findById(("id") long id){ ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("update"); modelAndView.addObject("student",studentRepository.findById(id)); return modelAndView; }}xxxxxxxxxx<%-- Created by IntelliJ IDEA. User: southwind Date: 2019-03-21 Time: 12:02 To change this template use File | Settings | File Templates.--%><% page contentType="text/html;charset=UTF-8" language="java" %><% page isELIgnored="false" %><% taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><html><head> <title>Title</title></head><body> <h1>学生信息</h1> <table> <tr> <th>学生编号</th> <th>学生姓名</th> <th>学生年龄</th> <th>操作</th> </tr> <c:forEach items="${list}" var="student"> <tr> <td>${student.id}</td> <td>${student.name}</td> <td>${student.age}</td> <td> <a href="/hello/findById/${student.id}">修改</a> <a href="/hello/deleteById/${student.id}">删除</a> </td> </tr> </c:forEach> </table> <a href="/save.jsp">添加学生</a></body></html>
xxxxxxxxxx<%-- Created by IntelliJ IDEA. User: southwind Date: 2019-03-21 Time: 12:09 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="/hello/save" method="post"> ID:<input type="text" name="id"/><br/> name:<input type="text" name="name"/><br/> age:<input type="text" name="age"/><br/> <input type="submit" value="提交"/> </form></body></html>
xxxxxxxxxx<%-- Created by IntelliJ IDEA. User: southwind Date: 2019-03-21 Time: 12:09 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="/hello/update" method="post"> ID:<input type="text" name="id" value="${student.id}" readonly/><br/> name:<input type="text" name="name" value="${student.name}"/><br/> age:<input type="text" name="age" value="${student.age}"/><br/> <input type="submit" value="提交"/> </form></body></html>Spring Boot 可以结合 Thymeleaf 模版来整合 HTML,使用原生的 HTML 作为视图。
Thymeleaf 模版是面向 Web 和独立环境的 Java 模版引擎,能够处理 HTML、XML、JavaScript、CSS 等。
xxxxxxxxxx<p th:text="${message}"></p>
xxxxxxxxxx<!-- 继承父包 --><parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.7.RELEASE</version></parent><dependencies> <!-- web启动jar --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.6</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency></dependencies>xxxxxxxxxxserver port9090spring thymeleaf prefixclasspath/templates/ suffix.html modeHTML5 encodingUTF-8xxxxxxxxxxpackage com.southwind.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;("/index")public class IndexHandler { ("/index") public String index(){ System.out.println("index..."); return "index"; }}xxxxxxxxxx<html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body> <h1>Hello World</h1></body></html>如果希望客户端可以直接访问 HTML 资源,将这些资源放置在 static 路径下即可,否则必须通过 Handler 的后台映射才可以访问静态资源。
xxxxxxxxxx("/index2")public String index2(Map<String,String> map){ map.put("name","张三"); return "index";}xxxxxxxxxx<p th:text="${name}"></p><p th:text="'学生姓名是'+${name}+2"></p><p th:text="|学生姓名是,${name}|"></p>th:if 表示条件成立时显示内容,th:unless 表示条件不成立时显示内容
xxxxxxxxxx("/if")public String index3(Map<String,Boolean> map){ map.put("flag",true); return "index";}xxxxxxxxxx<p th:if="${flag == true}" th:text="if判断成立"></p><p th:unless="${flag != true}" th:text="unless判断成立"></p>xxxxxxxxxx("/index")public String index(Model model){ System.out.println("index..."); List<Student> list = new ArrayList<>(); list.add(new Student(1L,"张三",22)); list.add(new Student(2L,"李四",23)); list.add(new Student(3L,"王五",24)); model.addAttribute("list",list); return "index";}xxxxxxxxxx<table> <tr> <th>index</th> <th>count</th> <th>学生ID</th> <th>学生姓名</th> <th>学生年龄</th> </tr> <tr th:each="student,stat:${list}" th:style="'background-color:'+@{${stat.odd}?'#F2F2F2'}"> <td th:text="${stat.index}"></td> <td th:text="${stat.count}"></td> <td th:text="${student.id}"></td> <td th:text="${student.name}"></td> <td th:text="${student.age}"></td> </tr></table>stat 是状态变量,属性:
Thymeleaf 对于 URL 的处理是通过 @{...} 进行处理,结合 th:href 、th:src
xxxxxxxxxx<h1>Hello World</h1><a th:href="@{http://www.baidu.com}">跳转</a><a th:href="@{http://localhost:9090/index/url/{na}(na=${name})}">跳转2</a><img th:src="${src}"><div th:style="'background:url('+ @{${src}} +');'"><br/><br/><br/></div>xxxxxxxxxx("/eq")public String eq(Model model){ model.addAttribute("age",30); return "test";}xxxxxxxxxx<input th:value="${age gt 30?'中年':'青年'}"/>
xxxxxxxxxx("/switch")public String switchTest(Model model){ model.addAttribute("gender","女"); return "test";}xxxxxxxxxx<div th:switch="${gender}"> <p th:case="女">女</p> <p th:case="男">男</p> <p th:case="*">未知</p></div>
基本对象
#ctx :上下文对象#vars:上下文变量#locale:区域对象#request:HttpServletRequest 对象#response:HttpServletResponse 对象#session:HttpSession 对象#servletContext:ServletContext 对象xxxxxxxxxx("/object")public String object(HttpServletRequest request){ request.setAttribute("request","request对象"); request.getSession().setAttribute("session","session对象"); return "test";}xxxxxxxxxx<p th:text="${#request.getAttribute('request')}"></p><p th:text="${#session.getAttribute('session')}"></p><p th:text="${#locale.country}"></p>
可以直接通过 # 访问。
1、dates:java.util.Date 的功能方法
2、calendars:java.util.Calendar 的功能方法
3、numbers:格式化数字
4、strings:java.lang.String 的功能方法
5、objects:Object 的功能方法
6、bools:对布尔求值的方法
7、arrays:操作数组的功能方法
8、lists:操作集合的功能方法
9、sets:操作集合的功能方法
10、maps:操作集合的功能方法
xxxxxxxxxx("/util")public String util(Model model){ model.addAttribute("name","zhangsan"); model.addAttribute("users",new ArrayList<>()); model.addAttribute("count",22); model.addAttribute("date",new Date()); return "test";}xxxxxxxxxx<!-- 格式化时间 --><p th:text="${#dates.format(date,'yyyy-MM-dd HH:mm:sss')}"></p><!-- 创建当前时间,精确到天 --><p th:text="${#dates.createToday()}"></p><!-- 创建当前时间,精确到秒 --><p th:text="${#dates.createNow()}"></p><!-- 判断是否为空 --><p th:text="${#strings.isEmpty(name)}"></p><!-- 判断List是否为空 --><p th:text="${#lists.isEmpty(users)}"></p><!-- 输出字符串长度 --><p th:text="${#strings.length(name)}"></p><!-- 拼接字符串 --><p th:text="${#strings.concat(name,name,name)}"></p><!-- 创建自定义字符串 --><p th:text="${#strings.randomAlphanumeric(count)}"></p>
xxxxxxxxxxpackage com.southwind.entity;import lombok.Data;import org.hibernate.validator.constraints.Length;import javax.validation.constraints.Min;import javax.validation.constraints.NotEmpty;import javax.validation.constraints.NotNull;public class User { (message = "id不能为空") private Long id; (message = "姓名不能为空") (min = 2,message = "姓名长度不能小于2位") private String name; (value = 16,message = "年龄必须大于16岁") private int age;}xxxxxxxxxx("/validator")public void validatorUser( User user,BindingResult bindingResult){ System.out.println(user); if(bindingResult.hasErrors()){ List<ObjectError> list = bindingResult.getAllErrors(); for(ObjectError objectError:list){ System.out.println(objectError.getCode()+"-"+objectError.getDefaultMessage()); } }}
xxxxxxxxxx<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.11</version></dependency>xxxxxxxxxxserver port9090spring thymeleaf prefixclasspath/templates/ suffix.html modeHTML5 encodingUTF-8 datasource urljdbcmysql//localhost3306/test?useUnicode=true&characterEncoding=UTF-8 usernameroot passwordroot driver-class-namecom.mysql.cj.jdbc.Driverxxxxxxxxxxpackage com.southwind.entity;import lombok.Data;import org.hibernate.validator.constraints.Length;import javax.validation.constraints.Min;import javax.validation.constraints.NotEmpty;import javax.validation.constraints.NotNull;public class User { (message = "id不能为空") private Long id; (message = "姓名不能为空") (min = 2,message = "姓名长度不能小于2位") private String name; (value = 60,message = "成绩必须大于60分") private double score;}xxxxxxxxxxpackage com.southwind.repository;import com.southwind.entity.User;import java.util.List;public interface UserRepository { public List<User> findAll(); public User findById(long id); public void save(User user); public void update(User user); public void deleteById(long id);}xxxxxxxxxxpackage com.southwind.repository.impl;import com.southwind.entity.User;import com.southwind.repository.UserRepository;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;public class UserRepositoryImpl implements UserRepository { private JdbcTemplate jdbcTemplate; public List<User> findAll() { return jdbcTemplate.query("select * from user",new BeanPropertyRowMapper<>(User.class)); } public User findById(long id) { return jdbcTemplate.queryForObject("select * from user where id = ?",new Object[]{id},new BeanPropertyRowMapper<>(User.class)); } public void save(User user) { jdbcTemplate.update("insert into user(name,score) values(?,?)",user.getName(),user.getScore()); } public void update(User user) { jdbcTemplate.update("update user set name = ?,score = ? where id = ?",user.getName(),user.getScore(),user.getId()); } public void deleteById(long id) { jdbcTemplate.update("delete from user where id = ?",id); }}xxxxxxxxxxpackage com.southwind.controller;import com.southwind.entity.User;import com.southwind.repository.UserRepository;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;import java.util.List;("/user")public class UserHandler { private UserRepository userRepository; ("/findAll") public List<User> findAll(){ return userRepository.findAll(); } ("/findById/{id}") public User findById(("id") long id){ return userRepository.findById(id); } ("/save") public void save( User user){ userRepository.save(user); } ("/update") public void update( User user){ userRepository.update(user); } ("/deleteById/{id}") public void deleteById(("id") long id){ userRepository.deleteById(id); }}
xxxxxxxxxx<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.1</version></dependency>xxxxxxxxxxserver port9090spring thymeleaf prefixclasspath/templates/ suffix.html modeHTML5 encodingUTF-8 datasource urljdbcmysql//localhost3306/test?useUnicode=true&characterEncoding=UTF-8 usernameroot passwordroot driver-class-namecom.mysql.cj.jdbc.Drivermybatis mapper-locationsclasspath/mapping/*.xml type-aliases-packagecom.southwind.entityxxxxxxxxxxpackage com.southwind.mapper;import com.southwind.entity.User;import java.util.List;public interface UserRepository { public List<User> findAll(int index,int limit); public User findById(long id); public void save(User user); public void update(User user); public void deleteById(long id); public int count();}xxxxxxxxxx <mapper namespace="com.southwind.mapper.UserRepository"> <select id="findAll" resultType="User"> select * from user limit #{param1},#{param2} </select> <select id="count" resultType="int"> select count(id) from user </select> <select id="findById" parameterType="long" resultType="User"> select * from user where id = #{id} </select> <insert id="save" parameterType="User"> insert into user(name,score) values(#{name},#{score}) </insert> <update id="update" parameterType="User"> update user set name = #{name},score = #{score} where id = #{id} </update> <delete id="deleteById" parameterType="long"> delete from user where id = #{id} </delete></mapper>xxxxxxxxxxpackage com.southwind.entity;import lombok.Data;import org.hibernate.validator.constraints.Length;import javax.validation.constraints.Min;import javax.validation.constraints.NotEmpty;import javax.validation.constraints.NotNull;public class User { (message = "id不能为空") private Long id; (message = "姓名不能为空") (min = 2,message = "姓名长度不能小于2位") private String name; (value = 60,message = "成绩必须大于60分") private double score;}xxxxxxxxxxpackage com.southwind.controller;import com.southwind.entity.User;import com.southwind.mapper.UserRepository;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.*;import org.springframework.web.servlet.ModelAndView;("/mapper")public class UserMapperHandler { private UserRepository userRepository; private int limit = 10; ("/findAll/{page}") public ModelAndView findAll(("page") int page){ ModelAndView modelAndView = new ModelAndView(); int index = (page-1)*limit; modelAndView.setViewName("show"); modelAndView.addObject("list",userRepository.findAll(index,limit)); modelAndView.addObject("page",page); //计算总页数 int count = userRepository.count(); int pages = 0; if(count%limit == 0){ pages = count/limit; }else{ pages = count/limit+1; } modelAndView.addObject("pages",pages); return modelAndView; } ("/deleteById/{id}") public String deleteById(("id") long id){ userRepository.deleteById(id); return "redirect:/mapper/findAll/1"; } ("/findById") public ModelAndView findById(("id") long id){ ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("user",userRepository.findById(id)); modelAndView.setViewName("update"); return modelAndView; } ("/update") public String update(User user){ userRepository.update(user); return "redirect:/mapper/findAll/1"; } ("/save") public String save(User user){ userRepository.save(user); return "redirect:/mapper/findAll/1"; } ("/redirect/{name}") public String redirect(("name") String name){ return name; }}xxxxxxxxxx<html xmlns:th="http://www.thymeleaf.org"><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body> <form action="/mapper/save" method="post"> 用户姓名:<input type="text" name="name" /><br/> 用户成绩:<input type="text" name="score" /><br/> <input type="submit" value="提交"/> </form></body></html>
xxxxxxxxxx<html xmlns:th="http://www.thymeleaf.org"><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body> <form action="/mapper/update" method="post"> 用户ID:<input type="text" name="id" th:value="${user.id}" readonly/><br/> 用户姓名:<input type="text" name="name" th:value="${user.name}" /><br/> 用户成绩:<input type="text" name="score" th:value="${user.score}" /><br/> <input type="submit" value="提交"/> </form></body></html>
xxxxxxxxxx<html xmlns:th="http://www.thymeleaf.org"><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title> <script type="text/javascript" th:src="@{/jquery-3.3.1.min.js}"></script> <script type="text/javascript"> $(function(){ $("#first").click(function(){ var page = $("#page").text(); page = parseInt(page); if(page == 1){ return false; } window.location.href="/mapper/findAll/1"; }); $("#previous").click(function(){ var page = $("#page").text(); page = parseInt(page); if(page == 1){ return false; } page = page-1; window.location.href="/mapper/findAll/"+page; }); $("#next").click(function(){ var page = $("#page").text(); var pages = $("#pages").text(); if(page == pages){ return false; } page = parseInt(page); page = page+1; window.location.href="/mapper/findAll/"+page; }); $("#last").click(function(){ var page = $("#page").text(); var pages = $("#pages").text(); if(page == pages){ return false; } window.location.href="/mapper/findAll/"+pages; }); }); </script></head><body> <h1>用户信息</h1> <table> <tr> <th>用户ID</th> <th>用户名</th> <th>成绩</th> <th>操作</th> </tr> <tr th:each="user:${list}"> <td th:text="${user.id}"></td> <td th:text="${user.name}"></td> <td th:text="${user.score}"></td> <td> <a th:href="@{/mapper/deleteById/{id}(id=${user.id})}">删除</a> <a th:href="@{/mapper/findById(id=${user.id})}">修改</a> </td> </tr> </table> <a id="first" href="javascript:void(0)">首页</a> <a id="previous" href="javascript:void(0)">上一页</a> <span id="page" th:text="${page}"></span>/<span id="pages" th:text="${pages}"></span> <a id="next" href="javascript:void(0)">下一页</a> <a id="last" href="javascript:void(0)">尾页</a><br/> <a href="/mapper/redirect/save">添加用户</a></body></html>