SpringMVC 参数校验+整合spring+mybatis

校验框架

校验框架入门

表单校验的重要性

  • 表单校验保障了数据有效性、安全性

在这里插入图片描述

数据可以随意输入,导致错误的结果。后端表单校验的重要性。

表单校验分类

  • 校验位置:
    • 客户端校验
    • 服务端校验
  • 校验内容与对应方式:
    • 格式校验
      • 客户端:使用Js技术,利用正则表达式校验
      • 服务端:使用校验框架
    • 逻辑校验
      • 客户端:使用ajax发送要校验的数据,在服务端完成逻辑校验,返回校验结果
      • 服务端:接收到完整的请求后,在执行业务操作前,完成逻辑校验

表单校验规则

  • 长度:例如用户名长度,评论字符数量
  • 非法字符:例如用户名组成
  • 数据格式:例如Email格式、 IP地址格式
  • 边界值:例如转账金额上限,年龄上下限
  • 重复性:例如用户名是否重复

表单校验框架

  • JSR(Java Specification Requests):Java 规范提案

    303:提供bean属性相关校验规则

  • JSR规范列表

    • 企业应用技术
       Contexts and Dependency Injection for Java (Web Beans 1.0) (JSR 299)
       Dependency Injection for Java 1.0 (JSR 330)@postConstruct, @PreDestroy
       Bean Validation 1.0 (JSR 303)
       Enterprise JavaBeans 3.1 (includes Interceptors 1.1) (JSR 318)
       Java EE Connector Architecture 1.6 (JSR 322)
       Java Persistence 2.0 (JSR 317)
       Common Annotations for the Java Platform 1.1 (JSR 250)
       Java Message Service API 1.1 (JSR 914)
       Java Transaction API (JTA) 1.1 (JSR 907)
       JavaMail 1.4 (JSR 919)
    • Web应用技术
       Java Servlet 3.0 (JSR 315)
       JavaServer Faces 2.0 (JSR 314)
       JavaServer Pages 2.2/Expression Language 2.2 (JSR 245)
       Standard Tag Library for JavaServer Pages (JSTL) 1.2 (JSR 52)
       Debugging Support for Other Languages 1.0 (JSR 45)
       模块化 (JSR 294)
       Swing应用框架 (JSR 296)
       JavaBeans Activation Framework (JAF) 1.1 (JSR 925)
       Streaming API for XML (StAX) 1.0 (JSR 173)
    • 管理与安全技术
       Java Authentication Service Provider Interface for Containers (JSR 196)
       Java Authorization Contract for Containers 1.3 (JSR 115)
       Java EE Application Deployment 1.2 (JSR 88)
       J2EE Management 1.1 (JSR 77)
       Java SE中与Java EE有关的规范
       JCache API (JSR 107)
       Java Memory Model (JSR 133)
       Concurrency Utilitie (JSR 166)
       Java API for XML Processing (JAXP) 1.3 (JSR 206)
       Java Database Connectivity 4.0 (JSR 221)
       Java Management Extensions (JMX) 2.0 (JSR 255)
       Java Portlet API (JSR 286)
  • Web Service技术
     Java Date与Time API (JSR 310)
     Java API for RESTful Web Services (JAX-RS) 1.1 (JSR 311)
     Implementing Enterprise Web Services 1.3 (JSR 109)
     Java API for XML-Based Web Services (JAX-WS) 2.2 (JSR 224)
     Java Architecture for XML Binding (JAXB) 2.2 (JSR 222)
     Web Services Metadata for the Java Platform (JSR 181)
     Java API for XML-Based RPC (JAX-RPC) 1.1 (JSR 101)
     Java APIs for XML Messaging 1.3 (JSR 67)
     Java API for XML Registries (JAXR) 1.0 (JSR 93)

  • JCP(Java Community Process):Java社区

  • Hibernate框架中包含一套独立的校验框架hibernate-validator

    导入坐标

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>6.1.0.Final</version>
    </dependency>
    
      <!--支持tomcat7-->
      <dependency>
          <groupId>org.hibernate</groupId>
          <artifactId>hibernate-validator</artifactId>
          <version>5.2.1.Final</version>
      </dependency>
    

    注意:
    tomcat7 :搭配hibernate-validator版本5...Final
    tomcat8.5↑ :搭配hibernate-validator版本6...Final

快速使用

** 开启校验**

 名称:@Valid 、 @Validated

  • @valid : 一般在实体类中校验别的实体类
  • @Validated : 一般校验形参
     类型:形参注解
     位置:处理器类中的实体类类型的方法形参前方
     作用:设定对当前实体类类型参数进行校验
     范例:

1.编写实体类,存放表单数据。并且设置校验规则

package cn.itcast.domain;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.NotBlank;
import org.springframework.format.annotation.DateTimeFormat;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.util.Date;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    @NotBlank(message = "姓名不能为空")
    private String name;

    @NotNull(message = "年龄不能为空")//此处不能用NotBlank,因为该注解只能校验字符串,而age是数字
    @Max(message = "年龄不能超过100",value = 100)
    @Min(message = "年龄不能小于1",value = 1)
    private Integer age;
}

2.编写处理器,接受表单数据,并且启用校验

package cn.itcast.controller;

import cn.itcast.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;

@Controller
@RequestMapping("/user")
@CrossOrigin
public class UserController {

    @RequestMapping("/reg")
    @ResponseBody
    public Map method(@Validated User user, Errors errors){//errors中存放校验失败的提示信息
        HashMap<Object, Object> map = new HashMap<>();
        HashMap<Object, Object> errorInfo = new HashMap<>();//存放字段名对应的错误提示
        //判断是否有错误信息
        if(errors.hasErrors()){
            for (FieldError e : errors.getFieldErrors()) {//errors.getFieldErrors()获取所有的错误信息
                //e.getField()表示获取属性名,e.getDefaultMessage()获取错误提示信息
                errorInfo.put(e.getField(),e.getDefaultMessage());
            }
        }

        if(errorInfo.size()==0){//没有错误数据
            map.put("status",true);
        }else{
            map.put("status",false);
            map.put("errorInfos",errorInfo);
        }

        return map;
    }
}

3.测试,访问 http://localhost/user/reg?name&age 结果如下

设置校验规则

 名称:@NotNull、@NotBlank

  • @NotNull : 一般用于校验非字符串
  • @NoBlank : 一般用于校验字符串
     类型:属性注解 等
     位置:实体类属性上方
     作用:设定当前属性校验规则
     范例:
    每个校验规则所携带的参数不同,根据校验规则进行相应的调整
    具体的校验规则查看对应的校验框架进行获取
    public class Employee{
       @NotNull(message = "姓名不能为空")
       private String name;//员工姓名
    }  
    

3.测试,访问 http://localhost/user/reg?name&age 结果如下

注意:测试的时候必须写清楚发送给服务器哪些字段,如果不写,服务器可能不校验。

{
    "errorInfos": {
        "name": "姓名不能为空",
        "age": "请输入年龄"
    },
    "status": false
}

获取错误信息

@RequestMapping(value = "/addemployee")
public String addEmployee(@Valid Employee employee, Errors errors, Model model){
    System.out.println(employee);
    if(errors.hasErrors()){
        for(FieldError error : errors.getFieldErrors()){
            model.addAttribute(error.getField(),error.getDefaultMessage());
        }
        return "addemployee.jsp";
    }
    return "success.jsp";
}  

通过形参Errors获取校验结果数据,通过Model接口将数据封装后传递到页面显示

<form action="/addemployee" method="post">
    员工姓名:<input type="text" name="name"><span style="color:red">${name}</span><br/>
    员工年龄:<input type="text" name="age"><span style="color:red">${age}</span><br/>
    <input type="submit" value="提交">
</form>

通过形参Errors获取校验结果数据,通过Model接口将数据封装后传递到页面显示
页面获取后台封装的校验结果信息

多规则校验

  • 同一个属性可以添加多个校验器
@NotNull(message = "请输入您的年龄")
@Max(value = 60,message = "年龄最大值不允许超过60岁")
@Min(value = 18,message = "年龄最小值不允许低于18岁")
private Integer age;//员工年龄
  • 3种判定空校验器的区别
    在这里插入图片描述
    @Null 限制只能为null
    @NotNull 限制必须不为null
    @AssertFalse 限制必须为false
    @AssertTrue 限制必须为true
    @DecimalMax(value) 限制必须为一个不大于指定值的数字
    @DecimalMin(value) 限制必须为一个不小于指定值的数字
    @Digits(integer,fraction) 限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction
    @Future 限制必须是一个将来的日期
    @Max(value) 限制必须为一个不大于指定值的数字
    @Min(value) 限制必须为一个不小于指定值的数字
    @Past 限制必须是一个过去的日期
    @Pattern(value) 限制必须符合指定的正则表达式
    @Size(max,min) 限制字符长度必须在min到max之间
    @Past 验证注解的元素值(日期类型)比当前时间早
    @NotEmpty 验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0)
    @NotBlank 验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,
    @NotBlank只应用于字符串且在比较时会去除字符串的空格
    @Email 验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式

嵌套校验

 名称:@Valid
 类型:属性注解
 位置:实体类中的引用类型属性上方
 作用:设定当前应用类型属性中的属性开启校验
 范例:

public class Employee {
    //实体类中的引用类型通过标注@Valid注解,设定开启当前引用类型字段中的属性参与校验
    @Valid
    private Address address;
}

 注意:开启嵌套校验后,被校验对象内部需要添加对应的校验规则

分组校验

  • 同一个模块,根据执行的业务不同,需要校验的属性会有不同
    • 新增用户
    • 修改用户
  • 对不同种类的属性进行分组,在校验时可以指定参与校验的字段所属的组类别
    • 定义组(通用)
    • 为属性设置所属组,可以设置多个
    • 开启组校验
      在这里插入图片描述

第一步:定义了两个组,一个是注册的时候校验,一个是修改的时候校验

package cn.itcast.group;

public interface RegGroup {
}
Java
package cn.itcast.group;

public interface UpdateUserGroup {
}

第二步:定义User\Address实体类,指定校验规则,并分组校验
规则:注册的时候校验帐号和密码,修改的时候校验密码和地址

Address

package cn.itcast.domain;

import cn.itcast.group.RegGroup;
import cn.itcast.group.UpdateUserGroup;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.NotBlank;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Address {
    @NotBlank(message = "省名不能为空",groups = {UpdateUserGroup.class})
    /**省的名字*/
    private String province;

    @NotBlank(message = "城市名不能为空",groups = {UpdateUserGroup.class})
    /**城市的名字*/
    private String city;
}

User

package cn.itcast.domain;

import cn.itcast.group.RegGroup;
import cn.itcast.group.UpdateUserGroup;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.NotBlank;
import org.springframework.format.annotation.DateTimeFormat;

import javax.validation.Valid;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import java.util.Date;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    @NotBlank(message = "用户名不能为空",groups = RegGroup.class)
    @Pattern(regexp = "^[A-Za-z_@.]{6,10}$",message = "用户名必须是6-10位之间的字母、下划线、@、.",groups = RegGroup.class)
    private String username;

    @NotBlank(message = "密码不能为空",groups = {RegGroup.class, UpdateUserGroup.class})
    @Pattern(regexp = "^[A-Za-z_@.]{6,10}$",message = "密码必须是6-10位之间的字母、下划线、@、.",groups = {RegGroup.class, UpdateUserGroup.class})
    private String password;

    @Valid()
    private Address address;
}

第三步 在controller层,分别定义两个接口,一个是注册接口,使用注册的校验规则,另一个是修改接口,使用修改的校验规则

package cn.itcast.controller;

import cn.itcast.domain.User;
import cn.itcast.group.RegGroup;
import cn.itcast.group.UpdateUserGroup;
import org.springframework.stereotype.Controller;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;

@Controller
@RequestMapping("/user")
@CrossOrigin
public class UserController {

    @RequestMapping("/reg")
    @ResponseBody
    public Map reg(@Validated(RegGroup.class) User user, Errors errors){//errors中存放校验失败的提示信息
        HashMap<Object, Object> map = new HashMap<>();
        HashMap<Object, Object> errorInfo = new HashMap<>();//存放字段名对应的错误提示
        //判断是否有错误信息
        if(errors.hasErrors()){
            for (FieldError e : errors.getFieldErrors()) {//errors.getFieldErrors()获取所有的错误信息
                //e.getField()表示获取属性名,e.getDefaultMessage()获取错误提示信息
                errorInfo.put(e.getField(),e.getDefaultMessage());
            }
        }

        if(errorInfo.size()==0){//没有错误数据
            map.put("status",true);
        }else{
            map.put("status",false);
            map.put("errorInfos",errorInfo);
        }

        return map;
    }
    @RequestMapping("/update")
    @ResponseBody
    public Map update(@Validated(UpdateUserGroup.class) User user, Errors errors){//errors中存放校验失败的提示信息
        HashMap<Object, Object> map = new HashMap<>();
        HashMap<Object, Object> errorInfo = new HashMap<>();//存放字段名对应的错误提示
        //判断是否有错误信息
        if(errors.hasErrors()){
            for (FieldError e : errors.getFieldErrors()) {//errors.getFieldErrors()获取所有的错误信息
                //e.getField()表示获取属性名,e.getDefaultMessage()获取错误提示信息
                errorInfo.put(e.getField(),e.getDefaultMessage());
            }
        }

        if(errorInfo.size()==0){//没有错误数据
            map.put("status",true);
        }else{
            map.put("status",false);
            map.put("errorInfos",errorInfo);
        }

        return map;
    }
}

测试结果

注册:没有校验地址
在这里插入图片描述
修改:没有校验帐号
在这里插入图片描述

ssm整合

整合流程简介

整合步骤分析

SSM(Spring+SpringMVC+MyBatis)

  • Spring

    • 框架基础
  • MyBatis

    • mysql+druid+pagehelper
  • Spring整合MyBatis

  • junit测试业务层接口

  • SpringMVC

    • rest风格(postman测试请求结果)
    • 数据封装json(jackson)
  • Spring整合SpringMVC

    • Controller调用Service
  • 其他

    • 表现层数据封装

    • 自定义异常

表结构

在这里插入图片描述
​ 最重要的5个步骤

  1. Spring

  2. MyBatis

  3. Spring整合MyBatis

  4. SpringMVC

  5. Spring整合SpringMVC

项目结构搭建

引入依赖

<dependencies>
  <!--jackson-->
  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.0</version>
  </dependency>
  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.0</version>
  </dependency>
  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.0</version>
  </dependency>
  <!-- servlet3.1规范的坐标 -->
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
  </dependency>
  <!--jsp坐标-->
  <dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.0</version>
    <scope>provided</scope>
  </dependency>

  <!--Lombok-->
  <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.6</version>
  </dependency>

  <!--文件上传-->
  <dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
  </dependency>
  <dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.3</version>
  </dependency>
  <!--数据校验,支持tomcat7-->
  <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.2.1.Final</version>
  </dependency>
  <!--spring的坐标-->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.6.RELEASE</version>
  </dependency>
  <!--spring web的坐标-->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.1.6.RELEASE</version>
  </dependency>
  <!--springmvc的坐标-->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.1.6.RELEASE</version>
  </dependency>
  <!--Spring集成Junit测试-->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.0.5.RELEASE</version>
  </dependency>
  <!--Spring集成Aspect切面-->
  <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.13</version>
  </dependency>
  <!--Spring 事物-->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>5.0.5.RELEASE</version>
  </dependency>
  <!--mybatis-->
  <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.3</version>
  </dependency>
  <!--mysql-->
  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.46</version>
  </dependency>
  <!--spring连接数据库-->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.1.6.RELEASE</version>
  </dependency>
  <!--数据库连接池-->
  <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.21</version>
  </dependency>
  <!--spring集成mybatis-->
  <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.0</version>
  </dependency>
  <!--spring集成junit-->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.0.5.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
  </dependency>
  <!--分页插件-->
  <dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.1.2</version>
  </dependency>
</dependencies>

<build>
  <plugins>
    <!--jdk编译插件-->
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.1</version>
      <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <encoding>utf-8</encoding>
      </configuration>
    </plugin>

    <!--tomcat插件-->
    <plugin>
      <groupId>org.apache.tomcat.maven</groupId>
      <!-- tomcat7的插件, 不同tomcat版本这个也不一样 -->
      <artifactId>tomcat7-maven-plugin</artifactId>
      <version>2.1</version>
      <configuration>
        <!-- 通过maven tomcat7:run运行项目时,访问项目的端口号 -->
        <port>80</port>
        <!-- 项目虚拟路径  如果配置的, 则访问路径为localhost:8080/-->
        <path>/</path>
      </configuration>
    </plugin>
  </plugins>
</build>

创建dao\service\domain

创建实体类 Account

package cn.itcast.domain;

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

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Account {
    private Integer id;
    private String name;
    private Double money;
}

创建 Dao

package cn.itcast.dao;

import cn.itcast.domain.Account;

import java.util.List;

public interface AccountDao {
    @Select("select * from account")
    List<Account> findAll();
}

创建Service

package cn.itcast.service;

import cn.itcast.domain.Account;

import java.util.List;

public interface AccountService {
    List<Account> findAll() ;
}

创建Service实现类

package cn.itcast.service.impl;

import cn.itcast.dao.AccountDao;
import cn.itcast.domain.Account;
import cn.itcast.service.AccountService;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

@Service
public class AccountServiceImpl implements AccountService {
	@Autowaired
    private AccountDao accountDao;

    public List<Account> findAll() {
        return accountDao.findAll();
    }
}

创建jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring01
jdbc.username=root
jdbc.password=root

Spring整合Mybatis

  1. 配置包扫描
  2. 配置数据库连接池
  3. 集成MyBatis
  4. 集成分页
  5. 配置事物
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
">
    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

    <!--1.配置包扫描-->
    <context:component-scan base-package="cn.itcast">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>


    <!--2.配置数据库连接池-->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!--3.集成MyBatis-->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="typeAliasesPackage" value="cn.itcast.domain"></property>
        <!--4.集成分页-->
        <property name="plugins">
            <array>
                <bean class="com.github.pagehelper.PageInterceptor">
                    <property name="properties">
                        <props>
                            <prop key="helperDialect">mysql</prop>
                            <!--reasonable:分页合理化参数,默认值为false。当该参数设置为 true 时,pageNum<=0 时会查询第一页,
                            pageNum>pages(超过总数时),会查询最后一页。
                            默认false 时,直接根据参数进行查询。-->
                            <prop key="reasonable">true</prop>
                        </props>
                    </property>
                </bean>
            </array>
        </property>
    </bean>

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="cn.itcast.dao"></property>
    </bean>

    <!--5.配置平台事物管理器,启用事物注解驱动在第一行-->
    <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
</beans>

测试

package cn.itcast.service.impl;

import cn.itcast.service.AccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AccountServiceImplTest {

    @Autowired
    private AccountService accountService ;
    @Test
    public void findAll() {
        System.out.println(accountService.findAll());
    }
}

配置SpringMVC

  1. 配置包扫描,只扫controller
  2. 启用springmvc注解
  3. 静态资源放行
  4. 配置视图解析器
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--1.配置包扫描,只扫controller-->
    <context:component-scan base-package="cn.itcast">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!--2.启用springmvc注解-->
    <mvc:annotation-driven/>

    <!--3.静态资源放行-->
    <mvc:default-servlet-handler/>

    <!--4.配置视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

配置web.xml

配置web核心三大组件
  1. listener:ContextLoaderListener
  2. filter:CharacterEncodingFilter
  3. servlet:DispatcherServlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
  <display-name>Archetype Created Web Application</display-name>
<!--

  1.listener:ContextLoaderListener

  2.filter:CharacterEncodingFilter

  3.servlet:DispatcherServlet

-->

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <filter>
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-mvc.xml</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

创建Result统一返回数据格式

Result

package cn.itcast.domain;

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

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Result {
    /**操作成功或失败的状态*/
    private boolean flag;
    /**小时提示*/
    private String message;
    /**消息状态码*/
    private Integer code;
    /**数据*/
    private Object data;
}

常量类

package cn.itcast.constant;

public class CodeConstant {
    //账户模块以1开头,长度是6
    /**查询账户成功*/
    public static final Integer ACCOUNT_GET_SUCCESS = 100001;
    /**查询账户失败*/
    public static final Integer ACCOUNT_GET_ERROR = 100002;
}
package cn.itcast.constant;

public class MessageConstant {
    //账户模块以1开头,长度是6
    /**查询账户成功*/
    public static final String ACCOUNT_GET_SUCCESS = "查询账户成功";
    /**查询账户失败*/
    public static final String ACCOUNT_GET_ERROR = "查询账户失败";
}

创建controller

@RestController
@RequestMapping("/account")
public class AccountController {
    @Autowired
    private AccountService accountService;

    @RequestMapping
    public Result findAll(){
        try {
            List<Account> list = accountService.findAll();
            return new Result(true, MessageConstant.ACCOUNT_GET_SUCCESS, CodeConstant.ACCOUNT_GET_SUCCESS,list);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false,MessageConstant.ACCOUNT_GET_ERROR,CodeConstant.ACCOUNT_GET_ERROR,null);
        }
    }
}

统一异常处理

自定义异常

设定自定义异常,封装程序执行过程中出现的问题,便于表现层进行统一的异常拦截并进行处理

  • BusinessException
  • SystemException
    自定义异常消息返回时需要与业务正常执行的消息按照统一的格式进行处理

定义BusinessException

public class BusinessException extends RuntimeException {
    //自定义异常中封装对应的错误编码,用于异常处理时获取对应的操作编码
    private Integer code;

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public BusinessException(Integer code) {
        this.code = code;
    }

    public BusinessException(String message, Integer code) {
        super(message);
        this.code = code;
    }

    public BusinessException(String message, Throwable cause,Integer code) {
        super(message, cause);
        this.code = code;
    }

    public BusinessException(Throwable cause,Integer code) {
        super(cause);
        this.code = code;
    }

    public BusinessException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace,Integer code) {
        super(message, cause, enableSuppression, writableStackTrace);
        this.code = code;
    }
}
@GetMapping("/{uuid}")
public Result get(@PathVariable Integer uuid){
    User user = userService.get(uuid);
    //模拟出现异常,使用条件控制,便于测试结果
    if (uuid == 10 ) throw new BusinessException("查询出错啦,请重试!",Code.GET_ERROR);
    return new Result(null != user ?Code.GET_OK: Code.GET_ERROR,user);
}

返回消息兼容异常信息

@Component
@ControllerAdvice
public class ProjectExceptionAdivce {
    @ExceptionHandler(BusinessException.class)
    @ResponseBody
    //对出现异常的情况进行拦截,并将其处理成统一的页面数据结果格式
    public Result doBusinessException(BusinessException e){
        return new Result(e.getCode(),e.getMessage());
    }
}

纯注解开发SSM

用注解替代applicationContext.xml

同前期设置,添加事务注解驱动
@Configuration

//扫描组件,排除SpringMVC对应的bean,等同于<context:component-scan />
@ComponentScan(value = "com.itheima",excludeFilters = {
    @ComponentScan.Filter(type= FilterType.ANNOTATION,classes = {Controller.class})})
@PropertySource("classpath:jdbc.properties")
@Import({JdbcConfig.class,MyBatisConfig.class})
//等同于<tx:annotation-driven transaction-manager="txManager"/>,导入的默认名称为transactionManager
@EnableTransactionManagement
public class SpringConfig {
    //等同于<bean   class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    @Bean("transactionManager")
    public DataSourceTransactionManager getDataSourceTxManager(@Autowired DataSource dataSource){
        DataSourceTransactionManager dtm = new DataSourceTransactionManager();
        //等同于<property name="dataSource" ref="dataSource"/>
        dtm.setDataSource(dataSource);
        return dtm;
    }
}  

用注解替代spring-mvc.xml

  • 同前期设置,添加@EnableWebMvc注解

    @Configuration
    @ComponentScan("com.itheima.controller")
    @EnableWebMvc
    public class SpringMvcConfig implements WebMvcConfigurer {
    }
    
  • EnableWebMvc

  1. 支持ConversionService的配置,可以方便配置自定义类型转换器
  2. 支持@NumberFormat注解格式化数字类型
  3. 支持@DateTimeFormat注解格式化日期数据,日期包括Date,Calendar,JodaTime(JodaTime要导包)
  4. 支持@Valid的参数校验(需要导入JSR-303规范)
  5. 配合第三方jar包和SpringMVC提供的注解读写XML和JSON格式数据
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值