概述
客户端的网络请求首先会被Http服务器接收(也叫Web服务器、web容器,其需要提供web应用运行所需的环境,接收客户端的Http请求);
Web服务器根据请求的路径将请求转交给对应的Servlet容器(也称Servlet引擎,为Servlet的运行提供环境支持,可以理解为tomcat或其他服务器);
Servlet容器根据对应的虚拟路径(@WebServlet中配置的)来加载Servlet,如果Serlvet没有被实例化则创建该Servlet的一个实例(调用init方法);
Servlet容器根据用户的HTTP请求,创建一个ServletRequest对象(HTTP的请求信息被封装在其中)和一个可以对HTTP请求进行响应的ServletResponse对象(类似于寄信,并在信中说明回信的地址),然后调用HttpServlet中重写的service(ServletRequest req, ServletResponse res)方法,并在这个方法中,将ServletRequest、ServletResponse这两个对象向下转型,得到我们非常熟悉的HttpServletRequest和HttpServletResponse两个对象,然后将客户端的请求转发到HttpServlet中protected修饰的service(HttpServletRequest req, HttpServletResponse resp)
HttpServletRequest和@Requestparam、@RequestBody三种都是常用的在http请求中接收前端参数的方式,而后端用于响应的有HttpServletResponse,今天实验了一下用于请求的几种方式:
1.HttpServletRequest
例子
public Object updateSongMsg(HttpServletRequest req){
JSONObject jsonObject = new JSONObject();
String id = req.getParameter("id").trim();
String singer_id = req.getParameter("singerId").trim();
String name = req.getParameter("name").trim();
String introduction = req.getParameter("introduction").trim();
String lyric = req.getParameter("lyric").trim();
Song song = new Song();
song.setId(Integer.parseInt(id));
song.setSingerId(Integer.parseInt(singer_id));
song.setName(name);
song.setIntroduction(introduction);
song.setUpdateTime(new Date());
song.setLyric(lyric);
boolean res = songService.updateSongMsg(song);
if (res){
jsonObject.put("code", 1);
jsonObject.put("msg", "修改成功");
return jsonObject;
}else {
jsonObject.put("code", 0);
jsonObject.put("msg", "修改失败");
return jsonObject;
}
}
参数用HttpServletRequest req,相当于把前端的请求内容包装了起来,个人认为传送时可以类似于Requesparam,下面用postman实验:
localhost:8888/song/update?id=1&singerId=1&name=直接&introduction=烦烦烦&lyric=123
下面查看数据库:
从源码可以看到 HttpServletRequest extends ServletRequest,是一个抽象接口
可以用它获得更多的客户端信息:
我们在上面的方法中输出:
@ResponseBody
@RequestMapping(value = "/song/update", method = RequestMethod.POST)
public Object updateSongMsg(HttpServletRequest req){
System.out.println("getRequestURI:"+req.getRequestURI()+" getServerName():"+req.getServerName()
+" getServerPort():"+req.getServerPort()+" rethod:"+req.getMethod());
}
再次发起请求时可以看到:
2.@RequestParam
有一些特殊情况,我们的服务端的接口变量名可能和前端不一致,这个时候我们可以通过 @RequestParam 注解来解决
修改上面的请求参数变为:
public Object updateSongMsg(@RequestParam("id")String id,@RequestParam("singerId")String singer_id,
@RequestParam("name")String name,@RequestParam("introduction")String introduction,
@RequestParam("lyric")String lyric){
JSONObject jsonObject = new JSONObject();
Song song = new Song();
song.setId(Integer.parseInt(id));
song.setSingerId(Integer.parseInt(singer_id));
song.setName(name);
song.setIntroduction(introduction);
song.setUpdateTime(new Date());
song.setLyric(lyric);
boolean res = songService.updateSongMsg(song);
if (res){
jsonObject.put("code", 1);
jsonObject.put("msg", "修改成功");
return jsonObject;
}else {
jsonObject.put("code", 0);
jsonObject.put("msg", "修改失败");
return jsonObject;
}
}
下面发送请求
localhost:8888/song/update?id=1&singerId=1&name=修改&introduction=烦烦烦&lyric=123
再次看数据库:
可以看到name发生了改变。其中数据库字段为singer_id,而我们传的是singerId,相当于把@RequestParam注解中的singerId中传过去的值给了参数中的singer_id,起到的效果与上面的HttpServletRequest相同
3.@RequestBody
@requestbody要求传递的是一个json格式的字符串
如:
$ajax(
{
type:"post",
url:"json/user",
data:'{"name":"admin","pwd":"123456"}',
success:function(data){
console.log(data);
}
})
注意上面的data是字符串(有单引号)
@RequestBody 注解用于接收前端传来的实体,接收参数也是对应的实体,比如前端通过json 提交传来两个参数username 和password,此时我们需要在后端封装一个实体来接收。
@PostMapping(value = "/config2",produces ="text/plain;charset=UTF-8" )
public String testConfig(@RequestBody User user) {
System.out.println(user.getUsername());
System.out.println(user.getPassword());
return "success";
}
此时必须以json字符串的形式接收。
即
{
“username":“nihao”,
“password”:“123456”
}
4.直接实体接收
使用实体接收的话,我们不能在前面加@RequestParam 注解了,直接使用即可。这个适合于实体字段非常多,用@RequestParam比较麻烦的场景
public class User {
private String username;
private String password;
// set get
}
@PostMapping("/form2")
public String testForm(User user) {//需注意方法的参数
System.out.println("获取到的username 为:" +
user.getUsername());
System.out.println("获取到的password 为:" +
user.getPassword());
return "success";
注意发送时必须以key-values的格式发送,而不是json格式
HttpServletRequest请求方法详解:
HttpServletRequest可以获得的参数更多,它可以获得客户端的请求行和请求头、请求体信息。
当访问Servlet时,会在请求消息的请求行中,包含请求方法、请求资源名、请求路径等信息,为了获取这些信息,在HTTPServletRequest接口中,定义了一系列用于获取请求行的方法
ttpServletResponse:服务端处理完Http的请求后,根据HttpServletResponse对象将处理结果作为Http响应返回给客户端
且注意HttpServletRequest的不同实现类有实现不同的方法。
获得请求行:一些请求行方法的解释:
获得请求头
除了请求行,在HttpServletRequest接口中,也定义了一系列用于获取HTTP请求头字段的方法:
获得请求体:这也是上面的示例获得参数的方法。
在实际开发中,经常需要获取用户提交的表单数据,例如,用户名,密码、电子邮件等,为了方便获取表单中的请求参数,在HttpServletRequest接口总,定义了一些列获取请求参数的方法