参数名称 | 参数值 | 是否必须 | 示例 | 备注 |
---|---|---|---|---|
Content-Type | application/json | 是 |
三、@RequestBody
从http请求body部分获取参数,通常用于接受json或xml格式
参数名称 | 示例 | 备注 |
---|---|---|
status | 1 | 套餐状态,1表示起售,0表示停售 |
用于从请求的URL路径中获取路径变量的值。路径变量是URL中的一部分,用于在RESTful风格的API中传递数据。路径变量的值会直接嵌入到URL路径中,并使用占位符 {}
来表示,Spring MVC 会根据占位符中的变量名将值注入到方法参数中。
@GetMapping("/users/{userId}")
public String getUser(@PathVariable("userId") Long userId) {
// 根据用户ID查询用户信息
}
参数名称 | 是否必须 | 示例 | 备注 |
---|---|---|---|
categoryId | 否 | 分类id | |
name | 否 | 套餐名称 | |
page | 是 | 页码 | |
pageSize | 是 | 每页记录数 | |
status | 否 | 套餐起售状态 |
//以下代码是请求参数对应接收类
@Data
public class SetmealPageQueryDTO implements Serializable {
private int page;
private int pageSize;
private String name;
//分类id
private Integer categoryId;
//状态 0表示禁用 1表示启用
private Integer status;
}
二、@RequestParam:
用于从请求的查询参数中获取单个参数值。通常用于GET请求或者POST请求中的查询参数。在GET请求中,查询参数会附加在URL后面,如 ?key1=value1&key2=value2
,而在POST请求中,查询参数会放在请求体中,需要使用 @RequestParam
指定参数名来获取值。
@GetMapping("/search")
public String search(@RequestParam("keyword") String keyword) {
// 处理查询操作
}
一:添加Spring Framework中的类标识注解 @RestController 这个注解后面可以跟上命名,当同一个项目中有两个一样的类名时,就可以使用这个注解来进行区别
二:添加处理路径 @RequestMapping(“/”)
三:添加日志记录器 原生是logging。这里我选择使用@Slf4j 创建日志记录器,并进行管理。使用该注解后,使用 log 对象进行管理
四:生成接口文档 @Api(tags = "标题")
这里使用Swagger生成接口文档,方便测试
五:对象管理 使用 @Autowired 来进行依赖注入
接口开发主要有三个地方需要开发,一是controller二是 service 三是mapper
@PostMapping("/admin/employee")
@ApiOperation("新增员工")
public Result save(@RequestBody EmployeeDTO employeeDTO){
//RequestBody 注解的作用是告诉Spring MVC框架,要将HTTP请求的body部分(通常是JSON或XML格式的数据)映射到方法参数 employeeDTO 上。
log.info("新增员工:{}",employeeDTO);
employeeService.sava(employeeDTO);
}
一: 确认控制器地址 @PostMapping(“/admin/employee”) 确认后面的请求路劲该写什么
二:编写传输的数据模型 编写一个实体用来接收前端传递过来的数据模型 EmployeeDTO employeeDTO
三:编写处理返回结果的类 Result
四:调用业务逻辑层的相关方法 employeeService.sava(employeeDTO);
附加: log.info(“新增员工:{}”,employeeDTO);便于调试@ApiOperation(“新增员工”)使得生成出来的接口测试站点更加容易阅读
一:编写接口的方法
二: 在实现类中实现
三:封装好属性与数据
记得在业务逻辑类前加上@service标签
遇到前端传来数据与数据库实体差距过大创建了两个对象的时候,业务逻辑层使用对象拷贝能更快拿到数据
/* 该注解用于生成接口文档时显示作用于类 */
@Api(tags = "员工相关接口")
public class EmployeeController {
@PostMapping("/login")
@ApiOperation(value = "员工登录方法") // 注意这里
public Result<EmployeeLoginVO> login(@RequestBody EmployeeLoginDTO employeeLoginDTO) {
@PostMapping("/logout")
@ApiOperation(value = "员工登出方法")
public Result<String> logout() {
return Result.success();
}
}
因为要用到标签所以在xml中进行编写
要注意到几个问题:
一:扫描范围
@PostMapping("/status/{status}")
@PutMapping
@ApiOperation("编辑员工信息")
public Result update(@RequestBody EmployeeDTO employeeDTO){
log.info("编辑员工:{}", employeeDTO);
employeeService.update(employeeDTO);
return Result.success();
@PostMapping
@ApiOperation("新增员工")
public Result save(@RequestBody EmployeeDTO employeeDTO){
log.info("新增员工:{}",employeeDTO);
employeeService.sava(employeeDTO);
/* 一个工具类,这个代表放回成功 */
return Result.success();
}
这是同一个类中的两个方法,都没有指定请求的路径,于是被视为都挂在在类默认路径上,一个是put一个是post请求
与@Component的区别: @Configuration
是 @Component
注解的特化,它们都是用来声明一个类作为Spring管理的组件,但 @Configuration
有特殊的语义,用于定义Bean和配置项。
启动加载: 配置类通常在Spring应用程序启动时被加载,Spring容器会扫描并解析其中的配置信息,以构建应用程序的应用上下文。
加上@RequestParam 注解即可
一个基于内存的key-value结构数据库。读写性能高,适合存储热点数据(经常访问的),mysql的补充
https://redis.net.cn/
@Test
public void testPOST() throws Exception {
/* 1、创建httpclient对象 */
CloseableHttpClient httpClient = HttpClients.createDefault();
/* 2、创建请求对象 */
//Post方式请求
HttpPost httpPost = new HttpPost("http://localhost:8080/admin/employee/login");
//构造json数据
JSONObject jsonObject = new JSONObject();
jsonObject.put("username","admin");
jsonObject.put("password", "123456");
//构造请求体
StringEntity stringEntity = new StringEntity(jsonObject.toString());
//设置请求编码
stringEntity.setContentEncoding("utf-8");
//设置数据类型
stringEntity.setContentType("application/json");
//设置当前Post请求的请求体
httpPost.setEntity(stringEntity);
/* 3、发送请求 */
//发送请求
CloseableHttpResponse response = httpClient.execute(httpPost);
/* 4、解析返回结果 */
//http响应码
int statusCode = response.getStatusLine().getStatusCode();
//http响应体
HttpEntity entity = response.getEntity();
//将响应体转为String字符串
String body = EntityUtils.toString(entity);
System.out.println(body);
/* 5、关闭资源 */
//关闭资源
response.close();
httpClient.close();
}
https://mp.weixin.qq.com/cgi-bin/wx?token=&lang=zh_CN
本套教程需要再详情中将基础库改为2.7以下版本
registry.addInterceptor(jwtTokenAdminInterceptor)
// 要拦截的网址
.addPathPatterns("/user/**")
// 要排除的网址
.excludePathPatterns("/user/user/login")
开发新增接口时注意这个新增是不是需要查询别的东西之类的,如果需要,那将很难进行测试
在进行数据库查询前,调用 PageHelper.startPage(pageNum, pageSize)
方法来开启分页功能。其中,pageNum
表示页码,pageSize
表示每页显示的记录数。执行完查询操作后,会自动进行分页,无需手动处理。
/**
* 根据分类id查询菜品
*
* @param categoryId
* @return
*/
// @GetMapping("/list")
// @ApiOperation("根据分类id查询菜品")
// public Result<List<DishVO>> list(Long categoryId) {
// Dish dish = new Dish();
// dish.setCategoryId(categoryId);
// dish.setStatus(StatusConstant.ENABLE);//查询起售中的菜品
//
// List<DishVO> list = dishService.listWithFlavor(dish);
//
// return Result.success(list);
// }
/* 进行接口改造,使得能存放进redis中 */
@GetMapping("/list")
@ApiOperation("根据分类id查询菜品")
public Result<List<DishVO>> list(Long categoryId) {
// 构造redis中的key dish_分类id
String key="dish_"+categoryId;
// 先查找redis中是否存在菜品数据 此处数据类型和存放进去的数据类型一致
List<DishVO> list =(List<DishVO>) redisTemplate.opsForValue().get(key);
if (list!=null &&list.size()>0){
// 直接返回内容无需查询数据库
return Result.success(list);
}
Dish dish = new Dish();
dish.setCategoryId(categoryId);
dish.setStatus(StatusConstant.ENABLE);//查询起售中的菜品
/* 如果不存在,查询数据库,将查询道德数据放入reids中 */
list = dishService.listWithFlavor(dish);
redisTemplate.opsForValue().set(key,list);
return Result.success(list);
}
增删改查启停售都需要清除缓存
@PostMapping
@ApiOperation("新增菜品")
public Result<String> save(@RequestBody DishDTO dishDTO){
log.info("新增菜品:{}", dishDTO);
dishService.saveWithFlavor(dishDTO);
return Result.success();
}
/* 清理缓存数据 */
String key ="dish_"+dishDTO.getCategoryId();
/* spel表达式来动态获取key */
@PostMapping
// @CachePut(cacheNames="userCache",key="#user.id") //如果使用spring cache缓存数据,key的生成:userCache::abc】
// @CachePut(cacheNames="userCache",key="#result.id")
// @CachePut(cacheNames="userCache",key="#p0.id")
// @CachePut(cacheNames="userCache",key="#a0.id")
// @CachePut(cacheNames="userCache",key="#root.args[0].id")
public User save(@RequestBody User user){
userMapper.insert(user);
return user;
}
编写类似一下的工具类
package com.sky.context;
public class BaseContext {
public static ThreadLocal<Long> threadLocal = new ThreadLocal<>();
public static void setCurrentId(Long id) {
threadLocal.set(id);
}
public static Long getCurrentId() {
return threadLocal.get();
}
public static void removeCurrentId() {
threadLocal.remove();
}
}
使用的方式:
一、在启动类上面加上
@EnableScheduling//开启任务调度
## 使用vue-cli脚手架来创建工程
https://so.csdn.net/so/search?spm=1000.2115.3001.4498&q=%E4%BD%BF%E7%94%A8vue%E8%84%9A%E6%89%8B%E6%9E%B6%E5%88%9B%E5%BB%BA%E9%A1%B9%E7%9B%AE&t=&u=
<template>
<div class="hello">
<h1>{{ name }}</h1>
<h1>{{ age > 40 ? '老奶' : '青年' }}</h1>
</div>
</template>
<script>
export default {
data() {
return {
name: '张三',
age: '30'
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped></style>
//上面的标题会变成下面的张三,而另一个年龄会变成老年。如此做判断的
编程式
//这样能实现访问不存在资源的时候显示404
{
path: '/404',
component: () => import('../views/404View.vue')
}, {
path: '*',
redirect: '/404'
}
**步骤一:**index中创建方法后,
步骤二: 在mutations中定义的函数因为不能直接调用,所以必须通过以下方式来调用
本文作者https://blog.csdn.net/qq_61654952?spm=1000.2115.3001.5343
[外链图片转存中…(img-EhKxU8Vm-1712314231766)]
[外链图片转存中…(img-bwnjzw3H-1712314231767)]
[外链图片转存中…(img-vaX7q7Ey-1712314231767)]
[外链图片转存中…(img-okxEjIki-1712314231768)]
[外链图片转存中…(img-zQiJk4w6-1712314231768)]
[外链图片转存中…(img-susgEZlQ-1712314231768)]
**步骤一:**index中创建方法后,
[外链图片转存中…(img-PRr357Aq-1712314231768)]
步骤二: 在mutations中定义的函数因为不能直接调用,所以必须通过以下方式来调用
[外链图片转存中…(img-kP6I4NaE-1712314231768)]
[外链图片转存中…(img-VdyhpKXT-1712314231769)]
[外链图片转存中…(img-m66u91rp-1712314231769)]
[外链图片转存中…(img-JIJwhaio-1712314231769)]
[外链图片转存中…(img-rBvk9sui-1712314231770)]
[外链图片转存中…(img-vlfMABWM-1712314231770)]
[外链图片转存中…(img-7doQuGPt-1712314231770)]
[外链图片转存中…(img-B1tSYwZq-1712314231770)]
[外链图片转存中…(img-egRQsefR-1712314231771)]
[外链图片转存中…(img-2qouvsDY-1712314231771)]
[外链图片转存中…(img-YV5FsncG-1712314231771)]
[外链图片转存中…(img-jiyUC6fr-1712314231772)]