1 SpringBoot常用开发技能
1.1 项目架构
- 创建项⽬
- 配置启动类
- 建⽴对应的包,先建⽴这些包,其他⽤到再补充
controller
service
mapper
domain
utils
1.2 开发HTTP接⼝GET请求
GET请求
场景:⼀般的查询接⼝就是get请求
注解:@GetMapping = @RequestMapping(method = RequestMethod.GET)
⼀个顶两的注解
@GetMapping = @RequestMapping(method = RequestMethod.GET)
@PostMapping = @RequestMapping(method = RequestMethod.POST)
@PutMapping = @RequestMapping(method = RequestMethod.PUT)
@DeleteMapping = @RequestMapping(method = RequestMethod.DELETE)
示例:视频列表查询
- 实体类:Video
public class Vedio implements Serializable {private Integer id;private String title;private String summary;private Integer price;private String coverImg;private Date createTime;public Vedio() {}public Vedio(Integer id, String title) {this.id = id;this.title = title;this.createTime = new Date();}
// 省get、set、tostring方法
- mapper类:VideoMapper
@Repository
public class VideoMapper {private static Map<Integer, Vedio> videoMap = new HashMap<>();/*** 模拟数据*/static {videoMap.put(1, new Vedio(1 , "东邪西毒"));videoMap.put(2, new Vedio(2 , "精武英雄"));videoMap.put(3, new Vedio(3 , "霸王别姬"));videoMap.put(4, new Vedio(4 , "南极大冒险"));videoMap.put(5, new Vedio(5 , "变形金刚"));videoMap.put(6, new Vedio(6 , "流浪地球"));}// 获取视频列表public List<Vedio> listVideo() {List<Vedio> list = new LinkedList<>();list.addAll(videoMap.values());return list;}
}
- service类,包括接口和实现类
接口类: VideoService
public interface VideoService {List<Vedio> listVideo();
}
实现类:VideoServiceImpl
@Service
public class VideoServiceImpl implements VideoService {@Autowired // 自动注入VideoMapperprivate VideoMapper videoMapper;@Overridepublic List<Vedio> listVideo() {return videoMapper.listVideo();}
}
- Controller类:VideoController
@RestController
@RequestMapping("/app/v1/video")
public class VideoController {@Autowired // 自动注入VideoService实现类private VideoService videoService;@RequestMapping("list")public Object getList() {return videoService.listVideo();}
}
测试:
- 启动程序
. ____ _ __ _ _/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \\\/ ___)| |_)| | | | | || (_| | ) ) ) )' |____| .__|_| |_|_| |_\__, | / / / /=========|_|==============|___/=/_/_/_/:: Spring Boot :: (v2.6.2)2022-01-12 14:11:05.388 INFO 20464 --- [ main] c.j.s.Springbootdemo2Application : No active profile set, falling back to default profiles: default
2022-01-12 14:11:06.005 INFO 20464 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2022-01-12 14:11:06.011 INFO 20464 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2022-01-12 14:11:06.011 INFO 20464 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.56]
2022-01-12 14:11:06.068 INFO 20464 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2022-01-12 14:11:06.068 INFO 20464 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 646 ms
2022-01-12 14:11:06.315 INFO 20464 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2022-01-12 14:11:06.321 INFO 20464 --- [ main] c.j.s.Springbootdemo2Application : Started Springbootdemo2Application in 1.198 seconds (JVM running for 1.959)
- 访问接口
1.3 制定统⼀接⼝返回协议
实际开发中通过⾃定义返回对象,统⼀协议,能够有效的避免开发中协议不统一导致的许多问题,而且还能提供工作的效率。
- 自定义返回信息对象(务必生成get、set方法)
/*** 业务返回信息类*/
public class RetData {/*** 业务返回码,默认:0:成功,-1:失败*/private int code; // 业务返回码/*** 业务数据*/private Object data; // 业务数据/*** 返回信息*/private String message; // 状态信息public RetData(){}public RetData(int code, Object data, String message) {this.code = code;this.data = data;this.message = message;}/*** 无参返回成功,默认返回码*/public static RetData RetSuccess() {return new RetData(0, null, "success");}/*** 有参返回成功,默认返回码* @param data* @return*/public static RetData RetSuccess(Object data) {return new RetData(0, data, "success");}/*** 无参返回错误,默认返回码* @return*/public static RetData RetError() {return new RetData(-1, null, "unknow error");}/*** 默认返回码带错误信息* @param msg* @return*/public static RetData RetError(String msg) {return new RetData(-1, null, msg);}/*** 自定义返回码带错误信息* @param code* @param msg* @return*/public static RetData RetError(int code, String msg) {return new RetData(code, null, msg);}public int getCode() {return code;}public void setCode(int code) {this.code = code;}public Object getData() {return data;}public void setData(Object data) {this.data = data;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}
}
- 在VideoController类中使用RetData返回
@RequestMapping("list")public Object getList() {return RetData.RetSuccess(videoService.listVideo()); // 使用RetData返回}
- 重启程序并访问接口,返回结果如下:
code:业务返回码
data:业务数据
message:返回信息
{"code": 0,"data": [{"id": 1,"title": "东邪西毒","summary": null,"price": null,"coverImg": null,"createTime": "2022-01-12T06:43:36.907+00:00"},{"id": 2,"title": "精武英雄","summary": null,"price": null,"coverImg": null,"createTime": "2022-01-12T06:43:36.907+00:00"},{"id": 3,"title": "霸王别姬","summary": null,"price": null,"coverImg": null,"createTime": "2022-01-12T06:43:36.907+00:00"},{"id": 4,"title": "南极大冒险","summary": null,"price": null,"coverImg": null,"createTime": "2022-01-12T06:43:36.907+00:00"},{"id": 5,"title": "变形金刚","summary": null,"price": null,"coverImg": null,"createTime": "2022-01-12T06:43:36.907+00:00"},{"id": 6,"title": "流浪地球","summary": null,"price": null,"coverImg": null,"createTime": "2022-01-12T06:43:36.907+00:00"}],"message": "success"
}
1.4 开发HTTP接⼝POST请求
POST请求-form表单
场景:表单提交,如果不⽤细分PUT/DELETE⽅法,则都可以⽤POST
注解:@PostMapping = @RequestMapping(method = RequestMethod.POST)
测试:
- 编写UserController类
@RestController
@RequestMapping("/app/v1/user")
public class UserController {@PostMapping("login")public RetData login(String username, String pwd) {System.out.println("username:" + username + ",pwd:" + pwd);return RetData.RetSuccess("");}
}
- 启动程序
- 采用参数形式
能够正常接收post提交的参数
- 采用form表单形式
也能够正常接收post提交的参数
实际开发中,参数数量比较多,通常我们会用对象接收参数,修改UserController如下:
@RestController
@RequestMapping("/app/v1/user")
public class UserController {@PostMapping("login")public RetData login(User user) {System.out.println("user:" + user.toString());return RetData.RetSuccess("");}
}
再次使用form表达形式提交
程序依然能够正常接收post提交的参数
user:User{id=null, username='tom', password='8888'}
但实际开发中,接口一般都是以json形式提交参数,提交方式如下:
此时程序无法正常接收数据
user:User{id=null, username='null', password='null'}
为了正常接收json形式的参数,需要在对象参数前面加注解:@RequestBody
注意:参数名字与对象属性名称保持一致
@PostMapping("login")public RetData login(@RequestBody User user) {System.out.println("user:" + user.toString());return RetData.RetSuccess("");}
这样才能正常的接收
user:User{id=null, username='fanny', password='123456'}
开发示例:账号密码提交登录接⼝,form表单形式
- Mapper类:UserMapper
@Repository
public class UserMapper {private static Map<String, User> userMap = new HashMap<>();static {userMap.put("jackyan", new User(1, "jackyan", "123456"));userMap.put("lucy", new User(2, "lucy", "888888"));userMap.put("tom", new User(3, "tom", "666666"));userMap.put("fancy", new User(4, "fancy", "555555"));}public User login(String username, String password) {User user = userMap.get(username);if (user == null) {return null;} else if (user.getPassword().equals(password)) {return user;}return null;}
}
- Service类
接口类:UserService
public interface UserService {public String login(String username, String password);
}
实现类:
@Service
public class UserServiceImpl implements UserService {// 模拟保存用户sessionprivate static Map<String, User> sessionMap = new HashMap<>();@Autowiredprivate UserMapper userMapper;@Overridepublic String login(String username, String password) {User user = userMapper.login(username, password);if (user == null) {return null;}String token = UUID.randomUUID().toString();// 保存用户sessionsessionMap.put(token, user);return token;}
}
- Controller类:UserController
@RestController
@RequestMapping("/app/v1/user")
public class UserController {@Autowiredprivate UserService userService;@PostMapping("login")public RetData login(@RequestBody User user) {String token = userService.login(user.getUsername(), user.getPassword());if (token == null) {return RetData.RetError("用户名或密码错误!");}return RetData.RetSuccess(token);}
}
- 测试
登录成功
登录失败
1.5 RequestBody对象数组提交接⼝
POST请求-RequestBody⽅式
开发示例:新增视频json对象,章数组提交
- Video类增加章列表信息
private List<Chapter> chapterList;
- 新增Chapter类
/*** 视频章信息*/
public class Chapter {private Integer id;private Integer videoId;private String title;public Chapter() {}public Chapter(Integer id, Integer videoId, String title) {this.id = id;this.videoId = videoId;this.title = title;}
// 省略set、get、tostring方法
- 编写Controller类测试
@PostMapping("save_video")public RetData saveVideo(@RequestBody Video video) {return RetData.RetSuccess(video);}
- 测试,发送数据
{"id":1001,"title":"精武英雄","chapterList":[{"id":10001,"title": "日本求学"},{"id":10002,"title": "回国探师"},{"id":10003,"title": "比武切磋"}]
}
- 测试结果
{"code": 0,"data": {"id": 1001,"title": "精武英雄","summary": null,"price": null,"coverImg": null,"createTime": null,"chapterList": [{"id": 10001,"videoId": null,"title": "日本求学"},{"id": 10002,"videoId": null,"title": "回国探师"},{"id": 10003,"videoId": null,"title": "比武切磋"}]},"message": "success"
}
1.6 定制JSON字段
springboot中自带jackson相关包,可以用来定制化处理实体类字段相关信息:
指定字段不返回:@JsonIgnore
指定⽇期格式:@JsonFormat(pattern="yyyy-MM-dd hh:mm:ss",locale="zh",timezone="GMT+8")
空字段不返回:@JsonInclude(Include.NON_NULL)
指定别名:@JsonProperty
@JsonProperty("cover_img") // 给字段取别名private String coverImg;@JsonFormat(pattern="yyyy-MM-dd hh:mm:ss",locale="zh",timezone="GMT+8")@JsonProperty("create_time")private Date createTime;@JsonProperty("chapter_list")
@JsonIgnore // 该字段不返回private String password;
喜欢的朋友记得点赞、收藏、关注哦!!!