深度解析SpringMVC——SSM整合

发布于:2023-01-25 ⋅ 阅读:(566) ⋅ 点赞:(0)

包层次结构
在这里插入图片描述

一、整合配置

Spring配置类

package com.GY.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;

@Configuration
@ComponentScan("com.GY.service")
@PropertySource("jdbc.properties")
@Import({JdbcConfig.class,MybatisConfig.class})
public class SpringConfig {
}

SpringMVC配置类

package com.GY.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

@Configuration
@ComponentScan("com.GY.controller")
@EnableWebMvc
public class SpringmvcConfig {
}

Jdbc配置类

package com.GY.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;

public class JdbcConfig {
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String name;
    @Value("${jdbc.password}")
    private String password;


    @Bean
    public DataSource dataSource(){
        DruidDataSource dataSource=new DruidDataSource();
        dataSource.setDriverClassName(driver);
        dataSource.setUrl(url);
        dataSource.setUsername(name);
        dataSource.setPassword(password);
        return dataSource;
    }
}

MyBatis配置类

package com.GY.config;

import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;

public class MybatisConfig {
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
        SqlSessionFactoryBean S=new SqlSessionFactoryBean();
        S.setDataSource(dataSource);
        S.setTypeAliasesPackage("com.GY.domain");
        return S;
    }

    //扫描映射
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(){
        MapperScannerConfigurer M=new MapperScannerConfigurer();
        M.setBasePackage("com.GY.dao");
        return  M;
    }
}

Web容器配置类

package com.GY.config;

import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import javax.servlet.Filter;


public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {


    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{SpringConfig.class};
    }

    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringmvcConfig.class};
    }

    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    //当有表单提交需求时乱码可设置过滤器
    protected Filter[] getServletFilters(){
        CharacterEncodingFilter filter=new CharacterEncodingFilter();
        filter.setEncoding("UTF-8");
        return new Filter[]{filter};
    }
}

二、功能模块开发

POJO封装对象
在这里插入图片描述

数据层接口

package com.GY.dao;

import com.GY.domain.User;
import org.apache.ibatis.annotations.*;
import java.util.List;


public interface UserDao {

    @Insert("insert into user values (#{id},#{name},#{money})")
    void save(User user);

    @Delete("delete from user where id=#{id}")
    void delete(Integer id);

    @Update("update user set name=#{name},money=#{money} where id=#{id}")
    void update(User user);

    @Select("select * from user where id=#{id};")
    User  getById(Integer id);

    @Select("select * from user")
    List<User> getAll();
}

业务层接口

package com.GY.service;

import com.GY.domain.User;
import java.util.List;

public interface UserService {

    //保存
    boolean save(User user);

    //根据id删除
    boolean delete(Integer id);

    //修改
    boolean update(User user);

    //根据id查询
    User  getById(Integer id);

    //查询全部
    List<User> getAll();
}

业务层实现类

package com.GY.service.Impl;

import com.GY.dao.UserDao;
import com.GY.domain.User;
import com.GY.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;


    public boolean save(User user) {
        userDao.save(user);
        return true;
    }

    public boolean delete(Integer id) {
        userDao.delete(id);
        return true;
    }

    public boolean update(User user) {
        userDao.update(user);
        return true;
    }
    public User  getById(Integer id){
        return userDao.getById(id);
    }

    public List<User> getAll() {
        return userDao.getAll();
    }
}

基于Restful的Controller控制器类开发

package com.GY.controller;

import com.GY.domain.User;
import com.GY.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;

@RestController
@RequestMapping("/users")

public class UserController {
    @Autowired
    private UserService userService;

    @PostMapping
    public boolean save(@RequestBody User user) {
        return  userService.save(user);
    }

    @DeleteMapping("/{id}")
    public boolean delete(@PathVariable Integer id) {
        return userService.delete(id);
    }

    @PutMapping
    public boolean update(@RequestBody User user) {
        return  userService.update(user);
    }

    @GetMapping("/{id}")
    public User  getById(@PathVariable Integer id){
        return userService.getById(id);
    }

    @GetMapping
    public List<User> getAll() {
        return userService.getAll();
    }
}

三、接口测试

业务层接口测试

import com.GY.config.SpringConfig;
import com.GY.domain.User;
import com.GY.service.UserService;
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;

import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class UserTest {
    @Autowired
    private UserService userService;
    @Test
    public void testById(){
       User user= userService.getById(1);
        System.out.println(user);
    }
    @Test
    public  void tsetGetAll(){
        List<User> All = userService.getAll();
        System.out.println(All);
    }
}

测试成功
在这里插入图片描述
表现层接口测试
查询全部
在这里插入图片描述
添加
在这里插入图片描述
再次查询发现添加操作成功在这里插入图片描述
🎊🎊🎊
由此说明我们的接口均可正常实现

四、表现层与前端数据传输协议实现

表现层数据封装

● 前端接收数据格式

🚸🚸🚸
问题】前端接收数据格式多种多样,数据无法解析
在这里插入图片描述
此时,便需要对接收的数据统一格式
在这里插入图片描述

设置统一数据返回结果类
(data:数据) ( code:编码) (msg:消息)
在这里插入图片描述

● 前端接收数据模型实现

数据返回结果类(Result类)
在这里插入图片描述

设置统一数据返回结果编码(Code类)

package com.GY.controller;

public class Code {
    public  static final Integer SAVE_OK=11;
    public  static final Integer DELETE_OK=21;
    public  static final Integer UPDATE_OK=31;
    public  static final Integer GET_OK=41;

    public  static final Integer SAVE_ERR=10;
    public  static final Integer DELETE_ERR=20;
    public  static final Integer UPDATE_ERR=30;
    public  static final Integer GET_ERR=40;
}

表现层封装数据(根据情况设定合理的Result)

package com.GY.controller;

import com.GY.domain.User;
import com.GY.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/users")

public class UserController {
    @Autowired
    private UserService userService;

    @PostMapping
    public Result save(@RequestBody User user) {
       boolean flag=userService.save(user);
        return new Result(flag?Code.SAVE_OK:Code.SAVE_ERR,flag) ;
    }

    @DeleteMapping("/{id}")
    public Result delete(@PathVariable Integer id) {
        boolean flag=userService.delete(id);
        return new Result(flag?Code.DELETE_OK:Code.DELETE_ERR,flag);
    }

    @PutMapping
    public Result update(@RequestBody User user) {
        boolean flag=userService.update(user);
        return new Result(flag?Code.UPDATE_OK:Code.UPDATE_ERR,flag);
    }

    @GetMapping("/{id}")
    public Result  getById(@PathVariable Integer id){
        User user=userService.getById(id);
      Integer code=user!=null?Code.GET_OK:Code.GET_ERR;
      String msg=user!=null?"":"数据查询失败,请重试";
        return new Result(code,user,msg);
    }

    @GetMapping
    public Result getAll() {
        List<User> user=userService.getAll();
        Integer code=user!=null?Code.GET_OK:Code.GET_ERR;
        String msg=user!=null?"":"数据查询失败,请重试";
        return  new Result(code,user,msg);
    }
}

Apifox中模拟数据请求
eg: ①模拟添加数据业务
在这里插入图片描述

eg: ①模拟查询全部数据业务
在这里插入图片描述

五、异常处理器

程序开发过程中不可避免的会遇到异常现象
在这里插入图片描述

● 出现异常现象的常见位置与常见诱因
① 框架内部抛出异常:因使用不合规导致
② 数据层抛出的异常:因外部服务器故障导致(例如:服务器访问超时)
③ 业务层抛出的异常:因业务逻辑书写错误导致(例如:遍历业务书写操作,导致索引异常等)
④ 表现层抛出的异常:因数据收集、校验等规则导致(例如:不匹配的数据类型间导致异常)
⑤ 工具类抛出的异常:因工具类书写不严谨不够健壮导致(例如:必要释放的连接长期未释放等)

思考
1、各个层级均出现异常,异常处理代码书写在哪一层

——所有的异常均抛出到表现层进行处理

2、表现层处理异常,每个方法中单独书写,代码书写量巨大且意义不强,如何解决
——AOP思想
总结:异常要分类处理;异常要放到表现层处理;异常要使用AOP的思想来处理

项目异常分类

业务异常(BusinessException)

不规范的用户行为操作产生的异常
在这里插入图片描述

规范的用户行为产生的异常
在这里插入图片描述处理方案 发送对应消息传递给用户,提醒规范操作

系统异常(SystemException)

项目运行过程中可预计且无法避免的异常
eg: 服务器宕机、中央服务器出现问题等… .
在这里插入图片描述
处理方案
◆ 发送固定消息传递给用户,安抚用户
◆ 发送特定消息给运维人员,提醒维护
◆ 记录日志

其他异常(Exception)

编程人员未预期到的异常
在这里插入图片描述
处理方案
◆ 发送固定消息传递给用户,安抚用户
◆ 发送特定消息给编程人员,提醒维护(纳入预期范围内)
◆ 记录日志

在这里插入图片描述

项目异常处理方案

◆集中的、统一的处理项目中的异常
自定义项目业务/系统级异常
eg:
在这里插入图片描述
在这里插入图片描述

模拟业务异常(触发自定义异常)
在这里插入图片描述

异常处理器(拦截并处理异常)

package com.GY.controller;

import com.GY.exception.BusinessException;
import com.GY.exception.SystemException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

//声明此类用来做异常处理(Rest风格)
@RestControllerAdvice
public class ProjectExceptionAdvice {

    //拦截哪种异常:业务异常
    @ExceptionHandler(SystemException.class)
    public  Result doSystemException(SystemException e){
        //记录日志
        // 发送消息给运维
        //发送邮件给开发人员
        return new Result(e.getCode(),null,e.getMessage());
    }

    //系统异常
    @ExceptionHandler(BusinessException.class)
    public  Result doBusinessException(BusinessException e){
        return new Result(e.getCode(),null,e.getMessage());
    }

    //处理其他异常
    @ExceptionHandler(Exception.class)
    public Result doException(Exception e){
        return new Result(Code.UNKNOW_ERR,"系统繁忙,请稍后重试!");
    }
}

异常处理成功
在这里插入图片描述

本文含有隐藏内容,请 开通VIP 后查看