SSM-SpringMVC请求-响应-转发-重定向
方法返回处理
默认的情况下MVC返回的时候调用视图解析器
什么是视图解析器
<!-- 配置的视图解析器 返回的值进行凭借-->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!-- 后缀-->
<property name="suffix" value=".jsp"/>
</bean>
作用:控制器中的方法返回是进行拼接 比如返回 baidu 这个字符串
那么解析后 就是 /WEB-INF/jsp/baidu.jsp 然后进行转发
这样做的意义?
在正常情况下是无法通过重定向直接访问WEB-INF下目录内容的只能通过转发的方式然后拼接路径才能访问到 而视图解析器帮我们省略了拼接路径和转发的步骤,直接通过文件名称不加后缀就能访问到
两种情况
-
无返回值的时候他默认解析路径一般都爆错404
@RequestMapping(value = "/pr") public void ini() { System.out.println("aaa"); }
结果报错404
报错信息 /WEB-INF/jsp/pr.jsp
从报错信息来看 视图解析器默认将路径作为返回值进行拼接了
2.使用String作为返回值
@RequestMapping(value = "/pr") public String ini() { System.out.println("aaa"); return "hello"; }
结果:转发到/WEB-INF/jsp/hello.jsp中了
不使用视图解析器
有时候我并不想使用视图解析器进行转发那么怎么关闭视图解析器呢
有两种方式
1.使用@ResponseBody
@RequestMapping(value = "/pr")
@ResponseBody
public void ini() {
//不会报错404
}
@RequestMapping(value = "/pr")
@ResponseBody
public String ini() {
return "啊哈哈哈";
}
2.使用原生态: PrintWriter out = response.getWriter();
@RequestMapping(value = "/pr")
public void ini(HttpServletResponse response) throws IOException {
//设置 响应 字符 utf-8 告诉游览器 要用utf-8来解析
response.setCharacterEncoding("utf-8");
response.setContentType("text/html; charset=utf-8");
PrintWriter out = response.getWriter();
out.print("输出");
out.flush();
out.close();
}
视图解析器将会失效 返回值也将会失效 不行你 加返回值试试 结果都一样
请求和响应
ServletAPl原生态方法:
HttpServletRequest request , HttpServletResponse response
@RequestMapping(value = "/pr")
public void ini(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException {
//设置 请求 和响应 的格式都是 utf-8
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
//告诉游览器 要用utf-8来解析
response.setContentType("text/html; charset=utf-8");
// .............................
}
至于怎么用下面有,这就不用多说了
注意事项: 转发和重定向的区别
-
转发能访问本地所有资源包括WEB-INF
-
而重定向只能访问项目的根文件和webapp下的一级目录,在往下就找不到了
Model,ModelMap和ModeAndView
我对于他们的理解是和request一样
他们的区别: Model,ModelMap都一样(看爱好使用) ModeAndView多了一个视图解析器
Model使用
@RequestMapping(value = "/pr")
public String ini(Model model) {
model.addAttribute("userName","Huanmin");
return "hello";
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="/pr">点击</a>
</body>
</html>
hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>${requestScope.userName}</h1>
</body>
</html>
Huanmin
还可以存对象
@RequestMapping(value = "/pr")
public String ini(Model model) {
User user=new User();
user.setName("Huanmin");
user.setAge(22);
model.addAttribute("user",user);
return "hello";
}
获取对象值的方式
<h1>姓名:${requestScope.user.name}</h1>
<h1>年龄:${requestScope.user.age}</h1>
ModelMap的使用
和Model一样 会用Map接口就会用ModelMap
@RequestMapping(value = "/pr")
public String ini(ModelMap modelMap) {
User user=new User();
user.setName("Huanmin");
user.setAge(22);
modelMap.put("user",user);
return "hello";
}
ModelAndView使用
从字面意思来看就是在Model基础上增加了视图解析器的功能 其他功能不变
@RequestMapping(value = "/pr")
public ModelAndView ini() {
ModelAndView md =new ModelAndView();
// 向request 作用域存值
md.addObject("userName","Huanmin");
//调用视图解析器 进行转发
md.setViewName("hello");
return md;
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="/pr">点击</a>
</body>
</html>
hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>${requestScope.userName}</h1>
</body>
</html>
Huanmin
ModelAndView也能做为方法参数使用 省略了new 对象的过程
@RequestMapping(value = "/pr")
public ModelAndView ini(ModelAndView md) {
return md;
}
转发和重定向
有三种转发方式 ,两种重定向方式
转发:
-
使用原生API转发
@RequestMapping(value = "/pr1") public void ini1(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { //转发 request.getRequestDispatcher("/WEB-INF/jsp/hello.jsp").forward(request,response); }
-
使用关键字forward: 转发
使用关键字来进行转发时视图解析器将不运行
效果等同于原生API 但是需要利用返回值
@RequestMapping(value = "/pr1") public String ini1(){ return "forward:/WEB-INF/jsp/hello.jsp"; }
-
使用视图解析器转发
这种转发有限制 必须是视图解析器指定的目录 比如我的视图解析器目录WEB-INF/jsp 他只会访问这个目录下的文件
@RequestMapping(value = "/pr1") public String ini1(){ return "hello"; }
重定向:
-
使用原生API重定向
@RequestMapping(value = "/pr1") public void ini1(HttpServletResponse response) throws IOException { response.sendRedirect("http://boke.huitoushian.cn/"); }
-
使用关键字redirect: 重定向
@RequestMapping(value = "/pr1") public String ini1(){ return "redirect:http://boke.huitoushian.cn/"; }
方法和方法之间值传递
可以使用@SessionAttributes 来传递 但是这个是整个类所有方法共享的 我只想我下一个方法能接收到也就是(request作用范围)
有两种方法
-
使用原生API 进行转发
@RequestMapping(value = "/pr") public void ini(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setAttribute("name","Huanmin"); request.getRequestDispatcher("/pr1").forward(request,response); } @RequestMapping(value = "/pr1") @ResponseBody public void ini1(HttpServletRequest request) { String name = (String) request.getAttribute("name"); System.out.println("结果:"+name); }
-
使用Model
@RequestMapping(value = "/pr")
public String ini(Model model) {
model.addAttribute("name","Huanmin");
return "redirect:/pr1";
}
@RequestMapping(value = "/pr1")
@ResponseBody
public void ini1(@RequestParam("name") String name) {
System.out.println("结果:"+name);
}
必须使用redirect重定向 因为 model本身已经是request作用域了 会将存储的值显示在url上如果你在转发那么就会将url参数给清除了
使用原生API和Model注意事项
使用原生Apl传递,都要使用原生API接收 不能使用其他办法
传值
request.setAttribute
获取值
-
@RequestAttribute
-
request.getAttribute
而使用Model传值的时候model 而接收值的时候需要通过获取路径参数的方式
传值
model.addAttribute
获取值
-
@RequestParam
-
request.getParameter