前后端分离开发
前后端分离开发后,从工程结构上也会发生变化,即前后端代码不在混合在一个maven工程中,而是分为前端工程和后端工程
后端工程会部署到Tomcat中
前端工程会部署到Nginx中
YApi
源码地址:https://github.com/YMFE/yapi
要使用YApi,需要自己进行部署
Swagger
使用Swagger你只需要按照它的规范取定义接口及接口相关的信息,在通过Swagger衍生出来的一系列项目和工具,就可以做到生成各种格式的接口文档,以及在线调试页面等功能。
knife4j是为Java MVC框架集成Swagger生成的Api文档的增强解决方案
依赖坐标
复制代码
1
2
3
4
5
6<dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-spring-boot-starter</artifactId> <version>3.0.2</version> </dependency>
修改WebMvcConfig
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93package com.itheima.reggie.config; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j; import com.itheima.reggie.common.JacksonObjectMapper; import com.itheima.reggie.entity.Employee; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; import java.math.BigInteger; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.util.List; import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES; @Slf4j @Configuration @EnableSwagger2 @EnableKnife4j public class WebMvcConfig extends WebMvcConfigurationSupport { /** * 设置静态资源映射 * @param registry */ @Override protected void addResourceHandlers(ResourceHandlerRegistry registry) { log.info("开始进行静态资源映射..."); registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/backend/"); registry.addResourceHandler("/front/**").addResourceLocations("classpath:/front/"); } /** * 扩展mvc框架的消息转换器 * @param converters */ @Override protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) { log.info("扩展消息转换器..."); //创建消息转换器对象 MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter(); //设置对象转换器,底层使用Jackson将Java对象转为json messageConverter.setObjectMapper(new JacksonObjectMapper()); //将上面的消息转换器对象追加到mvc框架的转换器集合中 converters.add(0,messageConverter); } @Bean public Docket createRestApi() { // 文档类型 return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.itheima.reggie.controller")) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("瑞吉外卖") .version("1.0") .description("瑞吉外卖接口文档") .build(); } }
在过滤器中配置不需要拦截的路径
复制代码
1
2
3
4
5"/doc.html", "/webjars/**", "/swagger-resources", "/v2/api-docs"
直接访问即可http://localhost:8080/doc.html
注解 | 说明 |
---|---|
@Api | 用在请求的类上,例如@Controller,表示对类的说明 |
@ApiModel | 用在类上,通常是实体类,表示一个返回响应数据的信息 |
@ApiModelProperty | 用在属性上,描述响应类的属性 |
@ApiOperation | 用在请求的方法上,说明方法的用途,作用 |
@ApiImplicitParams | 用在请求的方法上,表示一组参数的说明 |
@ApiImplicitParam | 用在注解中,指定一个请求参数的各个方面 |
注解演示@ApiModel和@ApiModelProperty
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71package com.itheima.reggie.entity; import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDateTime; /** * 套餐 */ @ApiModel("套餐") @Data public class Setmeal implements Serializable { private static final long serialVersionUID = 1L; @ApiModelProperty("id主键") private Long id; @ApiModelProperty("分类id") //分类id private Long categoryId; @ApiModelProperty("套餐名称") //套餐名称 private String name; @ApiModelProperty("套餐价格") //套餐价格 private BigDecimal price; @ApiModelProperty("状态 0:停用 1:启用") //状态 0:停用 1:启用 private Integer status; @ApiModelProperty("编码") //编码 private String code; @ApiModelProperty("描述信息") //描述信息 private String description; @ApiModelProperty("图片") //图片 private String image; @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; @TableField(fill = FieldFill.INSERT) private Long createUser; @TableField(fill = FieldFill.INSERT_UPDATE) private Long updateUser; }
注解演示:@Api
复制代码
1
2
3
4
5
6
7@RestController @RequestMapping("/setmeal") @Slf4j @Api(tags = "套餐相关接口") public class SetmealController {... }
注解演示:@ApiOperation
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16/** * 新增套餐 * @param setmealDto * @return */ @ApiOperation(value = "新增套餐接口") @CacheEvict(value = "setmealCache",allEntries = true) @PostMapping public R<String> save(@RequestBody SetmealDto setmealDto){ log.info("套餐信息:{}",setmealDto); setmealService.saveWithDish(setmealDto); return R.success("新增套餐成功"); }
注解演示@ApiImplicitParams和@@ApiImplicitParam
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50/** * 套餐分页查询 * @param page * @param pageSize * @param name * @return */ @GetMapping("/page") @ApiImplicitParams({ @ApiImplicitParam(name = "page",value = "页码",required = true), @ApiImplicitParam(name = "pageSize",value = "每页记录数",required = true), @ApiImplicitParam(name = "name",value = "套餐名称",required = false) }) public R<Page> page(int page,int pageSize,String name){ //分页构造器对象 Page<Setmeal> pageInfo = new Page<>(page,pageSize); Page<SetmealDto> dtoPage = new Page<>(); LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>(); //添加查询条件,根据name进行like模糊查询 queryWrapper.like(name != null,Setmeal::getName,name); //添加排序条件,根据更新时间降序排列 queryWrapper.orderByDesc(Setmeal::getUpdateTime); setmealService.page(pageInfo,queryWrapper); //对象拷贝 BeanUtils.copyProperties(pageInfo,dtoPage,"records"); List<Setmeal> records = pageInfo.getRecords(); List<SetmealDto> list = records.stream().map((item) -> { SetmealDto setmealDto = new SetmealDto(); //对象拷贝 BeanUtils.copyProperties(item,setmealDto); //分类id Long categoryId = item.getCategoryId(); //根据分类id查询分类对象 Category category = categoryService.getById(categoryId); if(category != null){ //分类名称 String categoryName = category.getName(); setmealDto.setCategoryName(categoryName); } return setmealDto; }).collect(Collectors.toList()); dtoPage.setRecords(list); return R.success(dtoPage); }
最后
以上就是温暖黑裤最近收集整理的关于前后端分离开发的全部内容,更多相关前后端分离开发内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复