能否用单个方法同时返回View与ResponseBody?及路径刷新异常求助
Spring MVC 路径匹配与多返回类型问题解答
一、刷新/grade/{courseCode}返回对象而非页面的问题
你当前的@GetMapping("/{courseCode}")方法加了@ResponseBody,不管是前端XHR请求还是浏览器直接刷新的普通GET请求,都会匹配到这个方法,所以返回JSON格式的Enrollment列表。要区分这两种请求,有两种可行方案:
方案1:通过请求头区分(推荐)
前端XHR请求会自动携带X-Requested-With: XMLHttpRequest请求头,后端可以通过这个标识判断请求类型,动态返回结果:
@GetMapping("/{courseCode}") public Object handleCourseRequest(@PathVariable String courseCode, HttpServletRequest request) { String requestedWith = request.getHeader("X-Requested-With"); if ("XMLHttpRequest".equals(requestedWith)) { // AJAX请求,返回JSON数据 List<Enrollment> enrollmentList = gradeService.getAllStudentEnrollmentById(courseCode); return enrollmentList; } else { // 普通浏览器请求,返回页面并传递数据 ModelAndView mav = new ModelAndView("lecturer/course-detail"); mav.addObject("courseCode", courseCode); // 可补充页面所需的其他业务数据 return mav; } }
注意:这里不需要加@ResponseBody,Spring会根据返回值类型自动处理——返回集合时自动序列化为JSON,返回ModelAndView时渲染对应的JSP视图。
方案2:给AJAX请求添加特定路径后缀
修改前端XHR请求的URL为/grade/{courseCode}.json,后端拆分两个方法分别处理不同请求:
// 处理浏览器刷新的普通请求,返回页面 @GetMapping("/{courseCode}") public String getCoursePage(@PathVariable String courseCode, Model model) { model.addAttribute("courseCode", courseCode); // 补充页面需要的其他业务数据 return "lecturer/course-detail"; } // 处理AJAX请求,返回JSON数据 @GetMapping("/{courseCode}.json") @ResponseBody public List<Enrollment> submitGrade(@PathVariable String courseCode) { return gradeService.getAllStudentEnrollmentById(courseCode); }
这种方式逻辑更清晰,前端调用AJAX时用带.json后缀的地址,浏览器直接访问无后缀地址就会返回页面。
二、单个方法同时返回View与ResponseBody的实现方式
完全可以实现,核心是根据请求类型动态返回不同类型的结果,Spring MVC会自动适配处理:
方式1:返回Object类型结合请求头判断
就是上面方案1的写法,返回Object类型,根据请求是否为AJAX,返回集合(自动转JSON)或ModelAndView(渲染视图),无需额外注解,Spring会通过HttpMessageConverter自动完成转换。
方式2:使用ResponseEntity实现灵活响应
如果需要自定义响应头、状态码等,可以用ResponseEntity包裹结果:
@GetMapping("/{courseCode}") public ResponseEntity<?> handleRequest(@PathVariable String courseCode, HttpServletRequest request) { String requestedWith = request.getHeader("X-Requested-With"); if ("XMLHttpRequest".equals(requestedWith)) { List<Enrollment> data = gradeService.getAllStudentEnrollmentById(courseCode); return ResponseEntity.ok(data); } else { ModelAndView mav = new ModelAndView("lecturer/course-detail"); mav.addObject("courseCode", courseCode); return ResponseEntity.ok(mav); } }
内容的提问来源于stack exchange,提问作者Rim
相关产品推荐
相关产品推荐

