Spring4 Spring MVC实战(四)——Spring MVC实现类struts通配符跳转,HMTL、Ajax和EasyUI的交互,405及406错误

1、通配符跳转

Spring4 Spring MVC实战(一)——读《Spring in action》搭建最简单的MVC。 只是配置了特定了路径。
但是想想要做到像struts一样的通配符匹配之后进行跳转,在Spring MVC中,这种就应该看文档。
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/原始的api文档
找到之后是有URI模板方法的: 我自己能想到的跳转方法也是这样的。


获取参数呢,查下资料也懂了,然后感觉相当厉害。
整个的Map也能获取了。不用像struts2一样通过ActionContext的getParameters获取Map。


而且这东西,真的是要结合用的才知道什么用。
访问:http://localhost:8080/project/spittle/3?a=8&b=2


@RequestMapping(value = "/spittle/{ownerId}",method= {RequestMethod.GET})  
public String spittle(@PathVariable String ownerId,@RequestParam("a") int petId,@RequestParam Map<String,String> allRequestParams) {
  System.out.println("uri parameter"+ownerId);//获取的uri中/spittle/{ownerId} ownerid的值 这里为3
  System.out.println("request parameter"+petId);//获取的是参数 参数a的值  这里为8


  //entrySet返回Set<Map.Entry<K,V>>,而Map.Entry 一个map entry就是一个键值对,getKey拿到key,getValue拿到value
  //代替keySet方法返回的是Set<k>,遍历Set后只取到key,再根据key从map中获取value
  for(Map.Entry<String, String> entry:allRequestParams.entrySet()){    
     System.out.println(entry.getKey()+"->"+entry.getValue());    
  }  //整个map的获取 这里能取到 a->8 b->2
  System.out.println(ownerId);
  return "spittle_"+ownerId;
}

所以要做到类通配符跳转,value = "/spittle/{ownerId}"这里根据自己的页面跳转进行配置然后return即可。


2、405错误

@RequestMapping(value = "/spittle/{ownerId}",method= {RequestMethod.POST}) 
如果只限定了POST方法,然后通过GET请求是会报405错误的。
改为method= {RequestMethod.POST,RequestMethod.GET}或者直接不限定即可。


3、前端页面的展示

前面做到了更加复杂的控制跳转,然后还能获取uri和前端请求参数。
接下来是要将后台处理的参数传递给前端。

@RequestMapping(value = "/spittle2",method= {RequestMethod.POST,RequestMethod.GET})  
public ModelAndView  ListData2() throws Exception {
  	ModelAndView model = new ModelAndView("ok");
  	String json = "{\"total\":10,\"rows\":[{\"a\":1,\"b\":\"ee\"}]}";
	model.addObject("msg", json);
	return model;
}
或者直接写成:
@RequestMapping(value = "/spittle2",method= {RequestMethod.POST,RequestMethod.GET})  
public ModelAndView  ListData2() throws Exception {
	return new ModelAndView("ok","msg", "{\"total\":10,\"rows\":[{\"a\":1,\"b\":\"ee\"}]}");
}

ModelAndView构造函数
public ModelAndView(Object view, String modelName,Object modelObject)
Convenient constructor to take a single model object.
Parameters:
view - View object to render (usually a Servlet MVC View object)
modelName - name of the single entry in the model
modelObject - the single model object


这里我们的view为ok,根据视图解析器,会找到/WEB-INF/views/ok.jsp
同时传递了model。

而此时ok.jsp显示msg的值非常简单,需要引用jstl。用的是EL表达式展示。
WEB-INF/views/ok.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
${msg}

更加复杂的数据展示就不说了,这里只是介绍最简单的值从后台到前端展示的一个过程。

4、与ajax的交互及406错误

一来就想着非跳转到页面时,如果不是在页面直接显示而是异步请求直接获取数据呢?经过不停地摸索之后我发现我的思路错了。完全错了。
错在我没弄清。

再回头看看Spring MVC实战(一)——读《Spring in action》搭建最简单的MVC所写的。流程中的第4和第5步。
在Controller(控制器)这里处理信息。打包模型数据还有视图名称给DispatcherServlet。
DispatcherServlet咨询view resolver(视图解析器),找到具体的视图映射。

@Controller
public class HomeController {
  @RequestMapping(value = "/test")
  public String helloWorld() {
      return "HelloWorld";
  }
}

正常这样,其实就是返回Hello World这样的视图名称,咨询视图解析器。

public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}

去找到/WEB-INF/views/HelloWorld.jsp

但是如果ajax请求不只是一个请求还想从请求中获取到数据的话,就不是跳转页面了,而是要从这个请求中直接
获取到返回数据。这在Spring MVC中怎么实现呢?——@ResponseBody

@ResponseBody有什么用呢,很神奇, the return type is written to the response HTTP body
是的,返回类型直接写到了response的HTTP body中。
相当于什么概念呢,你访问一个URI,页面展示的就是response所返回的东西,内容就是整个HTTP body中。

@ResponseBody
@RequestMapping(value = "/test")
public String helloWorld() {
  return "Hello World";
}


此时一访问是直接读取到response了。这是和页面跳转的区别。



http://localhost:8080/project/static/test.html:


<html>
<head>
<title>ajax交互</title>
<script type="text/javascript" src="../js/jquery/jquery.js"></script>
<script>
function test(){  
    $.ajax({  
    type:"GET",  
    url:"../hello",  
    error:function(data){  
        alert("出错!:"+data);  
    },  
    success:function(data){ 
    	alert(data);//直接弹出Hello world
        alert("success:"+data.a);  
        alert("success:"+data.b);  
    }  
    });  
}  	
</script>
</head>
<body>
	 <input type="submit" value="test" onclick="test();"/>
</body>
</html>

如果我们想返回json类型呢。Spring可以返回Map类型。
@RequestMapping(value = "/spittle",method= {RequestMethod.POST,RequestMethod.GET})  
public @ResponseBody Map  ListData() throws Exception {
  Map<String, Object> map = new HashMap<String, Object>();  
  map.put("a", "a");  
  map.put("b", 2);
  return map;
}

更改test.html的ajax请求url,success后获取的data就能获取到json串了。

不过这里就会出现406错误了。因为想想会知道,因为response直接展示Map这样一个
对象是不可能的,所以不可接受,但是如果字符串的话就简单了。


pom.xml添加依赖:
  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.4.0</version>
</dependency>

这样将map转成json串。添加jackson-databind,因为依赖关系jackson-annotations和jackson-core也会添加进来。


5、与EasyUI的交互。

EasyUI的Datagrid接受json串格式为:{"total":10,"rows":[{"a":1,"b":"ee"}]}

有些人数据没正常显示出来还给我了踩。
今天发现了问题。
因为在后台处理是,有些人为了避免使用转义字符。直接将双引号改为单引号。这样到EasyUI这边是识别不到数据的。
String json = "[{'id':1,'name':'ee','password':'1'}]";

这样datagrid根本就加载不到数据。改为转义字符正常
String json = "[{\"id\":1,\"name\":\"ee\",\"password\":\"1\"}]";

@RequestMapping(value = "/spittle",method= {RequestMethod.POST,RequestMethod.GET})  
public @ResponseBody Map  ListData() throws Exception {
  Map<String, Object> map = new HashMap<String, Object>();  
  map.put("a", 1);  
  map.put("b", 2);
  return map;
}

这样返回的map会转化为:{"total":"13","rows":{"a":1,"b":2}}

如果rows有多条呢,如何转化:成{"total":"13","rows":[{"a":1,"b":2},{"a":1,"b":2}]}
分析一下rows里面放的是数组,那么要将map置于数组中。

 @RequestMapping(value = "/spittle",method= {RequestMethod.POST,RequestMethod.GET})  
public @ResponseBody Map  ListData() throws Exception {
  Map<String, Object> bigmap = new HashMap<String, Object>();  
  Map<String, Object> map1 = new HashMap<String, Object>();  
  Map<String, Object> map2 = new HashMap<String, Object>();  
  bigmap.put("total", "13");  
  map1.put("a", 1);
  map2.put("a", 1);
  map1.put("b", 2);
  map2.put("b", 2);
  Map[] maparray = {map1,map2};
  bigmap.put("rows",maparray);  
  return bigmap;
}


WEB-INF/static/test2.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" type="text/css" href="../css/easyui/themes/default/easyui.css">   
<link rel="stylesheet" type="text/css" href="./css/easyui/themes/icon.css">
<script type="text/javascript" src="../js/easyui/jquery.min.js"></script>   
<script type="text/javascript" src="../js/easyui/jquery.easyui.min.js"></script> 
<script type="text/javascript" src="../js/easyui/easyui-lang-zh_CN.js"></script> 
<script>
	$(document).ready(function(){
		$('#table1').datagrid({
			nowrap: true,
			singleSelect: false,
			striped: true,
			fit: true,
			fitColumns:false,
			url:'../spittle',
			columns:[[ 
				{field:'a',title:'a',width:550,align: 'center'},
				{field:'b',title:'b',width:550,align: 'center'}
				
			]],
			pagination:true,
			rownumbers:true,
			pageNumber:1
		});		 
	});
	
</script>
</head>
<body>
	  <table id="table1"></table>
</body>
</html>



最后正常显示:




猜你喜欢

转载自blog.csdn.net/iaiti/article/details/52779362