SpringBoot

1.Demo

(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>com.mxj</groupId>
    <artifactId>08-spring-boot-view-jsp</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.21.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!--springBoot启动器-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--jstl-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>

        <!--jasper-->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomact-embed-jasper</artifactId>
            <scope>provided</scope>
        </dependency>

    </dependencies>

</project>

(2)配置Controller

@Controller
public class Helloworld {
    @RequestMapping("/hello")
    @ResponseBody
    public Map<String,Object> showHelloWorld(){
        Map<String,Object> map = new HashMap<>();
        map.put("msg","HelloWorld");
        return map;
    }
}

(3)编写启动器

注意:启动器存放的位置可以和Controller位于同一个包下,或者位于Controller的上一级包中,但是不能放在Controller的平级以及子包下

/**
 * SpringBoot 启动类
 */
@SpringBootApplication
public class App {

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

 2.SpringBoot整合Servlet

(1)通过注解扫描完成Servlet组件的注册

编写Servlet

@WebServlet(name="FirstServlet",urlPatterns="/first")
public class FirstServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }
}

编写启动类

@SpringBootApplication
@ServletComponentScan   //在springBoot启动时会扫描@WebServlet,并将该类实例化
public class App {
    public static void main(String[] args){
        SpringApplication.run(App.class,args);
    }
}

(2)通过方法完成Servlet组件的注册

编写Servlet

public class SecondServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("SecondServlet..............");
    }
}

编写启动类

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

    @Bean
    public ServletRegistrationBean getServletRegistrationBean(){
        ServletRegistrationBean bean = new ServletRegistrationBean(new SecondServlet());
        bean.addUrlMappings("/second");
        return bean;
    }
}

 3. SpringBoot整合Filter

(1)通过注解扫描完成Filter组件的注册

编写Filter

//@WebFilter(filterName = "FirstFilter",urlPatterns = {"*.do","*.jsp"})
@WebFilter(filterName="FirstFilter",urlPatterns={"/first"})
public class FirstFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("进入Filter");
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("离开Filter");
    }
    @Override
    public void destroy() {

    }
}

编写启动类

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

(2)通过方法完成Filter组件的注册

编写Filter

public class SecondFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("进入SecondFilter");
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("离开SecondFilter");
    }
    @Override
    public void destroy() {

    }
}

编写启动类

@SpringBootApplication
public class App2 {

    public static void main(String[] args){
        SpringApplication.run(App2.class,args);
    }
    /**
     * 注册Servlet
     */
    @Bean
    public ServletRegistrationBean getervletRegistrationBean(){
        ServletRegistrationBean bean = new ServletRegistrationBean(new SecondServlet());
        bean.addUrlMappings("/second");
        return bean;
    }
    /**
     * 注册Filter
     */
    @Bean
    public FilterRegistrationBean getFilterRegistrationBean(){
        FilterRegistrationBean bean = new FilterRegistrationBean(new SecondFilter());
        //bean.addUrlPatterns(new String[]{"*.do","*.jsp"});
        bean.addUrlPatterns("/second");
        return bean;
    }
}

 4.SpringBoot整合Listener

(1)通过注解扫描完成Listener组件注册

编写Listener

@WebListener
public class FirstListener implements ServletContextListener {
    public void contextInitialized(ServletContextEvent sce) {

    }
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("Listener......init......");
    }
}

编写启动类

@SpringBootApplication
@ServletComponentScan
public class App {

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

(2)通过方法完成Listener组件注册

编写Listener

public class SecondListener implements ServletContextListener {
    public void contextInitialized(ServletContextEvent sce) {

    }
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("SecondListener......init......");
    }
}

编写启动类

@SpringBootApplication
public class App2 {

    public static void main(String[] args){

        SpringApplication.run(App2.class,args);
    }
    /**
     * 注册listener
     */
    public ServletListenerRegistrationBean<SecondListener> getServletListenerRegistrationBean(){
        ServletListenerRegistrationBean<SecondListener> bean= new ServletListenerRegistrationBean<SecondListener>(new SecondListener());
        return bean;
    }
}

 5.SpringBoot访问静态资源

(1)classpath/static目录

(2)ServletContext根目录(src/main/webapp)

6.SpringBoot文件上传

前端

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件上传</title>
</head>
<body>
    <from action="fileUploadController" method="post" enctype="multipart/form-data">
        上传文件:<input type="file" name="filename"/><br/>
        <input type="submit" value="提交"/>
    </from>
</body>
</html>

编写Controller

@RestController //表示该类下的方法的返回值会自动做json格式的转换
public class FileUploadcontroller {

    /**
     * 处理文件上传
     */
    @RequestMapping("/fileUploadController")
    public Map<String,Object> fileUpload(MultipartFile filename) throws IOException {
        System.out.println(filename.getOriginalFilename());
        filename.transferTo(new File("d:/"+filename.getOriginalFilename()));
        Map<String,Object> map = new HashMap<>();
        map.put("msg","ok");
        return map;
    }
}

编写启动类

@SpringBootApplication
public class App {

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

设置上传文件的默认值,main/resources/application.properties

spring.http.multipart.max-file-size=200MB  //设置单个上传文件的大小
spring.http.multipart.max-request-size=200MB  //设置一次请求上传文件的总容量

 7.SpringBoot整合jsp技术

(1)创建工程

(2)修改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>com.mxj</groupId>
    <artifactId>08-spring-boot-view-jsp</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.21.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!--springBoot启动器-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <!--jstl-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>

        <!--jasper-->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomact-embed-jasper</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>

</project>

(3)创建SpringBoot的全局配置文件:application.properties

spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp

(4)创建Controller

@Controller
public class UserController {

    /**
     * 处理请求,产生数据
     */
    @RequestMapping("/showUser")
    public ModelAndView  showUser(Model model){
        List<Users> list = new ArrayList<>();
        list.add(new Users(1,"张三",20));
        list.add(new Users(2,"李四",22));
        list.add(new Users(3,"王五",24));
        System.out.println("UserController启动");
        //Model对象
        model.addAttribute("list",list);
        ModelAndView mav = new ModelAndView("/WEB-INF/jsp/userList.jsp");
        //跳转视图
        return mav;
    }
}

(5)创建jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <table border="1" align="center" width="50%">
        <tr>
            <th>Id</th>
            <th>Name</th>
            <th>Age</th>
        </tr>
        <c:forEach items="${list}" var="user">
            <tr>
                <td>${user.userid}</td>
                <td>${user.username}</td>
                <td>${user.userage}</td>
            </tr>
        </c:forEach>
    </table>
</body>
</html>

(6)创建启动类

@SpringBootApplication
public class App {

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

 8.SpringBoot整合Freemarker

(1)创建项目

(2)修改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>com.mxj</groupId>
    <artifactId>08-spring-boot-view-freemarker</artifactId>
    <version>1.0-SNAPSHOT</version>


    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--freemarker启动器坐标-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
    </dependencies>

</project>

(3)编写视图

注意:SpringBoot要求模板形式的视图层文件必须放到src/main/resources/templates文件夹下

<html>
    <head>
        <title>展示用户</title>
        <meta charset="utf-8"></meta>
    </head>
    
    <body>
        <table border="1" align="center" width="50%">
            <tr>
                <th>Id</th>
                <th>Name</th>
                <th>Age</th>
            </tr>
            <#list list as user>
                <tr>
                    <td>${user.userid}</td>
                    <td>${user.username}</td>
                    <td>${user.userage}</td>
                </tr>
            </#list>
        </table>
    </body>
</html>

(4)编写Controller

@Controller
public class UserController {
    /**
     * 处理请求,产生数据
     */
    @RequestMapping("/showUser")
    public String showUser(Model model){
        List<Users> list = new ArrayList<>();
        list.add(new Users(1,"张三",20));
        list.add(new Users(2,"李四",22));
        list.add(new Users(3,"王五",24));
        //Model对象
        model.addAttribute("list",list);
        //跳转视图
        return "userList";
    }
}

(5)创建启动器

@SpringBootApplication
public class App {

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

 9.SpringBoot整合Thymeleaf

  • 创建Thymeleaf入门项目

(1)创建项目

(2)修改pom文件添加坐标

<?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>com.mxj</groupId>
    <artifactId>spring-boot-view-thymeleaf</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <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>

</project>

(3)创建存放视图的目录:Src/main/resources/templates

  templates:该目录是安全的,意味着该目录下的内容是不允许外界直接访问的

(4)创建Controller

@Controller
public
class DemoController { @RequestMapping("/show") public String showInfo(Model model){ model.addAttribute("msg","Thymeleaf第一个案例"); return "index"; } }

(5)创建视图

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <title>Title</title>
</head>
<body>
    <span th:text="Hello"></span>
    <hr/>
    <span th:text="${msg}"></span>
</body>
</html>

(6)编写启动器

@SpringBootApplication
public class App {
    public static void main(String[] args){
        SpringApplication.run(App.class,args);
    }
}
  • Thymeleaf特点

  Thymeleaf是通过特定语法对html的标记做渲染

  •  Thymeleaf语法

(1)变量输出与字符串操作

  th:text  在页面中输出值

  th:value  可以将一个值放入到input标签的value中

  ${#strings.isEmpty(key)}       判断字符串是否为空

  ${#strings.contains(msg,'T')}  判断字符串是否包含指定的子串

  ${#strings.startsWith(msg,'a')}  判断当前字符串是否以子串开头

  ${#strings.endsWith(msg,'a')}  判断当前字符串是否以子串结尾

  ${#strings.length(msg)}    返回字符串的长度

  ${#strings.indexOf(msg,'h')}  查找子串的位置,并返回该子串的下标,没找到返回-1

  $(#strings.substring(msg,start,end))  截取子串,用法与jdk下String相同

  ${#strings.toUpperCase(msg)}  字符串转大写

  ${#strings.toLowerCase(msg)}  字符串转小写

(2)日期格式化处理

  ${#dates.format(key)}      格式化日期,默认以浏览器默认语言为格式化标准

  ${#dates.format(key,'yyyy/MM/dd')}  按照自定义格式做日期转换

  ${#dates.year(key)}      获取年   

  ${#dates.month(key)}     获取月

  ${#dates.day(key)}       获取日

(3)条件判断

  th:if             if判断,th:if"${sex} == '男' "          

  th:switch th:case       switch判断

(4)迭代遍历

  th:each迭代list

<tr th:each="u var: ${list}">
    <td th:text="${u.userid}"></td>
    <td th:text="${u.username}"></td>
    <td th:text="${u.userage}"></td>
    <td th:text="${var.index}"></td>  当前迭代对象的索引,从0开始
    <td th:text="${var.count}"></td>  当前迭代对象的计数器,从1开始
    <td th:text="${var.size}"></td>   当前迭代对象的大小
    <td th:text="${var.even}"></td>   当前循环的行号是否是奇数
    <td th:text="${var.odd}"></td>   当前循环的行号是否是偶数
    <td th:text="${var.first}"></td>  当前循环是否是第一个
    <td th:text="${var.last}"></td>   当前循环是否是最后一个
</tr>

  th:each迭代map

<tr th:each="maps : ${map}">
    <td th:each="entry:${maps}" th:text="${entry.key}"></td>
    <td th:each="entry:${maps}" th:text="${entry.value}"></td>
    <td th:each="entry:${maps}" th:text="${entry.value.userid}"></td>
    <td th:each="entry:${maps}" th:text="${entry.value.username}"></td>
    <td th:each="entry:${maps}" th:text="${entry.value.userage}"></td>
</tr>

(5)域对象操作

@RequestMapping("/show")
public String showInfo(HttpServletRequest request,Model model){
    request.setAttribute("req","HttpServletRequest");
    request.getSession().setAttribute("sess","HttpSession);
    request.getSession().getServletContext.setAttribute("app","Application");
    return "index"'
}
<body>
    Request:<span th:text="${#httpServletRequest.getAttribute('req')}"></span>
    Session:<span th:text="session.sess"></span>
    Application:<span th:text="${application.app}"></span>
</body>

(6)URL表达式

  url基本语法:@{}

  url类型:  

<body>
    <a th:href="@{http://www.baidu.com}">绝对路径</a><br/>
</body>

相对于项目的上下文的相对路径

<body>
    <a th:href="@{/show}">相对路径</a>
</body>

相对于服务器路径的根

<body>
    <a th:href="@{~/project/resourcename}">相对路径</a>
</body>

url实现参数传递

<body>
    <a th:href="@{/show(id=1,name=张三)}">相对路径-传参</a>
</body>

在url中通过restful风格进行参数传递

<body>
    <a th:href="@{/path/{id}/show(id=1,name=张三)}">相对路径-传参-restful</a>
</body>

 10.SpringBoot整合SpringMVC+Mybatis

(1)创建项目

(2)修改pom文件

<?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>com.mxj</groupId>
    <artifactId>spring-boot-springmvc-mybatis</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <java.version>1.8</java.version>
        <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>
        <thymeleaf-layout-dialect.version>2.0.4</thymeleaf-layout-dialect.version>
    </properties>

    <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.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.0.1</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.9</version>
        </dependency>
    </dependencies>

</project>

(3)添加application.properties全局配置文件

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/ssm
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
mybatis.type-aliases-package=com.mxj.pojo

(4)数据库表设计

CREATE TABLE `users` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  `age` int(10) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

(5)创建实体类:Users

(6)创建mapper接口以及映射配置文件

public interface UsersMapper {
    void insertUser(Users users);
}
<?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.mxj.mapper.UsersMapper">
    <insert id="insertUser" parameterType="users">
        insert into users(name,age) values(#{name},#{age})
    </insert>
</mapper>

 (7)创建业务层

@Service
@Transactional
public class UsersServiceImpl implements UsersService {

    @Autowired
    private UsersMapper usersMapper;
    @Override
    public void addUser(Users users) {
        this.usersMapper.insertUser(users);
    }
}

(8)创建Controller

@Controller
@RequestMapping("/users")
public class UsersController {

    @Autowired
    private UsersService usersService;
    /**
     * 页面跳转
     */
    @RequestMapping("/{page}")
    public String showPage(@PathVariable String page){
        return page;
    }

    /**
     * 添加用户
     */
    @RequestMapping("/addUser")
    public String addUser(Users users){
        this.usersService.addUser(users);
        return "ok";
    }
}

(9)编写页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>添加用户</title>
</head>
<body>
    <form th:action="@{/users/addUser}" method="post">
        用户姓名:<input type="text" name="name"/><br/>
        用户年龄:<input type="text" name="age"/><br/>
        <input type="submit" name="提交"/><br/>
    </form>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>操作提示页面</title>
</head>
<body>
    操作成功!!!
</body>
</html>

 (10)编写启动类

@SpringBootApplication
@MapperScan("com.mxj.mapper")   //用于扫描MyBatis的Mapper接口
public class App {
    public static void main(String[] args){
        SpringApplication.run(App.class,args);
    }
}

 11.SpringBoot对表单做数据校验

  • SpringBoot对表单数据校验的技术特点

    SpringBoot中使用了Hiberbate-validate校验框架

  • SpringBoot表单数据校验步骤

(1)在实体类中添加校验规则

public class Users {
    @NotBlank   //非空校验
    private Integer age;
    private String name;
    @NotBlank   //密码非空校验
    private String password;
}

(2)在Controller中开启校验

    /**
     * 完成用户添加
     * @Valid 开启对Users对象的数据校验
     * BindingResult:封装了校验的结果
     */
    @RequestMapping("/save")
    public String saveUser(@Valid Users users, BindingResult result){
        if(result.hasErrors()){
            return "add";
        }
        return "ok";
    }

(3)在页面中获取提示信息

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>添加用户</title>
</head>
<body>
    <from th:action="@{/save}" method="post">
        用户姓名:<input type="text" name="name" /><font color="red" th:errors="user.name">姓名不能为空</font><br/>
        用户密码:<input type="password" name="password" /><font color="red" th:errors="user.password">密码不能为空</font><br/>
        用户年龄:<input type="text" name="age" /><font color="red" th:errors="user.age">年龄不能为空</font><br/>
        <input type="submit" value="OK"/>
    </from>
</body>
</html>
  • 其他校验规则

  @NotBlank:判断字符串是否为null或者是空串

  @NotEmpty:判断字符串是否为null或者是空串

  @Length:判断字符串的长度(最大或最小)

  @Min:判断数值最小值

  @Max:判断数值最大值

  @Email:判断邮箱是否合法

 12.SprintBoot中异常处理

  • SpringBoot中对于异常处理提供了五种处理方式

  (1)自定义错误页面

  (2)通过@ExceptionHandle注解处理异常

    /**
     * java.lang.ArithmeticException
     * 该方法需要返回一个ModelAndView,目的是可以让我们封装异常信息以及视图的指定
     * 参数Exception e:会将产生异常对象注入方法中
     */
    @ExceptionHandler(value={java.lang.ArithmeticException.class})
    public ModelAndView arithmeticExceptionHandler(Exception e){
        ModelAndView mv = new ModelAndView();
        mv.addObject("error",e.toString());
        mv.setViewName("error1");
        return mv;
    }

  (3)通过@ControllerAdvice+@ExceptionHandle注解处理异常

    需要创建一个能够处理异常的全局异常类,在该类上添加@ControllerAdvice注解,类中内容和(2)中相同

  (4)配置SimpleMappingExceptionResolver处理异常

    相比于(3)只能跳转页面,不能传递异常信息

/**
 * 全局异常处理类
 */
@Configuration
public class GlobalException {
    /**
     * 该方法必须要有返回值,返回值类型必须是:SimpleMappingExceptionResolver
     */
    @Bean
    public SimpleMappingExceptionResolver getSimpleMappingExceptioinResolver(){
        SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
        Properties mappings = new Properties();
        /**
         * 参数一:异常类型
         * 参数二:视图名称
         */
        mappings.put("java.lang.ArithmeticException","error1");
        mappings.put("java.lang.NullPointerException","error2");

        resolver.setExceptionMappings(mappings);
        return resolver;
    }
}

  (5)自定义HandlerExceptionResolver类处理异常

/**
 * 实现HandlerExceptionResolver接口做异常处理
 */
@Configuration
public class GlobalException2 implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
        ModelAndView mv = new ModelAndView();
        //判断不同异常类型,做不同视图跳转
        if(e instanceof ArithmeticException){
            mv.setViewName("error1");
        }

        if(e instanceof NullPointerException){
            mv.setViewName("error2");
        }
        mv.addObject("error",e.toString());
        return mv;
    }
}

13.SpringBoot整合Junit

/**
 * SpringBoot测试类
 * @RunWith:启动器
 * SpringJUnit4ClassRunner.class 让junit与spring环境进行整合
 * @SpringBootTest(classes={SpringBootTestApplication})
 * 当前类为SpringBoot测试类,加载启动类,启动SpringBoot
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes={SpringBootTestApplication.class})
public class UserServiceTest {

    @Autowired
    private UserServiceImpl userServiceImpl;

    @Test
    public void testAddUser(){
        this.userServiceImpl.addUser();
    }
}

14.SpringBoot的热部署

  • SpringLoader插件

方式一:maven插件方式使用SpringLoader

(1)在pom文件中添加热部署插件配置

<!--springloader插件-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <dependencies>
                    <dependency>
                        <groupId>org.springframework</groupId>
                        <artifactId>springloaded</artifactId>
                        <version>1.2.5.RELEASE</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>

(2)使用maven命令启动:spring-boot:run

(3)SpringLoader缺陷

  只能对java代码做部署处理,但是对页面不行

  这种方式是在系统后台以进程方式运行,需要手动关闭java.exe

方式二:在项目中直接使用jar包

(1)添加SpringLoader的jar包到lib目录下

(2)启动命令:-javaagent:.\lib\springloaded-1.2.5.RELEASE.jar -noverify

  • DevTools工具

 SpringLoader与DevTools的区别

  SpringLoader在部署项目时使用热部署

  DevTools在部署项目时使用重新部署的方式

(1)修改pom文件添加依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <optional>true</optional>
</dependency>

(2)可以对java代码和页面做部署处理

 15.Spring Boot缓存技术

  • Spring Boot整合Ehcache

(1)修改pom文件

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache</artifactId>
</dependency>

(2)创建Ehcache配置文件

  文件名:chcache.xml

  位置:src/main/resources

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
    
    <diskStore path="java.io.tmpdir"/>

    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            maxElementsOnDisk="10000000"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
        <persistence strategy="localTempSwap"/>
    </defaultCache>
</ehcache>

(3)修改application.properties文件

spring.cache.ehcache.config=ehcache.xml

(4)修改启动类

@SpringBootApplication
@EnableCaching
public class App {

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

(5)创建业务层

@Service
public class UsersServiceImpl implements UsersService {
    @Autowired
    private UsersRepository usersRepository;
    @Override
    public List<Users> findUserAll() {
        return null;
    }

    @Override
    @Cacheable(value = "users")
    public Users findUserById(Integer id) {
        return this.usersRepository.findOne(id);
    }

    @Override
    public Page<Users> findUserByPage(Pageable pageable) {
        return this.usersRepository.findAll(pageable);
    }

    @Override
    public void saveUsers(Users users) {
        this.usersRepository.save(users);
    }
}

(6)修改实体类,实现 Serializable接口

  • @Cacheable与@CacheEvict

(1)@Cacheable

  作用:把方法的返回值添加到Ehcache中做缓存

  value属性:指定一个Ehcach配饰文件中的缓存策略,如果没有指定使用默认

  key属性:给存储的值添加唯一标记,查询时如果有key相同的直接从缓存中返回

(2)@CacheEvict

  作用:清除缓存

  ex:@CacheEvict(value="users",allEntries=true)清除缓存中以users缓存策略缓存的对象

  • Spring Boot整合Spring Data Redis

16.Spring Boot整合Spring Data JPA

  • Demo

(1)创建项目

(2)修改pom文件添加坐标

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.9</version>
        </dependency>            

(3)在项目中添加application.properties文件

spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/ssm?characterEncoding=UTF-8&useUnicode=true&useSSL=true&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

(4)添加实体类

@Entity
@Table(name="t_users")
public class Users {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id")
    private Integer id;

    @Column(name="name")
    private String name;

    @Column(name="age")
    private Integer age;

    @Column(name="address")
    private String address;
}

(5)编写Dao接口

/**
 * 参数一 T:当前需要映射的实体
 * 参数二 ID:当前映射的实体中的OID的类型
 */
public interface UsersRepository extends JpaRepository<Users,Integer> {
}

(6)创建启动类

@SpringBootApplication
public class App {

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

(7)编写测试代码

/**
 * 测试类
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = App.class)
public class UsersRepositoryTest {

    @Autowired
    private UsersRepository usersRepository;

    @Test
    public void testSave(){

        Users users = new Users();
        users.setAddress("Beijing");
        users.setAge(20);
        users.setName("zhangsan");
        this.usersRepository.save(users);
    }
}
  •  Spring Data JPA提供的核心接口

(1)Repository接口

  提供了方法名称命名查询方式

  提供了基于@Query注解查询与更新

编写接口

/**
 * Repository接口的方法名称命名查询
 */
public interface UsersRepositoryByName extends Repository<Users,Integer> {

    //方法的名称必须要遵循驼峰式命名规则,findBy(关键字)+属性名称(首字母大写)+查询条件(首字母大写)
    public List<Users> findByName(String name);

    List<Users> findByNameAndAge(String name,Integer age);

    List<Users> findByNameLike(String name);
}

测试代码

/**
 * 测试类
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = App.class)
public class UsersRepositoryTest {

    @Autowired
    private UsersRepositoryByName usersRepositoryByName;
/**
     * Repository--方法名称命名测试
     */
    @Test
    public void testFindName(){
        List<Users> list = this.usersRepositoryByName.findByName("zhangsan");
        for(Users users : list){
            System.out.println(users);
        }
    }

    /**
     * Repository--方法名称命名测试
     */
    @Test
    public void testFindNameAndAge(){
        List<Users> list = this.usersRepositoryByName.findByNameAndAge("zhangsan",21);
        for(Users users : list){
            System.out.println(users);
        }
    }

    /**
     * Repository--方法名称命名测试
     */
    @Test
    public void testFindNameLike(){
        List<Users> list = this.usersRepositoryByName.findByNameLike("zhang");
        for(Users users : list){
            System.out.println(users);
        }
    }
}

@Query注解方式编写接口

/**
 * Repository @Query
 */
public interface UsersRepositoryQueryAnnotation extends Repository<Users,Integer> {

    @Query("from Users where name = ?")
    List<Users> queryByNameUseHQL(String name);

    @Query(value = "select * from t_users where name = ?",nativeQuery = true)
    List<Users> queryByNameUseSQL(String name);

    @Query("update Users set name = ? where id = ?")
    @Modifying  //
    void updateUsersNameById(String name,Integer id);

}

测试代码

/**
 * 测试类
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = App.class)
public class UsersRepositoryTest {

    @Autowired
    private UsersRepositoryQueryAnnotation usersRepositoryQueryAnnotation;
    
   
    /**
     * Repository--@Query测试
     */
    @Test
    public void testUsersRepositoryQueryAnnotation(){
        List<Users> list = this.usersRepositoryQueryAnnotation.queryByNameUseHQL("zhangsan");
        for(Users users : list){
            System.out.println(users);
        }
    }

    /**
     * Repository--@Query测试
     */
    @Test
    public void testQueryByNameUseSQL(){
        List<Users> list = this.usersRepositoryQueryAnnotation.queryByNameUseSQL("zhangsan");
        for(Users users : list){
            System.out.println(users);
        }
    }

    /**
     * Repository--@Query测试
     */
    @Test
    @Transactional  //这两个注解一起使用时事务自动回滚
    @Rollback       //取消自动回滚
    public void testUpdateUsersNameById(){
        this.usersRepositoryQueryAnnotation.updateUsersNameById("zhangsan",1);
    }
}

(2)CrudRepository接口

  CrudRepository接口,主要是完成增删改查的操作,继承了Repository接口

(3)PagingAndSortingRepository接口

  排序&&分页

(4)JpaRepository接口*

  继承PagingAndSortingRepository接口,对继承的父接口中的方法的返回值进行适配

(5)JPASpecificationExecutor接口

  该接口主要是提供了多条件查询的支持,并且可以在查询中添加分页与排序

  注意:单独存在,需配合其他接口使用

17.SpringBoot定时任务

  • Scheduled定时任务器

    Spring3.0以后自带的一个定时任务器

(1)在pom文件中添加Scheduled的坐标

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-context-support</artifactId>
</dependency>

(2)编写定时任务类

/**
 * Scheduled定时任务器
 */
@Component
public class ScheduledDemo {

    /**
     * 定时任务方法
     * @Scheduled:设置定时任务
     * cron属性:cron表达式,定时任务触发时间的字符串表达形式
     */
    @Scheduled(cron = "0/2 * * * * ?")
    public void scheduledMethod(){
        System.out.println("定时器被触发 "+new Date());
    }
}

(3)在启动类中开启定时任务的使用

/**
 * Scheduled
 */
@SpringBootConfiguration
@EnableScheduling
public class App {
    public static void main(String[] args){
        SpringApplication.run(App.class,args);
    }
}
  • cron表达式

(1)语法格式

  Seconds Minutes Hours Day Month Week Year

  Seconds Minutes Hours Day Month Week

(2)各字符含义

位置 时间域名 允许值 允许的特殊字符
1 0-59 , - * /
2 分钟 0-59 , - * /
3 小时 0-23 , - * /
4 1-31 , - * / L W C
5 1-12 , - * /
6 星期 1-7 , - * ? / L W C
7 年(可选) 1970-2099 , - * /

*:可用在所有字符中,表示对应时间域的每一个时刻

?:该字符只在日期和星期字段中使用,它通常指定为“无意义的值”,相当于占位符

-:表式一个范围

,:表式一个列表值

/:x/y表示一个等步长序列,x为起始值,y为等量步长值

L:该字符只在日期和星期字段中使用,代表“Last”的意思

W:该字符只能出现在日期字段里,是对前导日期的修饰,表示离该日期最近的工作日

LW:在日期字段可以组合使用,意思是当月最后一个工作日

#:只能在日期字段中使用,表示当月某个工作日

C:该字符只能在日期和星期字段中使用,代表“Calendar”,表示计划所关联的日期;如果日期没有被关联,则相当于日历中所有日期。

  • 整合Quartz定时任务框架

(1)Quartz的介绍以及Quartz的使用思路

  Job - 任务

  Trigger - 触发器

  Scheduler - 任务调度

(2)Quartz基本使用

pom文件

<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.2.1</version>
</dependency>

创建任务类

/**
 * 定义任务类
 */
public class QuartzDemo implements Job {

    /**
     * 任务被触发时所执行的方法
     * @param jobExecutionContext
     * @throws JobExecutionException
     */
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("Execute..."+new Date());
    }
}

编写测试代码

public class QuartzMain {

    public static void main(String[] args) throws SchedulerException {

        //创建job对象 做什么
        JobDetail job = JobBuilder.newJob(QuartzDemo.class).build();

        /**
         * 简单的trigger触发时间,通过Quartz提供一个方法来完成简单的重复调用
         * cron Trigger:按照Cron的表达式来给定触发时间
         */
        //创建Trigger对象 什么时间做
        //Trigger trigger = TriggerBuilder.newTrigger().withSchedule(SimpleScheduleBuilder.repeatSecondlyForever()).build();
        Trigger trigger = TriggerBuilder.newTrigger().withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?")).build();

        //创建Scheduler对象 在什么时间做什么事
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
        scheduler.scheduleJob(job,trigger);

        //启动
        scheduler.start();
    }
}

 (3)Spring Boot整合Quartz定时框架

修改pom文件

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
</dependency>

<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.2.1</version>
    <exclusions>
        <exclusion>
            <artifactId>slf4j-api</artifactId>
            <groupId>org.slf4j</groupId>
        </exclusion>
    </exclusions>
</dependency>

编写Quartz配置类

/**
 * Quartz配置类
 */

@Configuration
public class QuartzConfig {

    /**
     * 1.创建Job对象
     */
    @Bean
    public JobDetailFactoryBean jobDetailFactoryBean(){
        JobDetailFactoryBean factory = new JobDetailFactoryBean();
        //关联我们自己的Job类
        factory.setJobClass(QuartzDemo.class);
        return factory;
    }

    /**
     * 2.创建Trigger对象
     * 简单的Trigger
     */
    @Bean
    public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
        SimpleTriggerFactoryBean factory = new SimpleTriggerFactoryBean();
        //关联JobDetail对象
        factory.setJobDetail(jobDetailFactoryBean.getObject());
        //该参数表示一个执行的毫秒数
        factory.setRepeatInterval(2000);
        //重复次数
        factory.setRepeatCount(5);
        return factory;
    }

    /**
     * 2.创建Trigger对象
     * Cron Trigger
     */
    @Bean
    public CronTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
        CronTriggerFactoryBean factory = new CronTriggerFactoryBean();
        //关联JobDetail对象
        factory.setJobDetail(jobDetailFactoryBean.getObject());
        //设置触发时间
        factory.setCronExpression("0/2 * * * * ?");
        return factory;
    }


    /**
     * 3.创建Scheduler对象
     */
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(SimpleTriggerFactoryBean simpleTriggerFactoryBean){
        SchedulerFactoryBean factory = new SchedulerFactoryBean();
        //关联trigger
        factory.setTriggers(simpleTriggerFactoryBean.getObject());
        return factory;
    }
}

启动类

/**
 * spring Boot整合Quartz
 */
@SpringBootApplication
@EnableScheduling
public class App {
    public static void main(String[] args){
        SpringApplication.run(App.class,args);
    }
}

(4)Job类中注入对象

注入时会产生异常,编写MyAdaptableJobFactory类解决该异常

/**
 * 该方法需要实例化任务对象手动的添加springIOC容器中并且完成对象的注入
 */
@Component("MyAdaptableJobFactory")
public class MyAdaptableJobFactory extends AdaptableJobFactory {
    /**
     * AutowireCapableBeanFactory 可以将一个对象添加到SpringIOC容器中,并且完成对象注入
     */
    @Autowired
    private AutowireCapableBeanFactory autowireCapableBeanFactory;
    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        Object obj = super.createJobInstance(bundle);
        //将obj对象添加到Spring IOC容器中,并完成注入
        this.autowireCapableBeanFactory.autowireBean(obj);
        return obj;
    }
}

修改QuartzConfig类

    /**
     * 3.创建Scheduler对象
     */
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean cronTriggerFactoryBean,MyAdaptableJobFactory myAdaptableJobFactory){
        SchedulerFactoryBean factory = new SchedulerFactoryBean();
        //关联trigger
        factory.setTriggers(cronTriggerFactoryBean.getObject());
        factory.setJobFactory(myAdaptableJobFactory);
        return factory;
    }

 

posted @ 2019-08-02 09:53  M_x_j  阅读(273)  评论(0编辑  收藏  举报