SpringMVC学习笔记三:SSM整合

前后端协议整合

Spring+SpringMVC+MyBatis架构搭建

引入相关的jar包

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-webmvc</artifactId>
	<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-jdbc</artifactId>
	<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-test</artifactId>
	<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.mybatis</groupId>
	<artifactId>mybatis</artifactId>
	<version>3.5.6</version>
</dependency>
<dependency>
	<groupId>org.mybatis</groupId>
	<artifactId>mybatis-spring</artifactId>
	<version>1.3.0</version>
</dependency>
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>5.1.47</version>
</dependency>
<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>druid</artifactId>
	<version>1.1.16</version>
</dependency>
<dependency>
	<groupId>junit</groupId>
	<artifactId>junit</artifactId>
	<version>4.12</version>
	<scope>test</scope>
</dependency>
<dependency>
	<groupId>javax.servlet</groupId>
	<artifactId>javax.servlet-api</artifactId>
	<version>3.1.0</version>
	<scope>provided</scope>
</dependency>
<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-databind</artifactId>
	<version>2.9.0</version>
</dependency>

引入Tomcat插件

<plugins>
	<plugin>
		<groupId>org.apache.tomcat.maven</groupId>
		<artifactId>tomcat7-maven-plugin</artifactId>
		<version>2.1</version>
		<configuration>
			<port>80</port>
			<path>/</path>
		</configuration>
	</plugin>
</plugins>

创建各层文件夹

  1. config文件夹用于放置配置类
  2. daodaomain用于放置数据层各种接口和类
  3. controller文件夹用于放置表现层各种类
  4. service用于放置业务层各种类
  5. test用于放置测试类
  6. resource 用于放置一些配置文件
  7. webapp用于放置网页资源
  8. 其他自定义类文件夹
    image

配置Spring配置类

@Configuration	//配置类注解
@ComponentScan({"service"})		//扫描注解服务层文件夹
@PropertySource({"classpath:jdbc.properties"})	//调用jdbc的配置文件
@Import({JdbcConfig.class,MyBatisConfig.class})	//导入jdbc配置类、MyBatispei
@EnableTransactionManagement	//开启事务管理器
public class SpringConfig {
}
  1. jdbc配置文件:用于连接数据库
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm_db
jdbc.username=root
jdbc.password=1234
  1. jdbc配置类
public class JdbcConfig {
	//通过@Value将外部配置文件的值动态注入
	@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
	public DataSource dataSource(){
		DruidDataSource dataSource = new DruidDataSource();
		dataSource.setDriverClassName(driver);
		dataSource.setUrl(url);
		dataSource.setUsername(username);
		dataSource.setPassword(password);
		return dataSource;
	}
	//创建一个事务平台管理的Bean
	@Bean
	public PlatformTransactionManager transactionManager(DataSource dataSource){
		DataSourceTransactionManager ds = new DataSourceTransactionManager();
		ds.setDataSource(dataSource);
		return ds;
	}
}
  1. 创建MyBatis配置类
public class MyBatisConfig {
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource);
        factoryBean.setTypeAliasesPackage("domain");
        return factoryBean;
    }
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(){
        MapperScannerConfigurer msc = new MapperScannerConfigurer();
        msc.setBasePackage("dao");
        return msc;
    }
}

配置SpringMVC配置类

@Configuration
@ComponentScan({"controller","config"})//扫描业务层,以及配置层(如果内部设有多个扫描要注意排除项是否被覆盖)
@EnableWebMvc	//开启web资源转换
public class SpringMvcConfig {

}

配置servelt容器

public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer{
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{SpringConfig.class};
    }

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

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};	//拦截一切发送的资源
    }
}
  1. 如果想要一些静态资源不被拦截,创建配置类设置
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
	@Override
	protected void addResourceHandlers(ResourceHandlerRegistry registry) {
		//如果拦截的请求为->localhost/pages/**,则直接调用web/pages/文件夹下的资源
		registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
		registry.addResourceHandler("/js/**").addResourceLocations("/js/");
		registry.addResourceHandler("/css/**").addResourceLocations("/css/");
		registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
	}
}

表现层的数据层模型封装

  1. 增删改都返回统一的数据类型data
  2. 不同的功能和查询成功与否使用code
  3. 操作失败没有结果,返回信息使用message
//创建一个结果类,用于前端数据分析
public class Result{
	private Object data;
	private Integer code;
	private String message;
	//根据实际需求可以进行增删
}
//状态码枚举
```java
public class Code {
    public static final Integer SAVE_OK = 20011;
    public static final Integer DELETE_OK = 20021;
    public static final Integer UPDATE_OK = 20031;
    public static final Integer GET_OK= 20041;

    public static final Integer SAVE_ERR = 20010;
    public static final Integer DELETE_ERR = 20020;
    public static final Integer UPDATE_ERR = 20030;
    public static final Integer GET_ERR = 20040;

    public static final Integer RESULT_Exception = 20000;

}
//前端控制器类
@RestController
@RequestMapping("/books")
public class BookController {
    @Autowired
    private BookService bookService;

    @PostMapping
    public Result save(@RequestBody Book book) {
        boolean flag = bookService.save(book);
        return new Result(flag?Code.SAVE_OK:Code.SAVE_ERR,flag);
    }

    @PutMapping
    public Result update(@RequestBody Book book) {
        boolean flag = bookService.update(book);
        return new Result(flag?Code.UPDATE_OK:Code.UPDATE_ERR,flag);
    }

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

    @GetMapping("/{id}")
    public Result getById(@PathVariable Integer id) {
        int i =1/0;
        Book book = bookService.getById(id);
        Integer code = book!=null? Code.GET_OK:Code.GET_ERR;
        String message = book!=null? "":"查询失败";
        return new Result(code,book,message);
    }

    @GetMapping
    public Result getAll() {
        List<Book> list = bookService.getAll();
        Integer code = list!=null? Code.GET_OK:Code.GET_ERR;
        String message = list!=null? "":"查询失败";
        return new Result(code,list,message);
    }
}

image

异常处理的封装

封装抛出异常的格式:
当程序出现问题的时候,抛出到前端显示的是一连串的错误输出,不利于格式整合
异常的处理应放在表现层:
因为异常会应为各种原因,在表现层,数据层,业务层产生各种异常,为了方面处理,统一将异常上抛,汇聚到表现层进行统一捕捉处理
使用AOP方式对异常进行处理:
在不改变源代码的情况,以及不能在不同方法中都在最初写入异常处理机制,而且会出现大量的重复代码,使用AOP方式可以较好的处理

异常处理器

//在表现层定义一个异常处理器
//配置异常处理器
@RestControllerAdvice
public class ProjectExceptionAdvice {
	//想要捕获的异常类型
	@ExceptionHandler(Exception.class)
	public Result doException(Exception e){
		System.out.println("捕获成功");
		return new Result(Code.RESULT_Exception,null,"程序出现异常");
	}
}

image

异常处理方案

项目异常分类

  • 业务异常
    • 规范的用户行为产生的异常
    • 规范的用户行为产生的异常
  • 系统异常
    • 项目运行过程中可预计且无法避免的异常
  • 其他异常
    • 编程人员未预期到的异常

项目异常处理方案

  • 业务异常
    • 发送对应消息传递给用户,提醒规范操作
  • 系统异常
    • 发送规定消息传递给用户,安抚用户
    • 发送特定消息给运维人员,提醒维护
    • 记录日志
  • 其他异常
    • 发送规定消息传递给用户,安抚用户
    • 发送特消息给编程人员,提醒维护
    • 记录日志
      异常处理机制
  • 自定义项目系统级异常
  • 自定义项目业务级异常
  • 自定义异常编码
  • 触发异常
  • 拦截并处理异常
//继承运行时异常
public class BusinessException extends RuntimeException{
	private Integer code;

	public Integer getCode() {
		return code;
	}
	//自定义异常构造器
	public BusinessException(Integer code, String message) {
		super(message);
		this.code = code;
	}

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


}

@RestControllerAdvice
public class ProjectExceptionAdvice {
	//想要捕获的异常类型
	@ExceptionHandler(BusinessException.class)
	public Result doException(BusinessException e){
		System.out.println("捕获成功");
		return new Result(e.getCode(),null,e.getMessage());
	}
	@ExceptionHandler(SystemException.class)
	public Result doException(SystemException e){
		System.out.println("捕获成功");
		return new Result(e.getCode(),null,e.getMessage());
	}
}

标准开发

image

posted @ 2022-07-13 15:49  小懒虫LK  阅读(29)  评论(0编辑  收藏  举报