SpringBoot的基本概念

在传统的SSM框架使用过程中,存在大量的配置,且这些配置基本上都是高度相似的,SpringBoot框架在配置方面做了大量的简化,本质上可以将它理解为默认集成了多个框架的综合体,却不怎么需要配置。

创建SpringBoot项目

访问https://start.spring.io/,配置项目的相关信息,然后生成项目,生成后,会自动下载项目的压缩包,将解压得到的文件夹移动到Workspace中,然后,通过Eclipse的**Import**功能导入**Existing Maven Projects**,修改**pom.xml**中的版本为`2.1.3`,如果项目没有开始自动更新,则对项目点右键,选择**Maven** > **Update Project**,在弹出的对话框中,勾选**Force update ...**然后开始更新,并等待更新结束即可。

注意:推荐使用Eclipse Oxygen 2以上版本,如果使用的版本较低,例如使用Mars系列的版本,在pom.xml中可能会提示错误,原因是maven的相关配置的版本较低,该错误可以无视,不影响正常运行。

若在选择依赖时添加了数据库和持久层依赖,则需要在**src/main/resources/application.properties**文件中进行配置:

spring.datasource.url=jdbc:mysql://localhost:3306/tedu_ums?useUnicode=true&characeterEncoding=utf-8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root
mybatis.mapper-locations=classpath:mappers/*.xml

(mybatis.mapper-locations=XML映射文件的位置)

 

启动SpringBoot项目

导入完成的项目中,默认就已经存在创建时配置的包,例如`cn.tedu.springboot`,该包是项目的根包,SpringBoot不需要配置组件扫描,默认就扫描这个根包,所以,在项目中创建的任何组件类都必须在这个根包或其子孙包中。

若要修改或添加组件扫描的位置,可以在SpringBoot的启动类中的@SpringBootApplication中显示的给scanBasePackages属性赋值:

//scanBasePackages:该属性是一个字符串数组类型的,可以添加多个包
@SpringBootApplication(scanBasePackages= {"cn.tedu.springboot"})

在根包下,默认就存在例如`SpringbootApplication`类,该类名是根据创建项目时的参数决定的,该类是SpringBoot的启动类,当需要启动项目时,直接运行该类中的`main()`即可。

SpringBoot项目内置了Tomcat,并且在启动时就会将项目部署到内置的Tomcat中,该Tomcat默认也是使用**8080**端口的,所以,务必保证端口不冲突!

 

单元测试

在**src/test/java**下,默认已经存在根包及单元测试类,且测试类中有1个空的测试方法:

@RunWith(SpringRunner.class)
	@SpringBootTest
	public class SpringbootApplicationTests {
	
		@Test
		public void contextLoads() {
		}
	
	}

首先,应该执行该空测试方法,如果整个执行过程中没有报告任何错误,则表示当前环境是正确的,相关jar包是完整的。

SpringBoot项目中,执行单元测试时,也会加载整个环境,例如加载Spring环境,所以,可以通过自动装配的方式获取数据源对象,然后执行获取连接:

@Autowired
	private DataSource dataSource;	
	@Test
	public void getConnection() throws SQLException {
		Connection conn = dataSource.getConnection();
		System.err.println(conn);//如果能正常输出显示连接对象,则表示关于数据库连接的配置信息是正确的!
	}

 

开发持久层

在SpringBoot项目中,依然使用与MyBatis开发时完全相同的方式进行处理。

可以先创建持久层接口`cn.tedu.springboot.mapper.UserMapper`,为了使得框架能知道接口在哪里,可以为接口添加`@Mapper`注解:

@Mapper
	public interface UserMapper {
	
		Integer addnew(User user);
		
	}

通常,并不推荐使用这样的方式配置接口文件的位置,更推荐的是在启动类之前添加@MapperScan("cn.tedu.springboot.mapper")注解配置: 

@SpringBootApplication
	@MapperScan("cn.tedu.springboot.mapper")
	public class SpringbootApplication {
	
		public static void main(String[] args) {
			SpringApplication.run(SpringbootApplication.class, args);
		}
	
	}

使用了`@MapperScan`注解后,就不必在每个接口之前添加`@Mapper`注解了。接下来,和此前的MyBatis开发步骤相同,配置XML映射。 

然后,需要在application.properties中添加配置,以确定XML映射文件的位置:

mybatis.mapper-locations=classpath:mappers/*.xml

 

开发业务层

在完整的服务器端数据处理流程中,应该有业务层,它的主要作用是设计业务流程和业务逻辑,从而保障数据安全,即数据是根据开发人员所设定的规则而产生或发生变化或访问的。

在编写代码时,应该先创建业务层的接口,例如创建`cn.tedu.springboot.service.IUserService`,并在该接口中添加抽象方法。

在设计抽象方法时,仅以操作成功为前提来设计方法的返回值,操作失败创建异常对象添加异常信息并抛出。

然后,创建`cn.tedu.springboot.service.UserServiceImpl`业务层实现类,实现以上`IUserService`接口,该类的对象是需要被Spring进行管理的,所以需要添加`@Service`注解。在类中,将调用持久层开发的方法来完成数据的验证及最终插入用户数据,所以,还需要声明`@Autowired private UserMapper userMapper;`持久层对象:

@Service
	public class UserServiceImpl implements IUserService {
		
		@Autowired
		private UserMapper userMapper;
        
            @Override
	    public void register(User user) {
		    // 根据参数user获取尝试注册的用户名,并根据用户名查询数据
		    String username = user.getUsername();
		    User result = userMapper.findByUsername(username);
		    // 判断查询结果是否为null
		    if (result == null) {
		    // 是:用户名未被占用,允许注册
			userMapper.addnew(user);
		    } else {
			    // 否:用户名已经被占用,不允许注册,抛出异常
			    throw new IllegalArgumentException("用户名(" + username + ")已经被占用!");
		    }
	    }
	
	}

 

访问SpringMVC的控制器

如果需要响应JSON数据,依然需要自定义响应结果的类型,例如创建`JsonResult`类,然后将方法的返回值类型声明为该类型即可,在SpringBoot中默认已经添加了Jackson相关依赖,并完成了相关配置,所以,直接使用即可。

在SpringBoot项目中,处理SpringMVC框架相关内容时,默认已经配置好了`DispatcherServlet`,且映射的路径是`/*`,所以,在设计URL时,控制器相关资源不需要使用`.do`作为后缀,甚至SpringBoot项目推荐使用RESTful的API风格,根本就不推荐使用任何后缀。

然后,需要创建cn.tedu.springboot.controller.UserController类,在类之前添加@RestController和@RequestMapping("user"),并在类中添加处理请求的方法:

@RequestMapping("user")
@RestController
public class UserController {
	
	@RequestMapping("handle_register")
	public JsonResult<Void> handleRegister(User user) {
		System.err.println("UserController.handleRegister()");
		System.err.println("\t" + user);
		
		JsonResult<Void> jr = new JsonResult<Void>();
		
		try {
			userService.register(user);
			jr.setState(1);
		} catch (IllegalArgumentException e) {
			jr.setState(2);
			jr.setMessage(e.getMessage());
		}
		
		return jr;
	}
		
}

> @RestController注解相关于@Controller和@ResponseBody的组合使用,只不过该注解是添加在控制器类之前的,使得该控制器类中所有处理请求的方法都是响应正文的!

> SpringBoot项目默认并不支持使用jsp,如果一定需要使用jsp,还需要另外添加依赖!

 

显示前端页面

在SpringBoot项目中,在**src/main/resources**下默认已经存在**static**文件夹,该文件夹就是用于存放静态资源的文件夹,例如用于存放html、css、js、图片文件等。

SpringBoot建议将静态资源存放在static中。

 

Interceptor拦截器的配置

创建一个配置类,实现WebMvcConfigurer接口,添加@Configuration注释,重写addInterceptors方法,在该方法中配置拦截器及其拦截的地址:

@Configuration
public class LoginConfigurer implements WebMvcConfigurer {
	 @Override
	 public void addInterceptors(InterceptorRegistry registry) {
        //白名单集合
        List<String> patterns = new ArrayList<String>();
        patterns.add("/web/login.html");
        patterns.add("/user/login");
        patterns.add("/web/reg.html");
        patterns.add("/user/reg");
       
        // 若有多个拦截器,多次执行这个方法
        // registry.addInterceptor(拦截器对象)..addPathPatterns("/**");    
        // 拦截器的执行顺序与此处添加顺序一致
        registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**")
                .excludePathPatterns(patterns);
	 }
	 
}

Controller层,处理器方法返回JSON数据时忽略null值不发送:

1.在Json类声明上方加@JsonInclude(JsonInclude.Include.NON_NULL)注解或@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)注解

,该方法只作用与该类中的属性,属性中的属性为null时不起作用

2.在属性声明的上方加@JsonInclude(JsonInclude.Include.NON_NULL)注解,只作用与该属性

3.在application.properties配置文件中添加spring.jackson.default-property-inclusion=non_null,对所有属性起作用