環境:Spring Boot 1.5.4html
基於 Spring Boot 能夠快速建立一個Web & Restful 應用,在開始應用以前,至少要了解如下用法:web
定義路由,定義 HTTP 方法spring
獲取Header、GET、POST、路徑等參數數組
Cookie、Session操做tomcat
應用一個模板引擎,選擇 Thymeleafcookie
獲取表單數據,以及文件上傳數據session
完成一個登錄、登出、註冊流程app
增長如下兩個依賴便可完成構建:框架
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
注意:當前版本默認選擇的 Thymeleaf 是 2.x 版本的,對html 標籤閉合性要求比較高,雖然能夠經過設置 mode,改變解析方式,可是還要引入額外的 nekoHTML,因此很蛋疼。不過能夠切換到 3.x 版本,兼容性未知。spring-boot
<properties> <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version> <thymeleaf-layout-dialect.version>2.1.1</thymeleaf-layout-dialect.version> </properties>
一旦添加了 spring-boot-starter-web 依賴 Spring Boot 會判斷這是一個Web 應用,並啓動一個內嵌的Servlet容器(默認是Tomcat)用於處理HTTP請求。
Spring 框架中關於 Web 應用有大量的註解:
@Controller
註解一個 Web 控制器類,框架會將 Servlet 容器裏收到的 HTTP 請求根據路徑分發給對應的 Controller 類進行處理
@RestController
註解一個 Restful 控制器,默認會自動返回 JSON
@RequestMapping
註解一個路由,若是定義在類上,至關於一個路由組,最終路由是類+方法路由,參數有路由規則和 HTTP 方法,同時還有一些簡寫形式如:@GetMapping
,@PutMapping
@PathVariable
註解路徑參數,如 /user/{id}
@RequestParam
註解請求參數,如 ?user=a 或 post['user'] = a
@RequestBody
註解請求體
@RequestHeader
註解請求header頭
@CookieValue
註解一個Cookie值
@SessionAttribute
註解一個Session值
下面代碼對應了兩個路由:
/
使用 @ResponseBody 註解,因此返回了文本串/hello
返回表示模板的字符串,將會使用 resources/templates/hello.html 模板渲染
@Controller public class IndexController { @RequestMapping("/") @ResponseBody public String index() { return "Spring Boot Index"; } @RequestMapping("/hello") public String hello(Model model) { model.addAttribute("title", "Spring Boot"); return "hello"; } }
這段代碼對應了 /rest/ 路由。注意 @RequestMapping 中空字符串與 "/" 的區別。
使用空,則 /rest 與 /rest/ 均可以訪問,使用 / 則必須經過 /rest 訪問:
@RestController @RequestMapping("/rest") public class RestfulController { @RequestMapping("") public String index() { return "Hello Rest"; } }
hello.html:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <title th:text="'Hello, ' + ${title}">title</title> </head> <body> <h1 th:text="'Hello, ' + ${title}">h1</h1> </body> </html>
@RequestParam
能夠用來註解一個請求參數,默認會合並 GET、POST 請求名相同的參數,變成一個數組,因此下面的 text2 會進行數組 -> String 的轉型。
@RequestMapping(value = "/get", method = {RequestMethod.GET, RequestMethod.POST}) @ResponseBody public String get(@RequestParam("text1") String text1, @RequestParam("text2") String text2) { return text1 + "/" + text2; }
在這裏不使用註解一樣能夠得到數據,那爲何要使用註解呢? 由於 @RequestParam
主要提供了一些額外的功能:
如參數名->變量名的映射,required 檢查等,更嚴謹一些。
@RequestMapping(value = "/getsimple", method = {RequestMethod.GET, RequestMethod.POST}) @ResponseBody public String getSimple(String text1, String text2) { return text1 + "/" + text2; }
除了使用 @RequestParam
註解獲取單個參數意外,還能夠獲取一個參數列表,但這種方式,POST 不會合並 GET 中的同名參數:
@RequestMapping("/getmap") @ResponseBody public String getMap(@RequestParam Map<String, Object> gets) { return gets.toString(); }
除了註解獲取數據之外,咱們還能夠經過向 Controller 中的方法,注入 Servlet 相關的類,來獲取一些額外的參數,好比客戶端 IP 地址
@RequestMapping("/request") @ResponseBody public String request(HttpServletRequest request) { HashMap<String, String> requests = new HashMap<>(); requests.put("Method", request.getMethod()); requests.put("QueryString", request.getQueryString()); requests.put("RequestURI", request.getRequestURI()); requests.put("getRequestURL", request.getRequestURL().toString()); requests.put("RemoteAddr", request.getRemoteAddr()); return requests.toString(); }
Cookie 的操做其實和 Spring 沒有太大的關係,不過Spring 提供了一個 @CookieValue
註解用來快速獲取 Cookie 值
經過 HttpServletResponse 設置頁面的 Cookie:
@RequestMapping("/setcookie") @ResponseBody public String setCookie(HttpServletResponse response) { Cookie cookie1 = new Cookie("cookie1", "value1"); cookie1.setMaxAge(1800); Cookie cookie2 = new Cookie("cookie2", "value2"); cookie2.setMaxAge(3600); response.addCookie(cookie1); response.addCookie(cookie2); return "cookie set ok"; }
經過 HttpServletRequest 或 @CookieValue 註解獲取 Cookie:
@RequestMapping("/getcookie") @ResponseBody public String getCookie(HttpServletRequest request, @CookieValue(value = "cookie1", required = false) String cookie1) { HashMap<String, String> map = new HashMap<>(); Cookie[] cookies = request.getCookies(); if (cookies != null) { for (Cookie cookie : cookies) { map.put(cookie.getName(), cookie.getValue()); } } logger.info(cookie1); return map.toString(); }
清空Cookie,就是從新設置cookie的值與過時時間:
@RequestMapping("/delcookie") @ResponseBody public String delCookie(HttpServletRequest request, HttpServletResponse response) { Cookie[] cookies = request.getCookies(); if (cookies != null) { for (Cookie cookie : cookies) { // setValue只是清空了value,cookie還在 cookie.setValue(null); cookie.setMaxAge(0); response.addCookie(cookie); } } return "delete ok"; }
Session的相關操做,經過 HttpSession、HttpServletRequest、@SessionAttribute 來完成。
設置 Session:
@RequestMapping("/setsession") @ResponseBody public String setSession(HttpSession session) { session.setAttribute("session1", "value1"); session.setAttribute("session2", "value2"); return ""; }
獲取Session:
@RequestMapping("/getsession") @ResponseBody public String getSession( HttpServletRequest request, HttpSession httpSession, @SessionAttribute(value = "session1", required = false) String session1) { HttpSession session = request.getSession(); String session2 = (String)session.getAttribute("session2"); String http_session1 = (String)httpSession.getAttribute("session1"); logger.info(http_session1); logger.info(session1); logger.info(session2); HashMap<String, String> sessionMap = new HashMap<>(); Enumeration<String> sessions = session.getAttributeNames(); while(sessions.hasMoreElements()) { String key = sessions.nextElement(); sessionMap.put(key, (String)session.getAttribute(key)); } return sessionMap.toString(); }
刪除Session:
@RequestMapping("/delsession") @ResponseBody public String delSession(HttpSession httpSession) { httpSession.removeAttribute("session1"); httpSession.removeAttribute("session2"); return "delete session ok"; }
在模板引擎以前,要了解怎麼向模板中傳遞數據,因而有這三種姿式:
Map,這是一個Java原生類型 ModelMap,這是一個類 Model,這是一個接口,其實現類爲 ExtendedModelMap,繼承了 ModelMap 類
這三個均可以在方法參數中直接注入使用,暫時不知道這三個有什麼區別,用起來差很少。
@RequestMapping("/model") public String model(Model model, ModelMap modelMap, Map<String, Object> map) { model.addAttribute("title1", "model_title"); modelMap.addAttribute("title2", "modelMap_title"); map.put("title2", "map_title"); User user = new User(1, "test"); model.addAttribute("user", user); return "model"; }
除了上面的用法,還可使用 ModelAndView 手動渲染模板,效果是同樣的:
@RequestMapping("/modelandview") public ModelAndView modelAndView() { ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("model"); modelAndView.addObject("title1", "title1"); modelAndView.addObject("title2", "title2"); User user = new User(1, "test"); modelAndView.addObject("user", user); return modelAndView; }
最後 SpringBoot 默承認以集成好幾種模板引擎,如今主要使用 thymeleaf。
這個註解有點複雜。能夠註解到方法上,也能夠註解到方法參數上
註解到方法參數
大概意思是經過模型中獲取,這個模型是什麼呢?大概經過一些途徑(可能來自Session?可能來自請求參數?可能來自控制器註解到方法上的 @ModelAttribute)
完成自動填充,而且自動傳遞到模板中,這是 Spring MVC 數據綁定。
下面是兩個例子:
請求經過 /xxx?id=1&name=張三,可以自動進行映射,而且傳到模板中,而且還能自動進行輸出格式轉換,以下面第一個例子,受 @ResponseBody 影響,直接輸出了 JSON
@RequestMapping("/getmodel") @ResponseBody public User getModel(@ModelAttribute User user) { return user; } @RequestMapping("/modelattribute") public String modelAttribute(@ModelAttribute User user) { return "model"; }
註解到方法
將這個控制器的方法,變成一個非請求處理的方法,在其它請求方法(RequestMapping)被調用前首先調用該方法,並將返回的數據放到 Model 中
有什麼用呢?
估計是用來生成初始化數據的,好比生成一個帶有一些默認數據的表單?在進入控制器以前對數據進行一些整理和清洗?
大多數 PHP 框架都有自動 trim GET/POST 參數的功能
在 Spring 裏面,能夠藉助 @InitBinder 註解能夠完成這種事情,咱們定義一個控制器基類,方便接受請求的控制器繼承
public class BaseController { @InitBinder protected void initBinder(WebDataBinder binder) { StringTrimmerEditor stringtrimmer = new StringTrimmerEditor(true); binder.registerCustomEditor(String.class, stringtrimmer); } }
server.address 綁定地址
server.port 綁定端口
server.compression.enabled 是否開啓壓縮
server.compression.mime-types 壓縮的類型
server.compression.min-response-size 壓縮的閾值
server.tomcat.* access日誌,日誌目錄,線程數等
server.session.cookie.* SessionCookie相關配置