springmvc请求返回一个字符_SpringMVC的Controller中常用的三种返回值类型

SpringMVC 通过注解实现的 Controller 常用的返回值类型主要有三种:返回字符串,返回 ModelAndView,返回 void。

先看一下项目的目录结构:

再看一下 springmvc.xml 配置文件的内容:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:tx="http://www.springframework.org/schema/tx"

xmlns:aop="http://www.springframework.org/schema/aop"

xmlns:mvc="http://www.springframework.org/schema/mvc"

xsi:schemaLocation="

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context.xsd

http://www.springframework.org/schema/tx

http://www.springframework.org/schema/tx/spring-tx.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop.xsd

http://www.springframework.org/schema/mvc

http://www.springframework.org/schema/mvc/spring-mvc.xsd">

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

返回字符串

应用场景1:直接返回视图名称,例如跳转到某个功能主页。

下面的 Controller 是用来处理用户页面的请求,gotoUserEdit 方法是用来处理跳转到用户编辑页面的请求。

package com.lyu.qjl.interview.controller;

import java.util.ArrayList;

import java.util.List;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.servlet.ModelAndView;

import com.lyu.qjl.interview.entity.User;

import com.lyu.qjl.interview.vo.UserVO;

/**

* 类名称:处理用户请求的handler

* 全限定性类名: com.lyu.qjl.interview.controller.UserController

* @author 曲健磊

* @date 2018年5月21日下午7:24:07

* @version V1.0

*/

@Controller

public class UserController{

/**

* 跳转到编辑用户页面

* @return

*/

@RequestMapping("/gotoUserEdit")

public String gotoUserEdit() {

return "userEdit";

}

}1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

这个 gotoUserEdit 方法匹配 /gotoUserEdit 请求。返回值为一个 userEdit 字符串,表示的是一个视图名,但是由于我们在 springmvc.xml 中已经配置了视图名的前缀和后缀,所以前端控制器实际上获得的视图名为 prefix配置的值 + returnStr(方法返回值) + suffix配置的值,即 /userEdit.jsp,所以页面最终会跳转到网站根目录下的 userEdit.jsp。

Question:我想访问某个页面我直接去输入这个页面的地址 /userEdit.jsp 不就可以了吗,为什么还要先去请求 SpringMVC,再由它返回?

Answer:对于 WebContent 这一层目录下面的页面,用户如果知道某个 jsp 页面可以直接访问。但是,通常情况下为了保证页面的安全,我们一般的做法是在 WebContent 这一层目录下只留一个引导页面(index.jsp)作为跳转,把网站相关的页面放入 WEB-INF 文件夹下保护起来。因为放在 WEB-INF 文件夹下的页面没有办法通过地址栏直接访问,只能通过后台的跳转来间接的访问,所以就需要请求 SpingMVC 来返回相应的页面。

实际应用中的 web 页面的目录结构:

注:login.jsp, main.jsp, userEdit.jsp, userList.jsp, userMain.jsp 都是放在 WEB-INF 这层目录下的,只有 index.jsp 是放在 WebContext 这一层下的。

测试:直接访问 WEB-INF 文件夹下的 login.jsp 页面的结果如下:

这样我们就没有办法直接从地址栏去访问 WEB-INF 下的 login.jsp 页面了,只能通过 SpringMVC 来进行页面的跳转了。

这里还需要注意一点:由于页面已经放到了 WEB-INF 目录下,所以 springmvc.xml 配置文件中的视图解析器中的前缀也要对应的有所改动:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:tx="http://www.springframework.org/schema/tx"

xmlns:aop="http://www.springframework.org/schema/aop"

xmlns:mvc="http://www.springframework.org/schema/mvc"

xsi:schemaLocation="

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context.xsd

http://www.springframework.org/schema/tx

http://www.springframework.org/schema/tx/spring-tx.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop.xsd

http://www.springframework.org/schema/mvc

http://www.springframework.org/schema/mvc/spring-mvc.xsd">

...

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

扩展:

大家注意到那个放在 WebContent 那一层目录下的 index.jsp 页面了吗?它在实际应用中有什么作用呢?

它一般配置为项目的欢迎页面,即 web.xml 中的 welcome-file。当我们在地址栏输入 localhost:8080/interview 的时候,首先就会访问该页面,然后由该页面向后台发请求,通过后台的 Controller 跳转到被 WEB-INF 文件夹保护起来的登录页面 login.jsp,最后,展现在我们面前的就是一个登录页面。

index.jsp 中的内容如下:

// 转发一个 "/login" 请求给后台的 Controller,由 Controller 返回 WEB-INF 目录下的 login.jsp 页面

request.getRequestDispatcher("/login").forward(request, response);

%>1

2

3

4

5

应用场景2:在登录成功的时候重定向到主页面,登录失败的时候转发回登录页面

String 类型的返回值除了返回一个可以被视图解析器解析的视图名以外,还可以返回 含有 redirect 或 forward 标签的字符串,如下:

package com.lyu.qjl.interview.controller;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.RequestMapping;

/**

* 类名称:用于处理登录请求的处理器

* 全限定性类名: com.lyu.qjl.interview.controller.LoginController

* @author 曲健磊

* @date 2018年5月21日下午7:02:03

* @version V1.0

*/

@Controller

public class LoginController{

@RequestMapping("/loginUser")

public String login(String username, String password, Model model) throws Exception {

if (username != null && password != null) {

if ("admin".equals(username) && "123".equals(password)) {

// 登录成功,重定向到主页面

return "redirect:/main";

} else {

// 向 request 域中设置错误提示信息

model.addAttribute("loginFlag", "用户名或密码错误");

// 登录失败,转发到登录页面

return "forward:/login";

}

} else {

// 只是把模型放到request域里面,并没有真正的安排好

model.addAttribute("loginFlag", "用户名或密码错误");

// 登录失败,转发到登录页面

return "forward:/login";

}

}

@RequestMapping("/login")

// 对外部提供接口的时候需要指定某些参数

public String login() {

return "login";

}

@RequestMapping("/main")

public String main() {

return "main";

}

}1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

redirect:/main 表示这是一个重定向到 /main 的请求, forward:/login 表示这是一个转发到 /login 的请求。

注意:如果在返回的字符串前加上了 redirect 或者 forward 标签,就不会走视图解析器,而是直接转发或重定向到指定的路径,所以对于重定向标签后面就不能加 WEB-INF ,因为重定向是客户端重新发送的请求,WEB-INF 目录下的页面仍然访问不到,但是对于转发标签的话后面可以跟 WEB-INF。

以上就是 Controller 的返回值为 String 时的另一种常见用途。

Question:为什么登录成功需要重定向到主页面?

Answer:因为转发客户端只发送了一次请求,如果登录成功转发到主页面的话,浏览器的地址栏中的 url 保留的是提交表单的请求,此时如果按 F5 刷新,就会造成二次提交表单,增大服务端的压力不说,还影响用户的体验,所以登录成功时要重定向到主页面,这样浏览器的地址栏保留的就是当前主页面的 url,无论怎么刷新都没事。

Question:为什么登录失败需要转发回登录页面?

Answer:用户登录失败,我们需要给用户提供相应的提示信息,如:“用户名密码不匹配”。如果重定向到登录页面,用户就没有办法获取到服务端设置在 request 域里面的错误提示信息,因为重定向的本质是客户端发送了两次请求,在第二次请求里面获取不到第一次请求中的数据,所以没有办法给用户相应的提示信息。而转发只发送了一次请求,转发回登录页面的时候可以获取到请求中的数据,所以登录失败时需要转发会登录页面。

返回ModelAndView

应用场景:其实这种返回值的应用场景比较随意,既可以用来做页面的跳转,也可以在跳转到页面的时候携带一些数据,例如:查询用户列表。

package com.lyu.qjl.interview.controller;

import java.util.ArrayList;

import java.util.List;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.servlet.ModelAndView;

import com.lyu.qjl.interview.entity.User;

import com.lyu.qjl.interview.vo.UserVO;

/**

* 类名称:处理用户请求的handler

* 全限定性类名: com.lyu.qjl.interview.controller.UserController

* @author 曲健磊

* @date 2018年5月21日下午7:24:07

* @version V1.0

*/

@Controller

public class UserController{

@RequestMapping("/getUserList")

public ModelAndView getUserList() {

System.out.println("进入getUseList");

ModelAndView modelAndView = new ModelAndView();

List userList = new ArrayList();

User user1 = new User("arry", 18, "男");

user1.setUserId(1L);

User user2 = new User("cc", 28, "女");

user2.setUserId(2L);

User user3 = new User("dd", 38, "男");

user3.setUserId(3L);

userList.add(user1);

userList.add(user2);

userList.add(user3);

// 将数据放入modelAndView对象

modelAndView.addObject("userList", userList);

// 将返回的逻辑视图名称放入modelAndView对象

modelAndView.setViewName("userList");

return modelAndView;

}

}1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

如果想在跳转到某个页面的时候携带一些数据,调用 ModelAndView 对象的 addObject 方法设置一些属性即可,不想带数据也可以不设置,但是必须得设置视图名 setViewName ,要不然它哪知道返回到哪个页面去呢?

返回void

如果是返回 void 会,就必须要在方法的参数中添加 HttpServletRequest 和 HttpServletResponse 来进行页面的跳转,代码如下:

public void test(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

// 转发到指定页面

request.getRequestDispatcher("xxx").forward(request, response);

// 或者重定向到指定页面

response.sendRedirect("/xxx");

}1

2

3

4

5

6

其实,从本质上来说前面两种方法(String,ModelAndView)就是间接调用的 request 和 response 这个两个对象来进行页面的跳转,以及数据的存储。

稍微的总结一下,这篇文章主要讲了 SpringMVC 的 Controller 的三种返回值类型:String,ModelAndView,void。在讲 String 的时候扩展了一些 redirect 和 forward 标签,提了一下在实际应用中转发和重定向的用处,以及实际项目中需要把页面放入 WEB-INF 目录里保护起来。ModelAndView 可以携带数据也可以不携带数据,以及前两种方法本质上都是在操作 request 和 response 对象。希望文章对大家能有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值