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,对所有属性起作用