其他分享
首页 > 其他分享> > SSM整合(MyBatis-Spring-SpringMVC)...校验技术

SSM整合(MyBatis-Spring-SpringMVC)...校验技术

作者:互联网

  1. 实用技术-校验框架
  2. SSM整合-视频
  3. 纯注解开发SSM

1 校验框架

1.1 入门

1.1.1 表单校验的重要性

表单校验保障了数据有效性、安全性
数据可以随意输入,导致错误的结果。

1.1.2 表单校验分类

1.1.3 格式校验规则

以下几种全部属于格式校验:

1.1.4 表单校验框架

1.2 快速使用

导入hibernate-validator校验框架的坐标

<!--导入校验的jsr303规范:接口-->
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
</dependency>
<!--导入校验框架实现技术-->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.1.0.Final</version>
</dependency>

注意:
tomcat7 :搭配hibernate-validator版本5...Final
tomcat8.5↑ :搭配hibernate-validator版本6...Final ,必须使用外置tomcat

1. 开启校验

 名称:@Valid 、 @Validated
 类型:形参注解
 位置:处理器类中的实体类类型的方法形参前方
 作用:设定对当前实体类类型参数进行校验
 范例:

@RequestMapping(value = "/addemployee")
public String addEmployee(@Valid Employee employee) {
    System.out.println(employee);
    return "success";
}

2.设置校验规则

 名称:@NotNull, @NotBlank, @NotEmpty
 类型:属性注解
 位置:属性上方
 作用:设定当前属性校验规则
 范例:每个校验规则所携带的参数不同,根据校验规则进行相应的调整

public class Employee{
    
    @NotBlank(message = "姓名不能为空")
    private String name;//员工姓名
    
    //添加getter,setter方法
}  

易错点:必须给name,age等属性编写getter,setter方法

3.获取错误信息

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

@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";
}

在JSP页面中获取后台封装的校验结果信息

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

使用校验步骤小结

  1. 方法参数上开启校验:@Valid 、 @Validated
  2. Bean的属性上设置校验规则:@NotBlank(message = “姓名不能为空”)
  3. 通过参数Errors获取错误信息
    • 获取所有错误:errors.getFieldErrors()
    • 获取错误字段:error.getField()
    • 获取错误提示:error.getDefaultMessage()
    • 将错误信息放置到model中显示给用户 -> JSP页面中${name}

1.3 多规则校验

同一个字段有多个约束条件,比如对于年龄的校验:

if (age !=null && age >18 && age < 60)

@NotNull(message = "请输入您的年龄")
@Max(value = 60,message = "年龄最大值不允许超过60岁")
@Min(value = 18,message = "年龄最小值不允许低于18岁")
private Integer age;//员工年龄

1.4 嵌套校验

引用类型字段如何校验,比如Employee中有address属性记录地址

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

1.在address属性上添加@Valid注解,开启嵌套属性校验

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

2.开启嵌套校验后,被校验对象内部需要添加对应的校验规则,并添加嵌套属性的get,set方法

//嵌套校验的实体中,对每个属性正常添加校验规则即可
public class Address {
    @NotBlank(message = "请输入省份名称")
    private String provinceName;//省份名称

    @NotBlank(message = "请输入城市名称")
    private String cityName;//城市名称

    @NotBlank(message = "请输入详细地址")
    private String detail;//详细住址

    @NotBlank(message = "请输入邮政编码")
    @Size(max = 6, min = 6, message = "邮政编码由6位组成")
    private String zipCode;//邮政编码
    
    //添加get,set方法
    
}
@PostMapping(value = "/addemployee")
public String addEmployee(@Valid Employee employee, Errors errors, Model m) {
    //Errors对象用于封装校验结果,如果不满足校验规则,对应的校验结果封装到该对象中,包含校验的属性名和校验不通过返回的消息
    //判定Errors对象中是否存在未通过校验的字段
    if (errors.hasErrors()) {
        //获取所有未通过校验规则的信息
        List<FieldError> fieldErrors = errors.getFieldErrors();
        for (FieldError error : fieldErrors) {
            //将校验结果信息添加到Model对象中,用于页面显示,后期实际开发中无需这样设定,返回json数据即可
            //name = 姓名不能为空 -> ${name}
            m.addAttribute(error.getField(), error.getDefaultMessage());
            //address.cityName = 请输入城市名称 -> ${requestScope['address.provinceName']}
            //m.addAttribute("address.provinceName", "请输入省份名称");
        }

        //el获取对象属性值
        Address address = new Address();
        address.setProvinceName("test省份不能为空");
        //${address.provinceName}
        m.addAttribute("address", address);

        //当出现未通过校验的字段时,跳转页面到原始页面,进行数据回显
        return "addemployee.jsp";
    }
    return "success.jsp";
}

3.在jsp页面中获取嵌套属性中的错误信息

${requestScope['address.cityName']}
<%--注意,引用类型的校验未通过信息不是通过对象进行封装的,直接使用对象名.属性名的格式作为整体属性字符串进行保存的,和使用者的属性传递方式有关,不具有通用性,仅适用于本案例--%>
省:<input type="text" name="address.provinceName"><span style="color:red">${requestScope['address.provinceName']}</span><br/>
市:<input type="text" name="address.cityName"><span
         style="color:red">${requestScope['address.cityName']}</span><br/>

3种判定空校验器的区别

String 选择@NotBlank,底层会调用"字符串".trim()清除前后空格

int, double 选择@NotNull,不能使用@NotBlank

数组选择@NotEmpty

1.5 分组校验

根据业务不同需要调整是否参与校验,比如同一个模块,新增和修改时校验规则是不一致的

解决方案:对不同种类的属性进行分组,在校验时可以指定参与校验的字段所属的组类别

2 SSM整合

2.1 整合流程简介

整合步骤分析:SSM(Spring+SpringMVC+MyBatis)

2.2 项目结构搭建

**Part0:**项目基础结构搭建

public interface UserDao {
    /**
     * 添加用户
     * @param user
     * @return
     */
    public boolean save(User user);

    /**
     * 修改用户
     * @param user
     * @return
     */
    public boolean update(User user);

    /**
     * 删除用户
     * @param uuid
     * @return
     */
    public boolean delete(Integer uuid);

    /**
     * 查询单个用户信息
     * @param uuid
     * @return
     */
    public User get(Integer uuid);

    /**
     * 查询全部用户信息
     * @return
     */
    public List<User> getAll();


    /**
     * 根据用户名密码查询个人信息
     * @param userName 用户名
     * @param password 密码信息
     * @return
     */
    //注意:数据层操作不要和业务层操作的名称混淆,通常数据层仅反映与数据库间的信息交换,不体现业务逻辑
    public User getByUserNameAndPassword(String userName,String password);
}
public interface UserService {
    /**
     * 添加用户
     * @param user
     * @return
     */
    public boolean save(User user);

    /**
     * 修改用户
     * @param user
     * @return
     */
    public boolean update(User user);

    /**
     * 删除用户
     * @param uuid
     * @return
     */
    public boolean delete(Integer uuid);

    /**
     * 查询单个用户信息
     * @param uuid
     * @return
     */
    public User get(Integer uuid);

    /**
     * 查询全部用户信息
     * @return
     */
    public List<User> getAll();

    /**
     * 根据用户名密码进行登录
     * @param userName
     * @param password
     * @return
     */
    public User login(String userName,String password);
}

2.3 Spring整合Mybatis(复习)

在pom.xml引入相关坐标

<dependencies>
    <!--spring+springmvc环境环境-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.1.9.RELEASE</version>
    </dependency>


    <!--mybatis环境-->
    <!--mybatis环境-->
    <!--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.47</version>
    </dependency>

    <!--spring整合jdbc-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.1.9.RELEASE</version>
    </dependency>

    <!--spring整合mybatis-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>2.0.3</version>
    </dependency>

    <!--druid连接池-->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.16</version>
    </dependency>

    <!--分页插件坐标-->
    <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper</artifactId>
      <version>5.1.2</version>
    </dependency>

    <!--jackson-->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.0</version>
    </dependency>


    <!--其他组件-->
    <!--junit单元测试-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>
    <!--spring整合junit-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>5.1.9.RELEASE</version>
    </dependency>
  </dependencies>

2.3.1 Spring整合Mybatis

  1. Spring环境配置:applicationContext.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"  xmlns:context="http://www.springframework.org/schema/context"  xmlns:tx="http://www.springframework.org/schema/tx"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  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">
    
        <!--开启bean注解扫描-->
        <context:component-scan base-package="com.ithe"/>
    
    </beans>
    
  2. MyBatis映射文件:UserDao.xml
    注意目录:resources\com\ithe\dao\UserDao.xml

    <?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.itheima.dao.UserDao">
    
        <!--添加-->
        <insert id="save" parameterType="user">
            insert into user(userName,password,realName,gender,birthday)values(#{userName},#{password},#{realName},#{gender},#{birthday})
        </insert>
    
        <!--删除-->
        <delete id="delete" parameterType="int">
            delete from user where uuid = #{uuid}
        </delete>
    
        <!--修改-->
        <update id="update" parameterType="user">
            update user set userName=#{userName},password=#{password},realName=#{realName},gender=#{gender},birthday=#{birthday} where uuid=#{uuid}
        </update>
    
        <!--查询单个-->
        <select id="get" resultType="user" parameterType="int">
            select * from user where uuid = #{uuid}
        </select>
    
        <!--分页查询-->
        <select id="getAll" resultType="user">
            select * from user
        </select>
    
        <!--登录-->
        <select id="getByUserNameAndPassword" resultType="user" >
            select * from user where userName=#{userName} and password=#{password}
        </select>
    
    </mapper>
    

    在UserDao中完成登录方法参数绑定:

    /**
     * 根据用户名密码查询个人信息
     *
     * @param userName 用户名
     * @param password 密码信息
     * @return
     */
    //注意:数据层操作不要和业务层操作的名称混淆,通常数据层仅反映与数据库间的信息交换,不体现业务逻辑
    public User getByUserNameAndPassword(
            @Param("userName") String userName,
            @Param("password") String password);
    
  3. 整合MyBatis到Spring环境中:applicationContext.xml

2.3.2 配置分页插件与事务

  1. 添加分页插件pagehelper坐标

    <!--分页插件坐标-->
    <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper</artifactId>
      <version>5.1.2</version>
    </dependency>
    
  2. 配置分页插件pagehelper:applicationContext.xml

    • -> setPlugins()
    • -> setProperties()
    <!--整合mybatis到spring中-->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="typeAliasesPackage" value="com.itheima.domain"/>
        <!--分页插件-->
        <property name="plugins">
            <array>
                <bean class="com.github.pagehelper.PageInterceptor">
                    <property name="properties">
                        <props>
                            <prop key="helperDialect">mysql</prop>
                            <!--pageNum<=0 时会查询第一页,pageNum>pageSize(超过总数时),会查询最后一页-->
                            <prop key="reasonable">true</prop>
                        </props>
                    </property>
                </bean>
            </array>
        </property>
    </bean>
    
  3. 在UserServiceImpl中完善分页查询

   @Override
   public PageInfo<User> getAll(int page, int size) {
       PageHelper.startPage(page, size);
       List<User> all = userDao.getAll();
       return new PageInfo<User>(all);
   }
  1. 添加事务管理:applicationContext.xml

    • 确认已添加tx命名空间

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:context="http://www.springframework.org/schema/context"
             xmlns:tx="http://www.springframework.org/schema/tx"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             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="txManager"/>
      
      <!--事务管理器-->
      <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
          <property name="dataSource" ref="dataSource"/>
      </bean>
      
    • 在Service类上或方法上添加@Transactional注解

      //类或接口上
      @Transactional(readOnly = true)
      
      //增删改方法上
      @Transactional(readOnly = false)
      

2.4 整合junit(复习)

测试环境使用单独的数据库配置:在test\resources放置一套applicationContext.xml和jdbc.properties

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class UserServiceTest {

@Autowired
    private UserService userService;

    @Test
    public void testSave(){
        User user = new User();
        user.setUserName("Jock");
        user.setPassword("root");
        user.setRealName("Jockme");
        user.setGender(1);
        user.setBirthday(new Date(333333000000L));

        userService.save(user);
    }

    @Test
    public void testDelete(){
        User user = new User();
        userService.delete(3);
    }

    @Test
    public void testUpdate(){
        User user = new User();
        user.setUuid(1);
        user.setUserName("Jockme");
        user.setPassword("root");
        user.setRealName("JockIsMe");
        user.setGender(1);
        user.setBirthday(new Date(333333000000L));

        userService.update(user);
    }

    @Test
    public void testGet(){
        User user = userService.get(1);
        System.out.println(user);
    }

    @Test
    public void testGetAll(){
        PageInfo<User> all = userService.getAll(2, 2);
        System.out.println(all);
        System.out.println(all.getList().get(0));
        System.out.println(all.getList().get(1));
    }

    @Test
    public void testLogin(){
        User user = userService.login("Jockme", "root");
        System.out.println(user);
    }
}

Spring整合MyBatis小结

在这里插入图片描述

2.5 Spring整合SpringMVC

在这里插入图片描述

2.5.1 Rest风格开发SpringMVC(复习)-视频08

**Part3:**配置SpringMVC,完成如下4个步骤:

  1. 在web.xml中配置DispatcherServlet,并加载spring-mvc.xml

    <?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/web-app_3_1.xsd"
             version="3.1">
    <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>
    
  2. 在spring-mvc.xml中配置只扫描com.ithe.controller包

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    
        <mvc:annotation-driven/>
    
        <context:component-scan base-package="com.ithe.controller"/>
    
    </beans>
    
  3. Spring的配置文件不加载controller:修改applicationContext.xml的包扫描,排除@Controller标记的类

    <!--开启bean注解扫描-->
    <context:component-scan base-package="com.itheima">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    
  4. 编写UserController

    @RestController
    @RequestMapping("/user")
    public class UserController {
    
        @PostMapping
        public boolean save(User user){
            System.out.println("save ..." + user);
            return true;
        }
    
        @PutMapping
        public boolean update(User user){
            System.out.println("update ..." + user);
            return true;
        }
    
        @DeleteMapping("/{uuid}")
        public boolean delete(@PathVariable Integer uuid){
            System.out.println("delete ..." + uuid);
            return true;
        }
    
        @GetMapping("/{uuid}")
        public User get(@PathVariable Integer uuid){
            System.out.println("get ..." + uuid);
            return null;
        }
    
        @GetMapping("/{page}/{size}")
        public List getAll(@PathVariable Integer page,@PathVariable Integer size){
            System.out.println("getAll ..." + page+","+size);
            return null;
        }
    
        @PostMapping("/login")
        public User login(String userName,String password){
            System.out.println("login ..." + userName + " ," +password);
            return null;
        }
    
    }
    

2.5.2 Spring整合SpringMVC

使用Spring时加载applicationContext.xml方式如下所示:

在这里插入图片描述

Part4:改为Web项目后,必须让tomcat启动时通过监听器加载Spring的配置文件:applicationContext.xml

  1. web.xml加载Spring配置文件

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:applicationContext.xml</param-value>
    </context-param>
    
    <!--启动服务器时,通过监听器加载spring运行环境-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
  2. Controller调用Service

    @RestController
    @RequestMapping("/user")
    public class UserController {
    
        @Autowired
        private UserService userService;
    
        @PostMapping
        public boolean save(User user){
            return userService.save(user);
        }
    
        @PutMapping
        public boolean update(User user){
            return userService.update(user);
        }
    
        @DeleteMapping("/{uuid}")
        public boolean delete(@PathVariable Integer uuid){
            return userService.delete(uuid);
        }
    
        @GetMapping("/{uuid}")
        public User get(@PathVariable Integer uuid){
            return userService.get(uuid);
        }
    
        @GetMapping("/{page}/{size}")
        public PageInfo<User> getAll(@PathVariable Integer page, @PathVariable Integer size){
            return userService.getAll(page,size);
        }
    
        @PostMapping("/login")
        public User login(String userName,String password){
            return userService.login(userName,password);
        }
    
    }
    

2.6 表现层数据封装(重点)

**Part5-1:**表现层数据封装

操作类型返回数据格式
操作是否成功true/false格式A
单个数据1, “zhangshan”格式B
对象数据json对象:{“name”:“Jock”,“age”:39}格式C
集合数据json数组:[{“name”:“Jock”,“age”:39},{“name”:“Jockme”,“age”:40}]格式D

下面进行表现层数据封装,分为如下4个步骤:

  1. 返回数据格式设计

  2. 编写返回数据封装类:Result,添加get,set方法

    public class Result {
        // 操作结果编码
        private Integer code;
        // 操作数据结果
        private Object data;
        // 消息
        private String message;
        
        
        //添加get,set方法
        
        public Result(Integer code) {
            this.code = code;
        }
        public Result(Integer code, Object data) {
            this.code = code;
            this.data = data;
        }
    
        public Result(Integer code, String message) {
            this.code = code;
            this.message = message;
        }
    }
    
  3. 状态码常量可以根据自己的业务需求设定

    public class Code {
    //    操作结果编码
        public static final Integer SAVE_OK = 20011;
        public static final Integer UPDATE_OK = 20021;
        public static final Integer DELETE_OK = 20031;
        public static final Integer GET_OK = 20041;
    
        public static final Integer SAVE_ERROR = 20010;
        public static final Integer UPDATE_ERROR = 20020;
        public static final Integer DELETE_ERROR = 20030;
        public static final Integer GET_ERROR = 20040;
    
    //    系统错误编码
    
    //    操作权限编码
    
    //    校验结果编码
    
    }
    
  4. Controller 调用

    @RestController
    @RequestMapping("/user")
    public class UserController {
    
        @Autowired
        private UserService userService;
    
        @PostMapping
        public Result save(User user){
            boolean flag = userService.save(user);
            return new Result(flag ? Code.SAVE_OK:Code.SAVE_ERROR);
        }
    
        @PutMapping
        public Result update(User user){
            boolean flag = userService.update(user);
            return new Result(flag ? Code.UPDATE_OK:Code.UPDATE_ERROR);
        }
    
        @DeleteMapping("/{uuid}")
        public Result delete(@PathVariable Integer uuid){
            boolean flag = userService.delete(uuid);
            return new Result(flag ? Code.DELETE_OK:Code.DELETE_ERROR);
        }
    
        @GetMapping("/{uuid}")
        public Result get(@PathVariable Integer uuid){
            User user = userService.get(uuid);
            return new Result(null != user ?Code.GET_OK: Code.GET_ERROR,user);
        }
    
        @GetMapping("/{page}/{size}")
        public Result getAll(@PathVariable Integer page, @PathVariable Integer size){
            PageInfo<User> all = userService.getAll(page, size);
            return new Result(null != all ?Code.GET_OK: Code.GET_ERROR,all);
        }
    
        @PostMapping("/login")
        public Result login(String userName,String password){
            User user = userService.login(userName,password);
            return new Result(null != user ?Code.GET_OK: Code.GET_ERROR,user);
        }
    
    }
    

2.7 自定义异常

**Part5-2:**自定义异常处理

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

    在自定义异常类中添加错误编码属性code以及get方法

    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;
        }
    }
    
  2. 自定义异常消息返回时需要与业务正常执行的消息按照统一的格式进行处理

    @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);
    }
    

2.8 返回消息兼容异常信息(重点)

在异常处理类中,将异常信息封装成Result对象:通过e.getCode()获取异常编码

@RestControllerAdvice
public class ProjectExceptionAdvice {

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

    @ExceptionHandler(Exception.class)
    public Result doOtherException(Exception e) {
        //redis发送真正的异常信息给运维人员e.getMessage()
        return new Result(500, "请稍候重试");
    }

}

3 纯注解开发SSM

需要使用注解改造的配置文件如下所示:

3.1 用注解代替UserDao.xml

使用MyBatis提供的注解在UserDao接口中改造

public interface UserDao {
    /**
     * 添加用户
     * @param user
     * @return
     */
    @Insert("insert into user(userName,password,realName,gender,birthday)values(#{userName},#{password},#{realName},#{gender},#{birthday})")
    public boolean save(User user);

    /**
     * 修改用户
     * @param user
     * @return
     */
    @Update("update user set userName=#{userName},password=#{password},realName=#{realName},gender=#{gender},birthday=#{birthday} where uuid=#{uuid}")
    public boolean update(User user);

    /**
     * 删除用户
     * @param uuid
     * @return
     */
    @Delete("delete from user where uuid = #{uuid}")
    public boolean delete(Integer uuid);

    /**
     * 查询单个用户信息
     * @param uuid
     * @return
     */
    @Select("select * from user where uuid = #{uuid}")
    public User get(Integer uuid);

    /**
     * 查询全部用户信息
     * @return
     */
    @Select("select * from user")
    public List<User> getAll();


    /**
     * 根据用户名密码查询个人信息
     * @param userName 用户名
     * @param password 密码信息
     * @return
     */
    @Select("select * from user where userName=#{userName} and password=#{password}")
    //注意:数据层操作不要和业务层操作的名称混淆,通常数据层仅反映与数据库间的信息交换,不体现业务逻辑
    public User getByUserNameAndPassword(@Param("userName") String userName,@Param("password") String password);
}

易错点:删除UserDao.xml

3.2 用注解替代applicationContext.xml

共分为如下3个步骤:

  1. 新建Druid数据源配置类:JdbcConfig

    public class JdbcConfig {
        //使用注入的形式,读取properties文件中的属性值,等同于<property name="*******" value="${jdbc.driver}"/>
        @Value("${jdbc.driver}")
        private String driver;
        @Value("${jdbc.url}")
        private String url;
        @Value("${jdbc.username}")
        private String userName;
        @Value("${jdbc.password}")
        private String password;
    
        //定义dataSource的bean,等同于<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        @Bean("dataSource")
        public DataSource getDataSource(){
            //创建对象
            DruidDataSource ds = new DruidDataSource();
            //手工调用set方法,等同于set属性注入<property name="driverClassName" value="******"/>
            ds.setDriverClassName(driver);
            ds.setUrl(url);
            ds.setUsername(userName);
            ds.setPassword(password);
            return ds;
        }
    }
    
  2. 新建MyBatis配置类:MyBatisConfig,添加分页插件pageHelper配置

    public class MyBatisConfig {
        //定义MyBatis的核心连接工厂bean,等同于<bean class="org.mybatis.spring.SqlSessionFactoryBean">
        @Bean
        //参数使用自动装配的形式加载dataSource,为set注入提供数据,dataSource来源于JdbcConfig中的配置
        public SqlSessionFactoryBean getSqlSessionFactoryBean(@Autowired DataSource dataSource,@Autowired Interceptor interceptor){
            SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
            //等同于<property name="typeAliasesPackage" value="com.ithe.domain"/>
            ssfb.setTypeAliasesPackage("com.ithe.domain");
            //等同于<property name="dataSource" ref="dataSource"/>
            ssfb.setDataSource(dataSource);
            ssfb.setPlugins(interceptor);
            return ssfb;
        }
    
        //定义MyBatis的映射扫描,等同于<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        @Bean
        public MapperScannerConfigurer getMapperScannerConfigurer(){
            MapperScannerConfigurer msc = new MapperScannerConfigurer();
            //等同于<property name="basePackage" value="com.ithe.dao"/>
            msc.setBasePackage("com.ithe.dao");
            return msc;
        }
    
        //分页插件pageHelper配置
        @Bean("pageInterceptor")
        public Interceptor getPageInterceptor(){
            Interceptor interceptor = new PageInterceptor();
            Properties properties = new Properties();
            properties.setProperty("helperDialect","mysql");
            properties.setProperty("reasonable","true");
            //等同于<property name="properties">
            interceptor.setProperties(properties);
            return interceptor;
        }
    
    }
    
  3. 新建Spring配置类:SpringConfig,完成事务管理配置

    @Configuration
    //等同于<context:component-scan base-package="com.itheima">
    @ComponentScan(value = "com.ithe",excludeFilters =
        //等同于<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
        @ComponentScan.Filter(type= FilterType.ANNOTATION,classes = {Controller.class}))
    //等同于<context:property-placeholder location="classpath*:jdbc.properties"/>
    @PropertySource("classpath:jdbc.properties")
    //等同于<tx:annotation-driven />,bean的名称默认取transactionManager
    @EnableTransactionManagement
    @Import({MyBatisConfig.class,JdbcConfig.class})
    public class SpringConfig {
        //等同于<bean id="txManager"/>
        @Bean("transactionManager")
        //等同于<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        public DataSourceTransactionManager getTxManager(@Autowired DataSource dataSource){
            DataSourceTransactionManager tm = new DataSourceTransactionManager();
            //等同于<property name="dataSource" ref="dataSource"/>
            tm.setDataSource(dataSource);
            return tm;
        }
    }
    

3.3 用注解替代spring-mvc.xml

在这里插入图片描述

3.4 用注解替代web.xml

  1. 新建Servlet容器初始化配置类:ServletContainersInitConfig

    public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
    
        //创建Servlet容器时,使用注解的方式加载SPRINGMVC配置类中的信息,并加载成WEB专用的ApplicationContext对象
        //该对象放入了ServletContext范围,后期在整个WEB容器中可以随时获取调用
        @Override
        protected WebApplicationContext createServletApplicationContext() {
            AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
            ctx.register(SpringMvcConfig.class);
            return ctx;
        }
    
        //注解配置映射地址方式,服务于SpringMVC的核心控制器DispatcherServlet
        @Override
        protected String[] getServletMappings() {
            return new String[]{"/"};
        }
    
        //乱码处理作为过滤器,在servlet容器启动时进行配置,相关内容参看Servlet零配置相关课程
        @Override
        public void onStartup(ServletContext servletContext) throws ServletException {
            //触发父类的onStartup
            super.onStartup(servletContext);
            //1.创建字符集过滤器对象
            CharacterEncodingFilter cef = new CharacterEncodingFilter();
            //2.设置使用的字符集
            cef.setEncoding("UTF-8");
            //3.添加到容器(它不是ioc容器,而是ServletContainer)
            FilterRegistration.Dynamic registration = servletContext.addFilter("characterEncodingFilter", cef);
            //4.添加映射
            registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE), false, "/*");
            
            
            //使用隐藏域设置请求方式
            //指定form表单请求方式为DELETE: <input type="text" name="_method" value="DELETE"/>
            //HiddenHttpMethodFilter httpMethodFilter = new HiddenHttpMethodFilter();
            //FilterRegistration.Dynamic httpMethodFilterRegistration =
            //        servletContext.addFilter(
            //        "hiddenHttpMethodFilter", cef);
            //httpMethodFilterRegistration.addMappingForServletNames(
            //        EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE),
            //        false,
            //        getServletName());
        }
    }
    
  2. 添加加载spring核心配置文件,生成Spring核心容器(主容器/父容器/根容器)

    @Override
    //基本等同于<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    protected WebApplicationContext createRootApplicationContext() {
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringConfig.class);
        return ctx;
    }
    
  1. 添加加载spring核心配置文件,生成Spring核心容器(主容器/父容器/根容器)

    @Override
    //基本等同于<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    protected WebApplicationContext createRootApplicationContext() {
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringConfig.class);
        return ctx;
    }
    

标签:...,return,uuid,SpringMVC,Spring,校验,user,JSR,public
来源: https://blog.csdn.net/qq_45181415/article/details/114900723