SpringMVC的Controller的访问原理
假设有一个基于SpringMVC的网站,其中有一个用户注册的功能。当用户在注册页面填写完信息后,点击提交按钮,会发送一个HTTP POST请求到服务器,请求的URL为/user/register
。
- DispatcherServlet接收请求:当用户点击提交按钮后,请求会被转发给DispatcherServlet。
- HandlerMapping找到匹配的Controller:DispatcherServlet会根据配置的HandlerMapping,找到匹配URL为
/user/register
的Controller。 - UserController处理请求:DispatcherServlet实例化UserController,并调用其中的
register()
方法进行处理。UserController类上可能有注解@Controller
,并且register()
方法上可能有注解@RequestMapping("/register")
,用来标识该方法是处理/user/register
请求的。 register()
方法执行:register()
方法会获取请求中的参数(如用户名、密码等),执行相应的注册逻辑,并将注册结果保存在ModelAndView对象中。- 视图解析器解析视图名称:DispatcherServlet将视图名称(比如
registerSuccess
)传递给配置的视图解析器,解析器根据视图名称查找并返回真正的视图对象。 - 视图渲染:DispatcherServlet将ModelAndView对象中的注册结果数据传递给视图对象,视图对象可以使用这些数据生成HTML代码或其他形式的视图内容。
- 响应返回给客户端:DispatcherServlet将最终生成的响应内容返回给浏览器,浏览器显示注册成功的页面。
总结起来,上述示例中的Controller(UserController)接收到/user/register
的请求后,执行注册逻辑,并将结果保存在ModelAndView对象中,最后通过视图解析器和视图对象生成最终的响应内容返回给客户端。
响应失败则反馈
增删改查的RESTful接口
第一步:建立pojo的包,用来存放简单的java的对象
pojo:简单的java对象,一般要包括:属性、getter和setter方法的,其他的也可以加。主要用来封装数据的。
User.java
package cn.bobohost.market.pojo;
/**
* 用户的pojo(java的普通对象、简单对象)的类(JavaBean、实体类),用来封装数据用的
*/
public class User {
//用户唯一编号
private Integer id;
//用户名
private String userName;
//年龄
private Integer age;
//提供属性方法
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
第二步:在controller的包中编写UserController:
命名:一般是pojo类的名字+Controller
package cn.bobohost.market.web.controller;
import cn.bobohost.market.pojo.User;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
/**
* 用户的Controller
*/
@RestController
public class UserController {
/**
* 保存一个用户
* Post请求的数据,要放到http的请求体里面,不是请求参数上的。
* 服务端必须加@RequestBody这个注解才能接受。
*
* @param user 用户对象
* @return 提示结果
*/
@PostMapping("/user/")
public String add(@RequestBody User user){
//服务端控制台打印
System.out.println(user);
//返回结果给客户端
return "保存成功!";
}
/**
*
*
* /user/{id}:代表,你请求的路径资源必须制定是哪个一个id的用户
* 将来客户端请求的时候:/user/1
* @param user 用来封装数据的消息体
* @param id 用户的唯一编号
* @return
*/
@PutMapping("/user/{id}")
public String update(@RequestBody User user,@PathVariable Integer id){
//服务端控制台打印
System.out.println(user);
//返回结果给客户端
return "修改成功!";
}
/**
* 删除
* 客户端:/user/1
* @param id
* @return
*/
@DeleteMapping("/user/{id}")
public String remove(@PathVariable Integer id){
System.out.println(id);
//返回结果给客户端
return "删除成功!";
}
/**
* 查询所有的用户列表
* @return
*/
@GetMapping("/user")
public List<User> list(){
List<User> userList =new ArrayList<>();
//添加元素---自己模拟两个用户
User user1 =new User();
user1.setId(1);
user1.setUserName("Rose");
user1.setAge(18);
User user2 =new User();
user2.setId(2);
user2.setUserName("Jack");
user2.setAge(88);
//将用户添加到列表
userList.add(user1);
userList.add(user2);
//返回列表
return userList;
}
/**
* 根据id查询一个用户
* @param id
* @return
*/
@GetMapping("/user/{id}")
public User getById(@PathVariable Integer id){
System.out.println(id);
User user1 =new User();
user1.setId(1);
user1.setUserName("Rose");
user1.setAge(18);
return user1;
}
}
重新启动服务。
快速使用浏览器测试:
因为浏览器默认只支持get请求,那么因此,这里只能测试get请求的Controller方法
//测试查询所有
http://localhost:8989/user
[
{
"id": 1,
"userName": "Qin",
"age": 22
},
{
"id": 2,
"userName": "Wang",
"age": 19
}
]
Java的列表对应的json数组,数组中每一个json对象对应一个java对象。
1)返回数据的时候,依赖@RestController,会将java对象自动转换为json数据。
2)当接收到数据的时候,依赖@RequestBody注解,会将json数据自动转换为java对象。
接口测试PostMan
浏览器默认只能发出get请求,如果需要发起其他请求,可以安装插件,或者前端写js代码,再js中调用。
实际上后端测试有专门的工具,可以模拟浏览器/前端来发起请求。
这里使用最流行的Rest api接口测试工具Postman。
概念:API(Application Programming Interface,应用程序编程接口)
Postman不只是用来测试我们自己写的接口,也经常用来测试别人的接口。
首先需要安装Postman
双击:Postman-win64-Setup.exe
,稍等片刻,自动打开开始界面。
打印对象toString方法的覆盖
在打印的用户对象到控制台的时候,发现打印的是内存地址:
cn.bobohost.market.pojo.User@4ca809fc
Java的内存管理是通过jvm(java虚拟机)自动管理的。
在程序运行时,对象等会自动被分配内存,内存地址是唯一的!
默认情况下,打印pojo的对象,默认打印的是内存地址,格式是java定义好的一个格式:
数据类型@内存地址
内存地址:用16进制来表示的。
数据类型:基本数据类型(int、double)、字符串String类型、对象类型(类的类型,比如User、Order、。。。)
对于java的类的类型的表示方式有两种:
一种是长类型写法:包名+类名。。标准写法,如cn.bobohost.market.pojo.User
一种是长类型写法:包名+类名。。标准写法,如cn.bobohost.market.pojo.User
在实际开发中,如果一个类中需要调用两个同名的但不同包的类,则一个用import导入,一个必须写长的全类名。
控制台打印对象的底层方法是toString(),默认打印的内存地址是帮你拼接的一个字符串:cn.bobohost.market.pojo.User@4ca809fc
现在我要打印详细的里面的内容怎么办?
解决:覆盖User的默认的toString方法。
可以通过快捷键生成覆盖的toString方法:
alt+insert,选toString
简化普通类-LombOK
LombOK是一个java的类库,用来简化pojo类的,可以不写getter和setter,以及toString
第一步:pom.xml引入依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
刷新maven!!!!!
第二步:安装一个idea的插件
可以检查一下插件,如果安装了就不用安装了
第三步:在代码中加入一个注解
@Data
@Data
public class User {
//用户唯一编号
private Integer id;
//用户名
private String userName;
//年龄
private Integer age;
}
点击启动。
解释一下:
@Data:自动生成setter/getter、equals、canEqual、hashCode、toString方法。
@Slf4j:日志
@RequiredArgsConstructor/@NoArgsConstructor:构造器相关
@Data
@Data
public class User {
//用户唯一编号
private Integer id;
//用户名
private String userName;
//年龄
private Integer age;
}
点击启动。
解释一下:
@Data:自动生成setter/getter、equals、canEqual、hashCode、toString方法。
@Slf4j:日志
@RequiredArgsConstructor/@NoArgsConstructor:构造器相关