Controller中方法的返回值
Controller中方法的返回值类型
在我们之前写的Controller的方法中,返回值都写的是ModelAndView,其实还可以返回其他类型的对象,在实际应用中需要根据不同的情况来使用不同的返回值:
- ModelAndView
- String
- void
- 自定义类型
返回ModelAndView
先来看下ModelAndView,这个是我们之前一直使用的返回值,如果Controller的方法执行完毕后,需要跳转到jsp或其他资源,且又要传递数据, 此时方法返回ModelAndView比较方便。
如果只传递数据,或者只跳转jsp或其他资源的话,使用ModelAndView就显得有些多余了。
返回String类型
如果controller中的方法在执行完毕后,需要跳转到jsp或者其他资源上,此时就可以让该方法返回String类型。
返回内部资源
创建一个Controller,方法返回String类型:
package com.monkey1024.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; /** * 方法返回String类型 */ @Controller public class ReturnStringController01 { @RequestMapping("/welcome.do") public String welcome() throws Exception{ //直接填写要跳转的jsp的名称 return "welcome"; } }
编写welcome.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> 欢迎你学习java! </body> </html>
在浏览器的地址栏中输入:
localhost:8080/welcome.do
则可以看到welcome.jsp中的内容。
返回外部资源
如果你需要在controller的方法中跳转到外部资源,比如跳转到:
http://www.monkey1024.com/
此时需要在springmvc.xml文件中配置一个BeanNameViewResolver类,即视图解析器。在springmvc.xml文件中添加下面内容:
<!-- 视图解析器 --> <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/> <!--定义外部资源view对象--> <bean id="monkey1024" class="org.springframework.web.servlet.view.RedirectView"> <property name="url" value="http://www.monkey1024.com/"/> </bean>
其中id是controller中的方法返回值,value是要跳转的外部资源的地址。
之后修改controller中的方法返回值:
@RequestMapping("/welcome.do") public String welcome() throws Exception{ //直接填写要跳转的jsp的名称 return "monkey1024"; }
此时在浏览器中输入:
localhost:8080/welcome.do
页面会跳转到
http://www.monkey1024.com/
这个就是跳转到外部资源的方式。
Model对象
之前简单说过这个Model,它是一个接口,写在controller的方法中的时候,spring mvc会为其进行赋值。我们可以使用Model对象来传递数据,也就是说我们可以使用Model传递数据并且将方法返回值设置为String类型,通过这种方式实现与方法返回ModelAndView一样的功能。
@RequestMapping("/welcome1.do") public String welcome1(String name,Model model) throws Exception{ //这种写法spring mvc会自动为传入的参数取名 model.addAttribute(name); model.addAttribute("username", name); //直接填写要跳转的jsp的名称 return "welcome"; }
在welcome.jsp中添加下面内容:
${username}<br> ${string}<br>
从浏览器的url中输入:
http://localhost:8080/welcome1.do?name=jack
可以看到页面中会显示两个jack
上面controller中使用了下面的写法:
model.addAttribute(name);
这种写法spring mvc会根据传入的参数对其进行取名,此时传入的参数name是一个String类型,因此会给他取名为string,即类似如下写法:
model.addAttribute("string", name);
这里面spring mvc的取名方式就是根据传入参数的类型来取名的,例如:
传入com.monkey1024.Product类型,会将其命名为"product"
com.monkey1024.MyProduct 命名为 "myProduct"
com.monkey1024.UKProduct 命名为 "UKProduct"
另外在Model接口中还有两个方法:
addAllAttributes(Collection<?> attributeValues);
会将传入的list中的数据对其进行命名,例如:
List<Integer> integerList = new ArrayList<>(); integerList.add(1); integerList.add(5); integerList.add(3); model.addAllAttributes(integerList);
上面代码相当于:
model.addAttribute("1", 1); model.addAttribute("5", 5); model.addAttribute("3", 3);
addAllAttributes(Map<string, ?=""> attributes);
会将map中的key作为名字,value作为值放入到model对象中,例如:
Map<String, Integer> integerMap = new HashMap<>(); integerMap.put("first", 1); integerMap.put("second", 2); integerMap.put("third", 3); model.addAllAttributes(integerMap);
上面代码相当于:
model.addAttribute("first", 1); model.addAttribute("second", 2); model.addAttribute("third", 3);
返回void
如果你不用spring mvc帮你完成资源的跳转,此时可以将controller中的方法返回值设置为void。一般情况下有下面两个应用场景:
- 通过原始的servlet来实现跳转
- ajax响应
先来看第一个,使用servlet来实现跳转,spring mvc底层就是servlet,因此我们可以在controller中使用servlet中的方法来实现页面的跳转,参数的传递。
package com.monkey1024.controller; import com.monkey1024.bean.School; import com.monkey1024.bean.Student; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 方法返回void */ @Controller public class ReturnVoidController01 { @RequestMapping("/returnVoid.do") public void welcome(HttpServletRequest request, HttpServletResponse response, Student student) throws Exception{ request.setAttribute("student", student); //因为使用servlet中的api,所以视图解析就不能使用了 request.getRequestDispatcher("/jsp/welcome.jsp").forward(request,response); } }
上面的写法跟之前在servlet中是一样的。
再来看下ajax响应,这块来使用下jQuery,先下载jQuery:
http://jquery.com/download/
拷贝到项目中webapp/js目录中,然后编写ajaxRequest.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <html> <head> <title>Title</title> <script src="/js/jquery-3.3.1.js"></script> </head> <body> <button id="ajaxRequest">提交</button> </body> <script> $(function () { $("#ajaxRequest").click(function () { $.ajax({ method:"post", url:"/ajaxRequest.do", data:{name:"monkey",age:18}, dataType:"json", success:function (result) { alert(result.name + "," + result.age); } }); }); }); </script> </html>
创建Controller,这里使用了fastjson,所以需要将fastjson的jar包导入到项目中:
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.46</version> </dependency>
在Controller中添加下面方法
@RequestMapping("/ajaxRequest.do") public void ajaxRequest(HttpServletRequest request, HttpServletResponse response, Student student) throws Exception{ PrintWriter out = response.getWriter(); String jsonString = JSON.toJSONString(student); out.write(jsonString); }
返回Object类型
倘若需要controller中的方法返回Object类型,需要先配置下面内容:
-
添加jackson的jar包,在Spring mvc中使用了jackson来进行json数据格式的转换。
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.4</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.4</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.9.4</version> </dependency>
- 在springmvc.xml文件中添加注解驱动。
<mvc:annotation-driven/>
上面两个配置缺一不可。
返回字符串
之前在controller方法中返回字符串,spring mvc会根据那个字符串跳转到相应的jsp中。这里返回的字符串会添加到响应体中传递到jsp页面中,此时需要在方法上添加一个注解@ResponseBody即可。
package com.monkey1024.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; /** * 方法返回Object类型 */ @Controller public class ReturnObjectController01 { @RequestMapping(value = "/returnString.do") @ResponseBody public Object returnString() throws Exception{ return "小猴子1024"; } }
在jsp中发送ajax请求:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <html> <head> <title>Title</title> <script src="/js/jquery-3.3.1.js"></script> </head> <body> <button id="ajaxRequest">提交</button> </body> <script> $(function () { $("#ajaxRequest").click(function () { $.ajax({ method:"post", url:"/returnString.do", success:function (result) { alert(result); } }); }); }); </script> </html>
上面的程序在执行结束后会出现乱码,此时需要在@RequestMapping中添加produces属性:
@Controller
public class ReturnObjectController01 {
@RequestMapping(value = "/returnString.do", produces = "text/html;charset=utf-8")
@ResponseBody
public Object returnString() throws Exception{
return "小猴子1024";
}
}
返回map类型
创建controller:
@Controller public class ReturnObjectController01 { @RequestMapping(value = "/returnString.do") @ResponseBody public Object returnString() throws Exception{ Map<String, String> map = new HashMap<>(); map.put("hello", "你好"); map.put("world", "世界"); return map; } }
jsp中添加ajax:
$(function () { $("#ajaxRequest").click(function () { $.ajax({ method:"post", url:"/returnString.do", success:function (result) { alert(result.hello); } }); }); });
除了这些之外还可以返回其他类型:List,基本数据类型的包装类,自定义类型等,这里就不演示了。
原文来自链接