【SpringMVC学习05】响应数据和结果视图

  Spring MVC 在数据绑定的过程中,需要对传递数据的格式和类型进行转换,它既可以转换 String 类型的数据,也能够转换 JSON 等其他类型的数据。 这里介绍 String 等数据类型的转换和绑定, Spring MVC 中 JSON 类型的数据交互和 RESTful 支持进行详细讲解。

一、返回值分类

1、返回字符串

(1)Controller方法返回字符串可以指定逻辑视图的名称,根据视图解析器为物理视图的地址。

@Controller
public class HelloSpringMVC {
	@RequestMapping("/testPojo")
    public String testPojo(User user){
        System.out.println("testPojo:" + user);
        //跳转到XXX页面
        return SUCCESS;
    } 
}

(2)具体使用场景

@Controller 
@RequestMapping("/user") 
public class UserController {        
/**     
* 请求参数的绑定     
*/    
@RequestMapping(value="/initUpdate")    
public String initUpdate(Model model) {        
	// 模拟从数据库中查询的数据        
	User user = new User();        
	user.setUsername("张三");        
	user.setPassword("123");        
	user.setMoney(100d);        
	user.setBirthday(new Date());        
	model.addAttribute("user", user);        
	return "update";    
}    
}
 
    <h3>修改用户</h3>    
    ${ requestScope }    
    <form action="user/update" method="post">        
    姓名:<input type="text" name="username" value="${ user.username }"><br>        
    密码:<input type="text" name="password" value="${ user.password }"><br>        
    金额:<input type="text" name="money" value="${ user.money }"><br>        
    <input type="submit" value="提交">
    </form>

2、返回值是void

  1. 如果控制器的方法返回值编写成void,执行程序报404的异常,默认查找JSP页面没有找到。
    1. 默认会跳转到@RequestMapping(value="/initUpdate") initUpdate的页面。
  2. 可以使用请求转发或者重定向跳转到指定的页面
@RequestMapping(value="/initAdd")    
public void initAdd(HttpServletRequest request,HttpServletResponse response) throws Exception {        
   System.out.println("请求转发或者重定向");        
   // 请求转发         
   //request.getRequestDispatcher("/WEB-INF/pages/add.jsp").forward(request, response);        
   // 重定向       
   //response.sendRedirect(request.getContextPath()+"/add2.jsp");                
   response.setCharacterEncoding("UTF-8");        
   response.setContentType("text/html;charset=UTF-8");                // 直接响应数据        
   response.getWriter().print("你好");        
   return;    
   }

3、返回值是ModelAndView对象

  1. ModelAndView对象是Spring提供的一个对象,可以用来调整具体的JSP视图
  2. 具体的代码如下
/**    
 * 返回ModelAndView对象     
 * 可以传入视图的名称(即跳转的页面),还可以传入对象。     
 * @return    
  * @throws Exception     
 */    
@RequestMapping(value="/findAll")    
public ModelAndView findAll() throws Exception {        
   ModelAndView mv = new ModelAndView();        
   // 跳转到list.jsp的页面        
   mv.setViewName("list");                
   // 模拟从数据库中查询所有的用户信息        
   List<User> users = new ArrayList<>();        
   User user1 = new User();        
   user1.setUsername("张三");        
   user1.setPassword("123");                
   User user2 = new User();        
   user2.setUsername("赵四");        
   user2.setPassword("456");
   users.add(user1);        
   users.add(user2);        
   // 添加对象        
   mv.addObject("users", users);                
   return mv;    
}        


<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>        
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 <title>Insert title here</title> 
 </head> 
 <body>

   <h3>查询所有的数据</h3>   
    <c:forEach items="${ users }" var="user">        
   	 ${ user.username }    
    </c:forEach>
</body> 
</html>

二、SpringMVC框架提供的转发和重定向

1、forward请求转发

(1) controller方法返回String类型,想进行请求转发也可以编写成

/**    
* 使用forward关键字进行请求转发     
* @return     
* @throws Exception     
*/    
@RequestMapping("/delete")    
public String delete() throws Exception {        
	System.out.println("delete方法执行了...");            
    return "forward:/user/findAll";   
}

2、redirect重定向

/**    
* 使用redirect关键字进行重定向     
* @return     
* @throws Exception     
*/    
@RequestMapping("/delete")    
public String delete() throws Exception {        
	System.out.println("delete方法执行了...");            
    return "redirect:/user/findAll";   
}

三、ResponseBody响应json数

1、DispatcherServlet拦截资源问题

DispatcherServlet会拦截到所有的资源,导致一个问题就是静态资源(img、css、js)也会被拦截到,从而不能被使用。解决问题就是需要配置静态资源不进行拦截,在springmvc.xml配置文件添加如下配置

  1. mvc:resources标签配置不过滤
    1. location元素表示webapp目录下的包下的所有文件
    2. mapping元素表示以/static开头的所有请求路径,如/static/a 或者/static/a/b

2、 使用@RequestBody获取请求体数据

前台ajax请求如下:

// 页面加载       
$(function(){        
// 绑定点击事件        
	$("#btn").click(function(){            
		$.ajax({                
			url:"user/testJson",                
			contentType:"application/json;charset=UTF-8",                
			data:'{"username":"aa","password":"123"}',                
			dataType:"json",               
			type:"post",                
			success:function(data){                    
				alert(data);                    
				alert(data.username);                
				}            
			});        
		});    
	});

(1)后台获取请求体数据(string):

* 获取请求体的数据     
* @param body     
*/   
@RequestMapping("/testJson")    
public void testJson(@RequestBody String body) {        
	System.out.println(body);    
}

输出结果为一个Json字符串,{“username”:“aa”,“password”:“123”}
(2)同样的,如果使用JavaBean来接收,使用@RequestBody注解会把json的字符串转换成JavaBean的对象。如下:

* 获取请求体的数据     
* @param body     
*/   
@RequestMapping("/testJson")    
public void testJson(@RequestBody User user) {        
	System.out.println(user.getUsername());
	System.out.println(user.getPassword());    
}

SpringMVC就会自动封装到User对象的属性,就能打印出用户名及密码。

(3)使用@ResponseBody注解把JavaBean对象转换成json字符串,直接响应
要求方法返回JavaBean对象

/**
* 获取请求体的数据 并返回Json数据    
* @param body     
*/   
@RequestMapping("/testJson")    
@ResponseBody
public User testJson(@RequestBody User user) {        
   System.out.println(user.getUsername());
   System.out.println(user.getPassword());    
   user.setName("许你长欢");
   return user;
}

四、RESTful风格支持

  Spring MVC 除了支持 JSON 数据交互外,还支持 RESTful 风格的编程。 接下来就对 Spring MVC 中 RESTful 风格的编程进行简单的讲解。

1、什么是RESTful

  RESTful 也称之为 REST ( Representational State Transfer ),可以将它理解为一种软件架构风格或设计风格,而不是一个标准。
简单来说, RESTful 风格就是把请求参数变成请求路径的一种风格。 例如,传统的 URL 请 求格式为:

http://.../queryltems?id=l 

而采用 RESTful 风格后,其 URL 请求为:

http://.../items/l 

  从上述两个请求中可以看出, RESTful 风格中的 URL 将请求参数 id=1 变成了请求路径的一 部分,并且 URL 中的 queryltems 也变成了 items ( RESTful 风格中的 URL 不存在动词形式的路径,如 queryltems 表示查询订单,是一个动词,而 items 表示订单,为名词)。
  RESTful 风格在 HTIP 请求中,使用 put、 delete、 post 和 get 方式分别对应添加、删除、 修改和查询的操作。

2、应用案例

  在使用RESTful风格时,首先需要配置环境

  <!--配置前端控制器-->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--加载springmvc.xml配置文件-->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <!--启动服务器,创建该servlet-->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  本案例将采用 RESTful 风格的请求实现对用户信息的查询,同时返回 JSON 格式的数据。 其 具体实现步骤如下。
(1)在控制器类 UserController 中,编写用户查询方法 selectUser() ,代码如下所示。

/**
*接收 RESTful 风格的请求,其接收方式为 GET 
*/ 
@RequestMapping(value="/user/{id}" ,method=RequestMethod.Get) @ResponseBody 
public User selectUser(@PathVariable("id") String id) 
{ 
	//查看数据接收 
	System.out.println("id="+id); 
	User user=new User() ; 
	//模拟根据 id 查询出到用户对象数据 
	if (id.equals ("1234")){ 
	 	user.setUsername("tom"); 
	 }
	//返回 JSON 格式的数据 return 
	return user; 
}

  在上述代码中, @RequestMapping(value="/user/{id}",method=RequestMethod.GET)注解 用于匹配请求路径(包括参数)和方式。 其中 value="/user/{id}“表示可以匹配以 “/user/{id}” 结尾的请求, id 为请求中的动态参数; method=RequestMethod.GET 表示只接收 GET 方式的请求。 方法中的@PathVariable(“id”)注解则用于接收并绑定请求参数,它可以将请求 URL 中的变量映射到方法的形参上,如果请求路径为 “/user/{id}” ,即请求参数中的 id 和方法形参名称 id 一样,则 @PathVariable 后面的”(“id”)" 可以省略。

  上述可能看不出太大差别,下面再来个PUT请求的例子:

    /**
     * 用户注册接口
     * @param administrators
     * @return
     */
    @RequestMapping(value = "/webRegister",method = RequestMethod.PUT)
    @ResponseBody
    public String webRegister(@RequestBody Administrators administrators) throws JsonProcessingException {
        Map<String,Object> returnMap = new HashMap<String,Object>();
        if(webUserService.regist(administrators)){
            returnMap.put("state", DormiConstants.SUCCESS);
        }else {
            returnMap.put("state",DormiConstants.fail);
        }
        return objectMapper.writeValueAsString(returnMap);

    }

猜你喜欢

转载自blog.csdn.net/weixin_43800761/article/details/102807731