SpringMVC学习笔记-响应

SpringMVC响应

页面跳转(无数据)

什么是转发?

什么是重定向?

转发与重定向有什么区别?

两者的本质

两者内部机制的区别

页面访问快捷设定 (InternalResourceViewResolver)

带数据页面跳转

(1)使用HttpServletRequest类型形参进行数据传递

(2)使用Model类型形参进行数据传递

(3)使用ModelAndView类型形参进行数据传递,将该对象作为返回值传递给调用者

返回json数据


SpringMVC响应

页面跳转(无数据)

不论跳转的内容是返回数据、文件、页面,都可以将它们划归为一种形式——数据流

最终相应都是以的形式出现的。

在SpringMVC中,我们将方法的返回值设置为String,就可以return一个具体的返回值设置访问的页面

将页面跳转的案例之前,我们先提一下之前在Servlet中学习的转发重定向这两个概念!

什么是转发?

forward(转发)

是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容发给浏览器。浏览器根本不知道服务器发送的内容从哪里来的,因为这个跳转过程在服务器实现的,并不是在客户端实现的所以客户端并不知道这个跳转动作,所以它的地址栏还是原来的地址

什么是重定向?

redirect(重定向)

服务端根据逻辑,发送一个状态码告诉浏览器重新去请求那个地址,所以地址栏显示的是新的URL

转发是服务器行为,重定向是客户端行为。

转发与重定向有什么区别?

(1)从地址栏显示来说
forward:地址栏还是原来的地址

redirect:地址栏显示的是新的URL

(2)从数据共享来说
forward:转发页面和转发到的页面可以共享request里面的数据
redirect:不能共享数据

(3)从运用地方来说
forward:一般用于用户登陆的时候,根据角色转发到相应的模块
redirect:一般用于用户注销登陆返回主页面和跳转到其它的网站

(4)从效率来说
forward:
redirect:低

两者的本质

转发过程

客户浏览器发送http请求----》web服务器接受此请求–》调用内部的一个方法在容器内部完成请求处理和转发动作----》将目标资源发送给客户;在这里,转发的路径必须是同一个web容器下的url,其不能转向到其他的web路径上去,中间传递的是自己的容器内的request。在客户浏览器路径栏显示的仍然是其第一次访问的路径,也就是说客户是感觉不到服务器做了转发的。转发行为是浏览器只做了一次访问请求。

重定向过程

客户浏览器发送http请求----》web服务器接受后发送302状态码响应及对应新的location给客户浏览器–》客户浏览器发现是302响应,则自动再发送一个新的http请求,请求url是新的location地址----》服务器根据此请求寻找资源并发送给客户。在这里 location可以重定向到任意URL,既然是浏览器重新发出了请求,则就没有什么request传递的概念了。在客户浏览器路径栏显示的是其重定向的路径,客户可以观察到地址的变化的。重定向行为是浏览器做了至少两次的访问请求的。

两者内部机制的区别

(1)转发只能将请求转发给同一个WEB应用中的组件,而重定向还可以重新定向到同一站点不同应用程序中的资源,甚至可以定向到一绝对的URL。

(2)重定向可以看见目标页面的URL,转发只能看见第一次访问的页面URL,以后的工作都是有服务器来做的。

(3)请求响应调用者和被调用者之间共享相同的request对象和response对象,
重定向调用者和被调用者属于两个独立访问请求和响应过程。

(4)重定向跳转后必须加上return,要不然页面虽然跳转了,
但是还会执行跳转后面的语句,
转发是执行了跳转页面,下面的代码就不会在执行了。

下面的代码就是使用forward(转发)、redirect(重定向)

@RequestMapping("/showPage1")
public String showPage1() {
    System.out.println("user mvc com.Harmony.controller is running ...");
    return "forward:page.jsp";
}

@RequestMapping("/showPage2")
public String showPage2() {
    System.out.println("user mvc com.Harmony.controller is running ...");
    return "redirect:page.jsp";
}

我们可以观察地址栏

当我们输入localhost/showPage1时(forward)

当我们输入localhost/showPage2时(redirect)

如果我们将页面设置在WEB-INF目录下,那么只能使用forward的方式访问,使用redirect报错!但是很巧的是forward默认的格式。

即在若要跳转到WEB-INF目录下的页面,路径前面我们什么都不用写!因为redirect不能用,且默认的就是forward。

页面访问快捷设定 (InternalResourceViewResolver)

展示页面的保存位置通常固定,且结构相似,可以设定通用的访问路径,简化页面配置格式

我们在配置文件上配上bean

spring-mvc.xml 

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/page/"/>
    <property name="suffix" value=".jsp"/>
</bean>

 UserController

//页面简化配置格式,使用前缀+页面名称+后缀的形式进行,类似于字符串拼接
@RequestMapping("/showPage3")
public String showPage3() {
    System.out.println("user mvc com.Harmony.controller is running ...");
    return "page";
}

 我们可以将其理解为字符串拼接操作,前缀是:"/WEB-INF/page/",后缀是:".jsp"。将其和page拼接起来就是 /WEB-INF/page/page.jsp

注意:使用页面访问快捷设定不适用于forwardredirect,首先默认就是forward所以不用写就是它!其次是在WEB-INF目录下,所以重定向肯定不能用

还有可以比较冷门的知识,见下述代码:

@RequestMapping("/Page")
public void showPage5() {
    System.out.println("user mvc com.Harmony.controller is running ...");
}
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/page/"/>
    <property name="suffix" value=".jsp"/>
</bean>

访问路径是 /Page 并且没有使用返回值,即类型为void。就会将路径的名称与前缀后缀拼接起来形成最终的访问页。即为: /WEB-INF/page/Page.jsp

数据页面跳转

SpringMVC为我们提供了3种方式,分别为HttpServletRequest、ModelModelAndView

(1)使用HttpServletRequest类型形参进行数据传递

@RequestMapping("/showPageAndData1")
public String showPageAndData1(HttpServletRequest request) {
    request.setAttribute("name","Harmony");
    return "page";
}

 在ServletRequest类中有提供setAttribute()方法。它的用法与BOM中的setAttribute()用法一样

该方法添加指定的属性,并为其赋指定的值

如果这个指定的属性已存在,则仅设置/更改值。

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/page/"/>
    <property name="suffix" value=".jsp"/>
</bean>
<%@page pageEncoding="UTF-8" language="java" contentType="text/html;UTF-8" %>
<html>
<body>
<h1>页面跳转测试中.../WEB-INF/page/page.jsp</h1>
info:${name}<br/>
</body>
</html>

运行结果如下

显然这种方式我们可以在页面拿到数据,但是我们不会这么写!这是因为这种方式是Servlet提供的在SpringMVC中我们尽量不这么写

(2)使用Model类型形参进行数据传递

Model的内部就是用了request对象,可以用简单类型,也可以使用引用类型。

@RequestMapping("/showPageAndData2")
public String showPageAndData2(Model model) {
    model.addAttribute("name","Harmony");
    Book book = new Book();
    book.setName("SpringMVC入门实战");
    book.setPrice(66.6d);
    model.addAttribute("book",book);
    return "page";
}
<%@page pageEncoding="UTF-8" language="java" contentType="text/html;UTF-8" %>
<html>
<body>
<h1>页面跳转测试中.../WEB-INF/page/page.jsp</h1>
info:${name}<br/>
book的name:${book.name}<br/>
book的price:${book.price}<br/>
</body>
</html>

运行结果如下

(3)使用ModelAndView类型形参进行数据传递,将该对象作为返回值传递给调用者

该方式是SpringMVC最推荐的!

该方式返回值类型要设定为ModeAndView,添加数据用addObject(),设置页面用setViewName()

//使用ModelAndView形参传递参数,该对象还封装了页面信息
@RequestMapping("/showPageAndData3")
public ModelAndView showPageAndData3(ModelAndView modelAndView) {
    //ModelAndView mav = new ModelAndView();    替换形参中的参数
    Book book = new Book();
    book.setName("SpringMVC入门案例");
    book.setPrice(66.66d);
    
    //添加数据的方式,key对value
    modelAndView.addObject("book",book);
    //添加数据的方式,key对value
    modelAndView.addObject("name","Harmony");
    
    //设置页面的方式,该方法最后一次执行的结果生效
    modelAndView.setViewName("page");
    //返回值设定成ModelAndView对象
    return modelAndView;
}

注意:

setViewName()里面是传一个属性名,而setView()里面要求是一个对象!

<%@page pageEncoding="UTF-8" language="java" contentType="text/html;UTF-8" %>
<html>
<body>
<h1>页面跳转测试中.../WEB-INF/page/page.jsp</h1>
info:${name}<br/>
book的name:${book.name}<br/>
book的price:${book.price}<br/>
</body>
</html>

运行结果与之前的那个一样!

返回json数据

首先我们要在pom.xml中导入json有关的架包

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.10.4</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.5</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.0</version>
</dependency>

 在spring-mvc.xml中加上

<!--开启springmvc注解驱动,
    对@ResponseBody的注解进行格式增强,
    追加其类型转换的功能,
    具体实现由MappingJackson2HttpMessageConverter进行
-->
<mvc:annotation-driven/>
//转换集合类型数据
@RequestMapping("/showData5")
@ResponseBody
public List showData5() {
    Book book1  = new Book();
    book1.setName("SpringMVC入门案例");
    book1.setPrice(66.66d);

    Book book2  = new Book();
    book2.setName("SpringMVC入门案例");
    book2.setPrice(66.66d);

    ArrayList al = new ArrayList();
    al.add(book1);
    al.add(book2);
    return al;
}

运行结果

posted @   金鳞踏雨  阅读(15)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示