Home | 簡體中文 | 繁體中文 | 雜文 | 打賞(Donations) | OSChina 博客 | Facebook | Linkedin | 知乎專欄 | Search | About

第 3 章 Spring MVC

目錄

3.1. @Controller
3.1.1. @RequestMapping
3.1.1.1. @RequestMapping("/")
3.1.1.2. 映射多個URL
3.1.1.3. headers
3.1.1.4. @GetMapping
3.1.1.5. @PostMapping
3.1.2. RequestMapping with Path Variables - @PathVariable
3.1.2.1. URL 參數傳遞
3.1.2.2. URL 傳遞 Date 類型
3.1.2.3. 處理特殊字元
3.1.2.4. @PathVariable 注意事項
3.1.3. RequestMapping with Request Parameters - @RequestParam
3.1.3.1. HTTP GET
3.1.3.2. HTTP POST
3.1.3.3. @RequestParam 傳遞特殊字元串
3.1.3.4. 傳遞日期參數
3.1.4. @RequestBody
3.1.4.1. @RequestBody 傳遞 List
3.1.4.2. 傳遞 Map 數據
3.1.5. @ModelAttribute
3.1.6. @CookieValue
3.1.7. @RequestHeader
3.1.8. @@SessionAttributes
3.1.9. @ResponseBody
3.1.9.1. 直接返回HTML
3.1.10. ModelAndView
3.1.10.1. 變數傳遞
3.1.10.2. ModelMap 傳遞多個變數
3.1.10.3. redirect
3.1.10.4. ArrayList
3.1.10.5. HashMap
3.1.10.6. 傳遞對象
3.1.10.7.
3.1.11. @CrossOrigin
3.1.12. @SessionAttributes
3.1.13. HttpServletRequest / HttpServletResponse
3.1.13.1. 用於方法參數
3.1.13.2. 注入方式
3.2. @RestController
3.2.1. 返回實體
3.2.2. JSON
3.2.3. XML
3.2.4. 兼容傳統 json 介面
3.2.5. @PageableDefault 分頁
3.3. @Scheduled 計劃任務
3.3.1. 每3秒鐘一運行一次
3.3.2. 凌晨23點運行
3.4. View
3.4.1. Using Spring’s form tag library
3.4.1.1. css
3.4.1.1.1. cssClass
3.4.1.1.2. cssStyle
3.4.1.1.3. cssErrorClass
3.4.1.2. cssClass
3.4.2. Thymeleaf
3.4.2.1. Maven pom.xml
3.4.2.2. Spring 配置
3.4.2.3. controller
3.4.2.4. HTML5 Template
3.4.3. FreeMarker
3.5. Properties
3.5.1. 載入*.properties檔案
3.5.2. @Value 註解
3.5.3. @PropertySource 註解
3.6. FAQ
3.6.1. o.s.web.servlet.PageNotFound
3.6.2. HTTP Status 500 - Handler processing failed; nested exception is java.lang.NoClassDefFoundError: javax/servlet/jsp/jstl/core/Config
3.6.3. 同時使用 Thymeleaf 與 JSP
3.6.4. 排除靜態內容
3.6.5. HTTP Status 406
3.6.6. Caused by: java.lang.IllegalArgumentException: Not a managed type: class common.domain.Article

Spring MVC 有兩種啟動模式,一種是傳統Tomcat,需要配置很多XML檔案。另一種方式是採用 Spring Boot 需要些一個Java程序,不需要寫xml檔案,這個程序會幫助你處理啟動所需的一切,並且採用嵌入方式啟動 Tomcat 或者 Jetty.

兩種方式各有優缺點,Tomcat 方式配置繁瑣,但是可以使用虛擬機,同一個IP地址使用不同域名訪問,出現不同的內容。而Spring Boot一個應用一個容器一個連接埠,比不得不通過連接埠來區分應用。

3.1. @Controller

package cn.netkiller.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class Welcome {

	@RequestMapping("/welcome")
	public ModelAndView helloWorld() {

		String message = "Helloworld!!!";
		return new ModelAndView("welcome", "message", message);
	}
}
	

3.1.1. @RequestMapping

@RequestMapping("/welcome")
		
@RequestMapping(value = "/list", method = RequestMethod.GET)
		
3.1.1.1. @RequestMapping("/")
			
package com.cf88.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/")
public class HelloController {

	@RequestMapping(value = "/{name}", method = RequestMethod.GET)
	public String getMovie(@PathVariable String name, ModelMap model) {
		model.addAttribute("name", name);
		return "hello";
	}

}		
			
			
3.1.1.2. 映射多個URL
@RequestMapping({ "/news/zh-cn", "/news/zh-tw" })
@ResponseBody
public String getNewsByPath() {
    return "Hello";
}
			
3.1.1.3. headers
			
@RequestMapping(value = "/news/json", method = GET, headers = "Accept=application/json")
@ResponseBody
public String getFoosAsJsonFromBrowser() {
    return "{...}";
}
			
			
curl -H "Accept:application/json,text/html" http://localhost:8080/spring/news/json.html
			
3.1.1.4. @GetMapping

@GetMapping 等效與 @RequestMapping

			
@RequestMapping(value = "/news/list", method = GET)			
			
			

範例

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

	@GetMapping("/finance/list")
	public String financeList() {
		return financeService.financeList();
	}
			
			
3.1.1.5. @PostMapping

@GetMapping 等效與 @RequestMapping

			
@RequestMapping(value = "/news/list", method = method = RequestMethod.POST)			
			
			

範例

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

	@PostMapping("/finance/list")
	public String financeList() {
		return financeService.financeList();
	}			
			
			

3.1.2. RequestMapping with Path Variables - @PathVariable

PATHINFO 變數可通過 @Pathvariable註解綁定它傳過來的值到方法的參數上。

3.1.2.1. URL 參數傳遞

需求,我們需要通過URL傳遞參數,所傳遞的值是分類ID與文章ID,例如 /news/1.html, /news/1/1.html。

			
package cn.netkiller.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class Pathinfo {
	@RequestMapping("/pathinfo/{id}")
	public ModelAndView urlTestId(@PathVariable String id) {

		return new ModelAndView("pathinfo/param", "id", id);
	}

	@RequestMapping("/pathinfo/{cid}/{id}")
	public ModelAndView urlTestId(@PathVariable String cid, @PathVariable String id) {

		ModelMap model = new ModelMap();

		model.addAttribute("cid", cid);
		model.addAttribute("id", id);

		return new ModelAndView("pathinfo/param", model);
	}
}
			
			

jsp測試檔案

			
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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>
${ cid } <br>
${ id } <br>
</body>
</html>
			
			
3.1.2.2. URL 傳遞 Date 類型

http://localhost:7000/history/2016-09-28%2000:00:00/

			
	@RequestMapping("/history/{datetime}")
	public String history(@PathVariable @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") Date datetime) throws Exception {

		System.out.println(datetime)

		return null;
	}			
			
			
3.1.2.3. 處理特殊字元

http://www.netkiller.cn/release/1.0.1

@RequestMapping(value = "/release/{version:[a-zA-Z0-9\\.]+}", method = RequestMethod.GET)  
public @ResponseBody  
String release(@PathVariable String version) {  
    log.debug("version: ", version);  
    return version;  
}
			

http://www.netkiller.cn/release/1.0.1/other

@RequestMapping(value="/release/{version:.+}",method=RequestMethod.GET)
public void download(HttpSession session,@PathVariable("version")String version){
	return version;
}
			
3.1.2.4. @PathVariable 注意事項

@PathVariable 參數傳統需要注意,參數中不能攜帶 “/”,斜杠會被視為目錄。

			
	@RequestMapping("/PathVariable/{code}.html")
	@ResponseBody
	public String urlTestId(@PathVariable String code) {
		return code;
	}
			
			

3.1.3. RequestMapping with Request Parameters - @RequestParam

@RequestParam 用來處理 HTTP GET/POST 請求的變數

import org.springframework.web.bind.annotation.RequestParam;
		
3.1.3.1. HTTP GET
			
	@RequestMapping("/request/param")
	@ResponseBody
	public String getBarBySimplePathWithRequestParam(@RequestParam("id") long id) {
	    return "Get a specific Bar with id=" + id;
	}
			
			

http://localhost:8080/Spring/request/param.html?id=100
			
3.1.3.2. HTTP POST
			
package cn.netkiller.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class Http {

	@RequestMapping("/http/form")
	public ModelAndView createCustomer(){
		ModelMap model = new ModelMap();

		model.addAttribute("email", "netkiller@msn.com");
		model.addAttribute("phone", "13113668890");

	    return new ModelAndView("http/form", model);
	}

	@RequestMapping(value= "/http/post", method = RequestMethod.POST)
	public ModelAndView saveCustomer(HttpServletRequest request,
	        @RequestParam(value="Email", required=false) String email,
	        @RequestParam(value="Password", required=false) String password,
	        @RequestParam(value="Phone", required=false) String phone){

		ModelMap model = new ModelMap();

		model.addAttribute("email", email);
		model.addAttribute("password", password);
		model.addAttribute("phone", phone);

	    return new ModelAndView("http/post", model);
	}

}
			
			

http/form.jsp

			
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!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>

	<form method="POST"
		action="http://localhost:8080/Spring/http/post.html" id="Register"
		name="Register">
		Email: <input class="register" type="text" id="Email" name="Email" value="${email}" /> <br />
		Password: <input class="register" type="password" id="Password" name="Password" value="" /><br />
		Phone: <input class="register" type="text" id="Phone" name="Phone" value="${phone}" /> <br />
		<input type="submit" id="btnRegister" name="btnRegister" value="Register" style="cursor: pointer" />
	</form>

</body>
</html>
			
			

http/post.jsp

			
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!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>
	${email}<br>
	${password}	<br>
	${phone} <br>
</body>
</html>
			
			
3.1.3.3. @RequestParam 傳遞特殊字元串

URL 中 “+” 有特殊意義,表示空格。

如果 @RequestParam 傳遞參數含有空格可以這樣處理。

			
	@RequestMapping("/RequestParam")
	@ResponseBody
	public String query(@RequestParam("code") String code) {

		return code.replace(" ", "+");

	}
			
			
3.1.3.4. 傳遞日期參數
			
	@RequestMapping("/range")
	public ModelAndView range(@RequestParam("beginDate") @DateTimeFormat(pattern = "yyyy-MM-dd") Date beginDate, @RequestParam("endDate") @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate) {
		log.info("===== Begin ===== {}", beginDate);

		// 你的邏輯

		log.info("===== End ===== {}", endDate);
		return new ModelAndView("activity/index", "message", "操作成功");
	}
			
			

3.1.4. @RequestBody

處理 raw 原始數據,例如提交的時 application/json, application/xml等

		
@RequestMapping(value = "/something", method = RequestMethod.PUT)  
public void handle(@RequestBody String body, Writer writer) throws IOException {  
	writer.write(body);  
} 
		
		
3.1.4.1. @RequestBody 傳遞 List
			
package cn.netkiller.api.restful;

import java.util.List;

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestRestController {

	@RequestMapping(value = "/test/list/{siteId}", method = RequestMethod.POST)
	public List<String> ping(@PathVariable("siteId") int siteId, @RequestBody List<String> tags) {
		System.out.println(String.format("%d, %s", siteId, tags));
		return (tags);
	}

}
			
			
			
$ curl -H "Content-Type: application/json" -X POST -d '["Neo","Netkiller"]' http://localhost:8440/test/list/22.json 

["Neo","Netkiller"]	
			
			
3.1.4.2. 傳遞 Map 數據
			
	@PostMapping("/finance/list")
	public String financeList(@RequestBody Map<String,String> map) {
		return financeService.financeList(map);
	}
			
			
			
% curl -H "Content-Type: application/json" -X POST -d '{"date":"2017-11-08"}' http://localhost:8440/finance/list.json			
			
			

3.1.5. @ModelAttribute

@ModelAttribute 處理 HTML FORM POST 提交

		
package cn.netkiller.pojo;

import java.util.List;

public class Deploy {

	private String group;
	private String envionment;
	private String project;
	private List<String> arguments;
	public Deploy() {
		// TODO Auto-generated constructor stub
	}
	// Getters & Setters
}
		
		
		
	@RequestMapping(value="/deploy/post",  method = RequestMethod.POST)
	public ModelAndView post(@ModelAttribute("deploy")Deploy deploy, BindingResult result) {
		if (result.hasErrors()) {
			System.out.println(result.toString());
        }
		System.out.println(deploy.toString());
		return new ModelAndView("output").addObject("output", deploy.toString());
	}		
		
		

3.1.6. @CookieValue

		
@RequestMapping("/sessionInfo")  
public void sessionInfo(@CookieValue("JSESSIONID") String cookie)  {

  //...  

}
		
		

3.1.7. @RequestHeader

		
@RequestMapping("/displayHeaderInfo")  
public void displayHeaderInfo(@RequestHeader("Accept-Encoding") String encoding,  
                              @RequestHeader("Keep-Alive") long keepAlive)  {  
  
  //...  
  
} 
		
		

3.1.8. @@SessionAttributes

@SessionAttributes: 該註解用來綁定HttpSession中的attribute對象的值,便于在方法中的參數里使用。 該註解有value、types兩個屬性,可以通過名字和類型指定要使用的attribute 對象;

		
@Controller  
@RequestMapping("/editProfile")  
@SessionAttributes("profile")  
public class ProfileForm {  
    // ...  
}  
		
		

3.1.9. @ResponseBody

import org.springframework.web.bind.annotation.ResponseBody;
		
3.1.9.1. 直接返回HTML
			
package cn.netkiller.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class Pathinfo {

	@RequestMapping(value = "/news/shenzhen/{numericId:[\\d]+}")
	@ResponseBody
	public String getNewsWithPathVariable(@PathVariable final long numericId) {
		return "Get a specific Bar with id=" + numericId;
	}

}

			
			

3.1.10. ModelAndView

3.1.10.1. 變數傳遞
	@RequestMapping("/testString")
	public ModelAndView helloWorld() {
		String message = "Helloworld!!!";
		return new ModelAndView("welcome", "message", message);
	}
			
	public ModelAndView handleRequestInternal() {

		ModelAndView mav = new ModelAndView("test");// 實例化一個VIew的ModelAndView實例
		mav.addObject("variable", "Hello World!");// 添加一個帶名的model對象
		return mav;
	}
			
3.1.10.2. ModelMap 傳遞多個變數

傳遞多個字元串

	@RequestMapping("/testModelMap")
	public ModelAndView testModelMap() {
		ModelMap model = new ModelMap();

		model.addAttribute("username", "Neo");
		model.addAttribute("password", "Netkiller");

		return new ModelAndView("test/modelmap", model);
	}
			

推薦使用ModelMap

			
	@RequestMapping("/testMapString")
	public ModelAndView testMapString() {

		Map<String,String> data = new HashMap<String,String>();
		data.put("username","Neo");
		data.put("password","Netkiller");
	    return new ModelAndView("test/modelmap",data);

	}
			
			
			
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!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=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
${username}<br>
${password}<br>
</body>
</html>
			
			
3.1.10.3. redirect
			
	@RequestMapping("/testRedirect")
	public ModelAndView testRedirect(){
		   RedirectView view = new RedirectView("testMapString.html");
		   return new ModelAndView(view);
	}
			
			
3.1.10.4. ArrayList
			
	@RequestMapping(value = "testList")
	public ModelAndView testList() {
		ModelAndView mav = new ModelAndView();
		mav.setViewName("/test/list");

		// List
		List<String> list = new ArrayList<String>();
		list.add("java");
		list.add("c++");
		list.add("oracle");
		mav.addObject("bookList", list);

		return mav;
	}
			
			
			
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!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=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
	${bookList}
	<br>

	<c:forEach items="${bookList}" var="node">
		<c:out value="${node}"></c:out><br>
	</c:forEach>

</body>
</html>
			
			
3.1.10.5. HashMap
			
	@RequestMapping("/testMap")
	public ModelAndView testMap() {
		ModelAndView mav = new ModelAndView();
		mav.setViewName("test/map"); // 返回的檔案名

		// Map
		Map<String, String> map = new HashMap<String, String>();
		map.put("Java", "http://www.netkiller.cn/java");
		map.put("PHP", "http://www.netkiller.cn/php");
		map.put("Home", "http://www.netkiller.cn");
		mav.addObject("channel", map);

		return mav;
	}
			
			
			
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!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=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
	<c:forEach items="${channel}" var="node">
		<a href="<c:out value="${node.value}"></c:out>"><c:out value="${node.key}"></c:out></a>
        <br/>
	</c:forEach>
</body>
</html>
			
			
3.1.10.6. 傳遞對象
			
	@RequestMapping("/testObject")
	public ModelAndView testObject() {
		ModelMap model = new ModelMap();

		User user = new User("neo", "passw0rd");
		model.addAttribute("user", user);
		return new ModelAndView("test/object", model);

	}
			
			
			
package cn.netkiller;

public class User {
	public String username;
	public String password;
	public User(String username, String password){
		this.username = username;
		this.password = password;
	}
	public String getUsername(){
		return this.username;
	}
	public String getPassword(){
		return this.password;
	}
}
			
			
			
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!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=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
Username: ${user.username}<br>
Password: ${user.password}<br>
</body>
</html>
			
			
3.1.10.7. 
			
			
			

3.1.11. @CrossOrigin

	@CrossOrigin(origins = "http://localhost:9000")
    @GetMapping("/greeting")
    public Greeting greeting(@RequestParam(required=false, defaultValue="World") String name) {
        System.out.println("==== in greeting ====");
        return new Greeting(counter.incrementAndGet(), String.format(template, name));
    }
		

3.1.12. @SessionAttributes

		
@Controller
@SessionAttributes("myRequestObject")
public class MyController {
  ...
}
		
		

3.1.13. HttpServletRequest / HttpServletResponse

3.1.13.1. 用於方法參數

HttpServletResponse 實例

			
package cn.netkiller.api.rest;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import api.util.MatrixToImageWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Hashtable;

@Controller
@RequestMapping("/public/QRCode")
public class QRCodeController {
    private static final Logger log = LoggerFactory.getLogger(QRCodeController.class);
	
    @RequestMapping("/create/{code}" )
    @ResponseBody
    public void create(@PathVariable String code, HttpServletResponse httpServletResponse) throws WriterException, IOException {
        log.info(code);
        if (code != null && !"".equals(code)){
            ServletOutputStream stream = null;
            try {
                String text = code; 	// 二維碼內容
                int width = 300; 		// 二維碼圖片寬度
                int height = 300; 		// 二維碼圖片高度
                String format = "gif";	// 二維碼的圖片格式

                Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
                hints.put(EncodeHintType.CHARACTER_SET, "utf-8");   // 內容所使用字符集編碼

                BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, hints);
                // 生成二維碼
                stream = httpServletResponse.getOutputStream();
                MatrixToImageWriter.writeToStream(bitMatrix, format, stream);

            }catch (WriterException e) {
                e.printStackTrace();
            } finally {
                if (stream != null) {
                    stream.flush();
                    stream.close();
                }
            }
        }
    }

    @RequestMapping("show")
    @ResponseBody
    public ModelAndView show(){

        return new ModelAndView("/qrcode/qrcode");
    }
}		
			
			
3.1.13.2. 注入方式