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(視圖解析器),找到具體的視圖映射。
@Controllerpublic 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>
最後正常顯示: