- 在Servlet中使用Response对象来完成响应
package com.listao.mvc.controller;
@Controller
public class ResponseCtl {
@RequestMapping("/void")
public void resp_void() {
System.out.println("resp_void ===>>> ");
}
}
void
返回值,SpringMVC会去/servlet_war_exploded/void
页面展示。如果没有配置视图解析器的前缀、后缀不会产生404
Type Exception Report
Message Circular view path [void]: would dispatch back to the current handler URL [/spring_mvc_war_exploded/void] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)
Description The server encountered an unexpected condition that prevented it from fulfilling the request.
Exception
javax.servlet.ServletException: Circular view path [void]: would dispatch back to the current handler URL [/spring_mvc_war_exploded/void] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)
org.springframework.web.servlet.view.InternalResourceView.prepareForRendering(InternalResourceView.java:210)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:148)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:316)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1393)
org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1138)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1077)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:962)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
javax.servlet.http.HttpServlet.service(HttpServlet.java:529)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:94)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
Note The full stack trace of the root cause is available in the server logs.
- 单元方法的返回值类型设置
void
。因为使用Response
对象在单元方法中直接对此次请求进行了响应,不需要再给DispatcherServlet
返回值。形参声明HttpServletResponse
,作为此次请求的Response
对象
@RequestMapping("/servlet/forward")
public void servlet_forward(HttpServletRequest req, HttpServletResponse resp) throws Exception {
req.getRequestDispatcher("/forward.jsp").forward(req, resp);
}
@RequestMapping("/servlet/redirect")
public void servlet_redirect(HttpServletRequest req, HttpServletResponse resp) throws Exception {
System.out.println("req.getContextPath() = " + req.getContextPath());
resp.sendRedirect(req.getContextPath() + "/redirect.jsp");
}
@RequestMapping("/forward")
public String forward() {
return "forward:/forward.jsp";
}
@RequestMapping("/redirect")
public String redirect() {
return "redirect:/redirect.jsp";
}
RedirectView
最终实现链接的重定向,在renderMergedOutputModel()
中完成,并且将数据保存到FlashMap
中,在跳转后的链接中可以获取一些数据
@RequestMapping("/view")
public View view(HttpServletRequest req) {
View view;
view = new InternalResourceView("/forward.jsp");
view = new RedirectView(req.getContextPath() + "/redirect.jsp");
return view;
}
ModelAndView
中:Model代表模型,View代表视图
@RequestMapping("/modelAndView")
public ModelAndView modelAndView(HttpServletRequest req) {
ModelAndView mv = new ModelAndView();
mv.setViewName("forward:/forward.jsp");
mv.setView(new InternalResourceView("/forward.jsp"));
mv.setViewName("redirect:/redirect.jsp");
mv.setView(new RedirectView(req.getContextPath() + "/redirect.jsp"));
return mv;
}
- 通知
DispatcherServlet
单元方法的返回值不要按照请求转发、重定向处理,进行直接响应
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.14.0-rc1</version>
</dependency>
import com.fasterxml.jackson.databind.ObjectMapper;
@Test
public void toJson() throws Exception {
User pet = new User(1, "cat", "ooxx");
ObjectMapper om = new ObjectMapper();
String asString = om.writeValueAsString(pet);
System.out.println(asString);
}
@ResponseBody
@RequestMapping("/json")
public Pet json(Person person) {
System.out.println("person = " + person);
Pet pet = new Pet("Tom", "cat");
return pet;
}
- 无需再次使用eval函数将响应数据转换为json对象,直接使用即可
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta charset="UTF-8">
<title>response.jsp</title>
<script src="static/js/jquery.min.js"></script>
<script>
$(function () {
$("#btn").click(function () {
$.get("json", {pname: "晓明", page: "10"}, function (data) {
console.log(data.petName)
console.log(data.petType)
}, "json")
})
})
</script>
</head>
<body>
<input id="btn" type="button" value="JSON">
</body>
</html>
- 相当于
@Controller
+ @ResponseBody
两个注解结合 - 返回json数据不需要在方法前面加
@ResponseBody
注解了。视图解析器也无法再解析jsp、html页面
@RestController
public class ResponseCtl {
@RequestMapping("/json")
public Pet json(Person person) {
System.out.println("person = " + person);
Pet pet = new Pet("Tom", "cat");
return pet;
}
}
名称 | 作用域 | 特点 | 作用 |
---|
Application(ServletContext) | 在应用程序中有效 | 整个项目内有效 | 解决了不同用户的数据共享问题 |
Session | 在当前会话中有效 | 一次会话内有效 | 解决了一个用户不同请求的数据共享问题 |
Request | 在当前请求中有效 | 一次请求内 | 解决了一次请求内的资源的数据共享问题 |
PageContext | 在当前页面有效 | | |
http://localhost:8080/ssm_war_exploded/scope
接口访问,所有域有数据http://localhost:8080/ssm_war_exploded/scope.jsp
刷新页面访问,req无数据- 重开浏览器,req、session无数据
@RequestMapping("/http")
public String scope(HttpServletRequest req, HttpSession httpSession) {
HttpSession session = req.getSession();
ServletContext servletContext = req.getServletContext();
req.setAttribute("key", "reqMsg");
session.setAttribute("key", "sessionMsg");
servletContext.setAttribute("key", "appMsg");
return "/scope.jsp";
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>scope.jsp</title>
</head>
<body>
<%-- 域中的数据 --%>
requestScope => ${requestScope.key} <br/>
sessionScope => ${sessionScope.key} <br/>
applicationScope => ${applicationScope.key} <br/>
<%-- 请求参数 --%>
param => ${param.key} <br/>
</body>
</html>
- 请求转发:数据置于
RequestScope
- 重定向:Model将域中数据,置于url请求参数(Scope中无数据)
@RequestMapping("/model")
public String model(Model model) {
model.addAttribute("key", "modelMsg");
System.out.println("model = " + model);
return "/scope.jsp";
return "redirect:/scope.jsp";
}
@RequestMapping("/mv")
public ModelAndView modelAndView(ModelAndView mv) {
System.out.println("mv = " + mv);
Map<String, Object> model = mv.getModel();
model.put("key", "mvValue");
mv.setViewName("redirect:/scope.jsp");
System.out.println("mv = " + mv);
return mv;
}
- 形参
RedirectAttributes
FlashMap attribute = (FlashMap) request.getAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE);
FlashMap outputFlashMap = RequestContextUtils.getOutputFlashMap(request);
FlashMapManager flashMapManager = new SessionFlashMapManager();
import org.springframework.web.servlet.FlashMap;
import org.springframework.web.servlet.FlashMapManager;
import org.springframework.web.servlet.support.RequestContextUtils;
import org.springframework.web.servlet.support.SessionFlashMapManager;
String redirectJsp = "redirect:/scope.jsp";
String redirectPath = "redirect:/scope/redirect";
@RequestMapping("/flashMap1")
public String flashMap1(RedirectAttributes redirectAttributes) {
Map<String, String> map = Map.of("mk1", "mv1", "mk2", "mv2");
redirectAttributes.addFlashAttribute("key", map);
redirectAttributes.addAttribute("key2", "value2");
return redirectPath;
}
@RequestMapping("/redirect")
public String redirect(
Model model,
ModelMap mm,
@ModelAttribute("key") Map<String, String> key,
@RequestParam(value = "key2", required = false) String key2
) {
System.out.println("model = " + model);
System.out.println("mm = " + mm);
Map<String, String> map = (Map<String, String>) mm.getAttribute("key");
System.out.println("map = " + map);
System.out.println("key = " + key);
System.out.println("key2 = " + key2);
return "/scope.jsp";
}
@RequestMapping("/flashMap2")
public String flashMap2(HttpServletRequest request) {
Map<String, Map<String, String>> map = Map.of("key", Map.of("mk1", "mv1", "mk2", "mv2"));
FlashMap attribute = (FlashMap) request.getAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE);
attribute.putAll(map);
HttpSession session = request.getSession();
session.setAttribute("key", "ooxx");
return redirectPath;
}
@RequestMapping("/flashMap3")
public String flashMap3(HttpServletRequest request) {
Map<String, Map<String, String>> map = Map.of("key", Map.of("mk1", "mv1", "mk2", "mv2"));
FlashMap outputFlashMap = RequestContextUtils.getOutputFlashMap(request);
outputFlashMap.putAll(map);
return redirectPath;
}
@RequestMapping("/flashMap4")
public String flashMap4(HttpServletRequest request, HttpServletResponse response) {
FlashMap flashMap = new FlashMap();
flashMap.put("key", Map.of("mk1", "mv1", "mk2", "mv2"));
FlashMapManager flashMapManager = new SessionFlashMapManager();
flashMapManager.saveOutputFlashMap(flashMap, request, response);
return redirectPath;
}