-
同步请求:form表单、超链接等。
-
异步请求:AJAX等。
一、响应同步请求
处理同步请求的方法的返回类型定义为String
或者是ModelAndView
,以实现页面的请求跳转(也叫转发)/重定向。
-
返回类型为
String
时:package controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @Controller @RequestMapping("/student") public class StudentController { @RequestMapping("/addStudent") public String addStudent(@RequestParam(value = "username") String username, @RequestParam(value = "password") String password, @RequestParam(value = "age", defaultValue = "0") Integer age, @RequestParam(value = "address") String address) { /* * 跳转到指定的页面。 * 注意: * 此处不能写成 return "tips.jsp"; * 原因: * 在类上我们定义了@RequestMapping("/student"), * 如果写成return "tips.jsp";,那么其URI路径将为"/项目名/student/tips.jsp" * ( * 1、 * 将类上的@RequestMapping("/student")去掉, * 方法上的注解改成@RequestMapping("/student/addStudent"), * 结果一样。 * 2、 * return "tips.jsp";使用的是相对路径,表示在当前路径下。 * 而"/addStudent"是在"/student"路径下,return "tips.jsp";与"/addStudent"在同一路径下, * 因此,return "tips.jsp";表示的是在"/student"路径下的tips.jsp文件。 * ), * 显然,tips.jsp文件在webapp目录下,不在student目录下,所以显示404。 * 解决: * 1、 * 将tips.jsp放在webapp目录的student目录下(webapp/student/tips.jsp)。 * 2、 * 将相对路径(return "tips.jsp";)改为绝对路径(return "/tips.jsp";)。 * 此时URI路径为"/项目名/tips.jsp"(前提是tips.jsp在webapp目录下)。 * 3、 * 将路径"/student/addStudent"改为"/student-addstudent"(就是将当前控制器方法的路径由"/student"改为根路径), * 这样tips.jsp与"/addStudent"就都在根目录下了。 */ return "/tips.jsp"; // 重定向到指定页面。 return "redirect:/tips.jsp"; } }
-
返回类型为
ModelAndView
时:package controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; @Controller @RequestMapping("/student") public class StudentController { @RequestMapping("/addStudent") public ModelAndView addStudent(@RequestParam(value = "username") String username, @RequestParam(value = "password") String password, @RequestParam(value = "age", defaultValue = "0") Integer age, @RequestParam(value = "address") String address) { System.out.println(username+", "+password+", "+age+", "+address); // 跳转到指定页面。 ModelAndView modelAndView = new ModelAndView("/tips.jsp"); return modelAndView; // 重定向到指定页面。 ModelAndView modelAndView = new ModelAndView("redirect:/tips.jsp"); return modelAndView; } }
二、响应异步请求
-
前端代码:
<input type="button" value="AJAX提交数据" id="btn1"> <script type="text/javascript" src="static/js/jquery-3.7.1.min.js"></script> <script type="text/javascript"> $("#btn1").click(function () { let obj = {}; obj.username="张三"; obj.password="123456"; obj.age=24; obj.address="江西省南昌市"; let s = JSON.stringify(obj); console.log(s); $.ajax({ <!--在url中使用?key=value传值,此为请求行传值--> url:"student/addStudent", type:"post", <!--此为请求体传值,一般用来传递一个对象结构,此时需要声明传递的数据类型。如下所示--> contentType:"application/json", data: JSON.stringify(obj), <!--回调方法--> success:function (res) { console.log(res); } }); }); </script>
-
使用
response
中的输出流进行响应:-
控制器方法的返回类型为
void
。 -
控制器方法添加
HttpServletResponse resp
参数。 -
在方法中通过
resp
获取输出流,使用输出流来响应异步请求。
package controller; import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.servlet.http.HttpServletResponse; import model.Student; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import java.io.IOException; import java.io.PrintWriter; @Controller @RequestMapping("/student") public class StudentController { @RequestMapping("/addStudent") public void addStudent(@RequestBody Student student, HttpServletResponse resp) throws IOException { System.out.println(student); // 使用Jackson将对象转换成JSON格式的字符串。 String s = new ObjectMapper().writeValueAsString(student); // 设置响应的数据类型和编码格式。 resp.setContentType("application/json; charset=utf-8"); // 获取输出流 PrintWriter writer = resp.getWriter(); writer.println(s); writer.flush(); writer.close(); } }
运行结果:
-
-
直接在控制器方法返回响应的对象(Spring MVC提供):
-
控制器方法的返回类型设置为响应给AJAX请求的对象类型(可以是单个、数组、集合等)。
-
在控制器方法前添加
@ResponseBody
注解,将返回的对象转换成JSON格式响应给AJAX请求。
package controller; import model.Student; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import java.util.ArrayList; import java.util.List; @Controller @RequestMapping("/student") public class StudentController { @RequestMapping("/addStudent") // @ResponseBody和@RequestBody都需要使用到jackson-databind依赖。 // 如果控制器类中所有的方法都是响应AJAX异步请求,可以将@ResponseBody注解统一放在类上。但是这样的话该控制器类便不能再做同步请求了。 @ResponseBody public List<Student> addStudent(@RequestBody Student student) { System.out.println(student); List<Student> students = new ArrayList<>(); students.add(student); students.add(student); return students; } }
运行结果:
-
三、控制器响应同步请求的数据传递
前端代码(index.jsp):
<form action="student/addStudent" method="post">
<p>学生姓名:<input type="text" name="username"></p>
<p>学生密码:<input type="password" name="password"></p>
<p>学生年龄:<input type="text" name="age"></p>
<p>学生地址:<input type="text" name="address"></p>
<p><input type="submit" value="表单提交数据"></p>
</form>
前端代码(tips.jsp):
<body>
<!--参数名与后端传递的键值对中的键保持一致-->
<p>学校:${school}</p>
<p>学生:${student}</p>
</body>
运行结果:
下述方法为使用Spring MVC原生的方法进行数据传递,除此之外还可使用Servlet中的HttpServletRequest
进行数据的传递。
-
返回类型为
String
时:-
在控制器方法中定义一个
Model
类型的参数。 -
在
return
之前,向Model
中添加要转发的参数(键值对),添加的参数就会被传递到转发的页面。
package controller; import model.Student; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping("/student") public class StudentController { @RequestMapping("/addStudent") public String addStudent(String username, String password, Integer age, String address, Model model) { System.out.println(username+", "+password+", "+age+", "+address); model.addAttribute("school", "绝望小学"); model.addAttribute("student", new Student(username, password, age, address)); return "/tips.jsp"; } }
-
-
返回类型为
ModelAndView
时:package controller; import model.Student; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; @Controller @RequestMapping("/student") public class StudentController { @RequestMapping("/addStudent") public ModelAndView addStudent(String username, String password, Integer age, String address) { System.out.println(username+", "+password+", "+age+", "+address); ModelAndView modelAndView = new ModelAndView("/tips.jsp"); modelAndView.addObject("school", "绝望小学"); modelAndView.addObject("student", new Student(username, password, age, address)); return modelAndView; } }