Spring MVC
框架主要解决了接收请求、响应结果、统一处理异常的相关问题,接收请求、响应结果是通过Controller
类处理的
Spring MVC
框架的依赖项:spring-webmvc
在Spring Boot
项目中,使用Spring MVC
框架应该添加依赖项:spring-boot-starter-web
当添加以上依赖项后,启用项目时,会自动将项目部署到内置的Tomcat,并启用Tomcat,默认占用8080端口,可在配置文件中,可以通过server.port
属性指定服务端口号,例如:
server:
port: 9080
开发Controller层时,至少需要:
Service
处理请求Knife4j
框架,生成在线API文档Knife4
j的API文档显示的文本Spring Validation
检验请求参数在满足基础理论情况下以查询为主的用GET
,增删改使用POST
,设计敏感数据的使用POST
,如登录查询用户名和密码
http client
进行测试,测试会变得很麻烦,比如,启动速度慢,测试验证不方便,依赖网络环境等,所以为了对Controller进行测试,引入MockMVC
MockMvc
实现了对Http
请求的模拟,能够直接使用网络的形式,转换到Controller
的调用,这样可以使得测试速度快、不依赖网络环境,而且提供了一套验证的工具,这样可以使得请求的验证统一而且很方便@Test
@Sql(scripts = {"classpath:/sql/truncate_tag.sql"})
@Sql(scripts = "classpath:/sql/truncate_tag.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
void addNew() throws Exception {
String url = "/content/tags/add-new";
String name = "新增标签类别";
String enable = "1";
String sort = "88";
mockMvc.perform(MockMvcRequestBuilders.post(url) // 请求方式 + 请求路径(不用虚拟路径)
// 携带表单信息
.param("name", name)
.param("enable", enable)
.param("sort", sort)
//接收 响应内容类型
.accept(MediaType.APPLICATION_JSON))
//断言:判断状态码 status().isBadRequest():400错误请求 status().isOk():正确 status().isNotFound():验证控制器不存在
.andExpect(MockMvcResultMatchers.status().isOk())
//追加 控制台打印出请求体
.andDo(MockMvcResultHandlers.print()
);
}
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
public GlobalExceptionHandler() {
log.info("创建全局异常处理器对象 GlobalExceptionHandler");
}
@ExceptionHandler
public JsonResult handleException(ServiceException e) {
log.debug("全局异常处理器开始处理ServiceException异常");
return JsonResult.fail(e.getServiceCode(), e.getMessage());
}
}
/**
* 业务异常
*/
public class ServiceException extends RuntimeException {
@Getter
private ServiceCode serviceCode;
public ServiceException(ServiceCode serviceCode, String message) {
super(message);
this.serviceCode = serviceCode;
}
}
@ExceptionHandler
public JsonResult handleThrowable(Throwable e) {
log.debug("全局异常处理器开始处理Throwable");
log.debug("异常跟踪信息如下:", e);
String message = "服务器忙,请稍后再试!【看到这句时,你应该检查服务器端的控制台,并在全局异常处理器中添加处理异常的方法】";
return JsonResult.fail(ServiceCode.ERROR_UNKNOWN, message);
}
关于统一异常详情可查看这篇文章Java阶段二Day22
向pom.xml
导入依赖
<dependency>
<groupId>com.github.xiaoymingroupId>
<artifactId>knife4j-spring-boot-starterartifactId>
<version>2.0.9version>
dependency>
Knife4jConfiguration
模板
import com.github.xiaoymin.knife4j.spring.extension.OpenApiExtensionResolver;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
/**
* Knife4j配置类
*
*/
@Slf4j
@Configuration
@EnableSwagger2WebMvc
public class Knife4jConfiguration {
/**
* 【重要】指定Controller包路径
*/
private String basePackage = "指定Controller包路径";
/**
* 主机名
*/
private String host = "主机名";
/**
* 标题
*/
private String title = "标题";
/**
* 简介
*/
private String description = "简介";
/**
* 服务条款URL
*/
private String termsOfServiceUrl = "服务条款URL";
/**
* 联系人
*/
private String contactName = "联系人";
/**
* 联系网址
*/
private String contactUrl = "联系网址";
/**
* 联系邮箱
*/
private String contactEmail = "联系邮箱";
/**
* 版本号
*/
private String version = "版本号";
@Autowired
private OpenApiExtensionResolver openApiExtensionResolver;
public Knife4jConfiguration() {
log.debug("创建配置类对象:Knife4jConfiguration");
}
@Bean
public Docket docket() {
String groupName = "1.0.0";
Docket docket = new Docket(DocumentationType.SWAGGER_2)
.host(host)
.apiInfo(apiInfo())
.groupName(groupName)
.select()
.apis(RequestHandlerSelectors.basePackage(basePackage))
.paths(PathSelectors.any())
.build()
.extensions(openApiExtensionResolver.buildExtensions(groupName));
return docket;
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title(title)
.description(description)
.termsOfServiceUrl(termsOfServiceUrl)
.contact(new Contact(contactName, contactUrl, contactEmail))
.version(version)
.build();
}
}
关于Knife4j
详情可查看这篇文章Java阶段二Day21
向pom.xml
导入依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-validationartifactId>
dependency>
ValidationConfiguration
模板
/**
* Validation配置类
*/
@Slf4j
@Configuration
public class ValidationConfiguration {
public ValidationConfiguration() {
log.debug("创建配置类对象:ValidationConfiguration");
}
@Bean
public javax.validation.Validator validator() {
return Validation.byProvider(HibernateValidator.class)
.configure() // 开始配置
.failFast(true) // 配置快速失败
.buildValidatorFactory() // 构建Validator工厂
.getValidator(); // 从Validator工厂中获取Validator对象
}
}
关于Validation
详情可查看这篇文章Java阶段二Day22