SpringBoot強化篇(四)--Spring MVC框架的整合及原理分析

Spring MVC 簡介

在大型軟件系統設計時,業務通常會相對複雜,假如全部業務實現的代碼都糾纏在一塊兒,會出現邏輯不清晰、可讀性差,維護困難,改動一處就牽一髮而動全身等問題。爲了更好解決這個問題就有了咱們如今常說的分層架構設計。css

MVC 是什麼

MVC是一種軟件架構設計思想,基於MVC架構將咱們的應用軟件進行分層設計和實現,例如能夠分爲視圖層(View),控制層(Controller),模型層(Model),經過這樣的分層設計讓咱們程序具有更好的靈活性和可可擴展性.由於這樣能夠將一個複雜應用程序進行簡化,實現各司其職,各盡所能.比較適合一個大型應用的開發.
▪ 視圖(View) - UI設計人員進行圖形界面設計,負責實現與用戶交互。
▪ 控制器(Controller)- 負責獲取請求,處理請求,響應結果。
▪ 模型(Model) - 實現業務邏輯,數據邏輯實現。
image.pnghtml

Spring MVC 概述

Spring MVC是MVC設計思想在Spring框架中的一種實現,基於這樣的思想spring框架設計了一些相關對象,用於更好的基於MVC架構處理請求和響應,其簡易架構如圖所示:
image.png
1.前端控制器 DispatcherServlet是客戶端全部請求處理的入口,負責請求轉發。
2.處理器映射器 RequestMapping負責存儲請求url到後端handler對象之間的映射。
3.處理器適配器 Handler 用於處理DispatcherServlet對象轉發過來的請求數據。
4.視圖解析器 ViewResolver負責處理全部Handler對象響應結果中的view。前端

Spring MVC 快速入門

準備工做

第一步:建立項目module,基本信息如圖所示:java

image.png

第二步:添加項目依賴(能夠在module建立時,也能夠建立後),代碼以下:web

Spring Web 依賴(提供了spring mvc支持而且會嵌入一個tomcat)spring

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Thymeleaf 依賴(提供了以html做爲頁面模板進行解析和操做的相關對象)json

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

static 目錄分析及應用

static 目錄爲springboot工程建立時添加了web依賴之後自動建立的目錄,此目錄中能夠存儲html、css、js、image,這些資源能夠在啓動服務器之後,直接在瀏覽器進行訪問。
imagesegmentfault

templates 目錄分析及應用

templates 目錄爲springboot工程建立時添加了thymeleaf依賴之後自動建立的目錄,此目錄中要存儲一些html模板,這個模板頁面不能直接經過瀏覽器url進行訪問,須要基於後端控制器,在方法中定義頁面響應
image
其中,假如default.html要在放在templates子目錄中,則還須要在配置文件中配置thymeleaf的前綴後端

#server port
server.port=80
#spring web
spring.thymeleaf.prefix=classpath:/templates/health/
spring.thymeleaf.suffix=.html
#spring thymeleaf
spring.thymeleaf.cache=false

定義HealthController類來測試瀏覽器

package com.cy.pj.health.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
@Controller
public class HealthController {//Handler對象 來處理DispatcherServlet分發過來的請求
    //三種狀況
    //1.只返回頁面
    //2.返回json字符串
    //3.返回頁面加參數
     @RequestMapping("/doPrint")
     @ResponseBody
     public void doPrint(HttpServletResponse response) throws Exception{
         Map<String,Object> map =new HashMap<>();
         map.put("username", "tony");
         map.put("state", true);
         //return map ;
         //將map中的數據轉換成json格式的字符串,底層實現以下
         ObjectMapper om=new ObjectMapper();
         String jsonStr=om.writeValueAsString(map);//jackson中轉換json字符串的方法
         System.out.println("jsonStr="+jsonStr);
         //將字符串響應到客戶端
         response.setCharacterEncoding("utf-8");//修改編碼方式
         response.setContentType("text/html;charset=utf-8");//告訴客戶端咱們的編碼格式讓其以這種方式解析數據
         PrintWriter pw = response.getWriter();//寫入響應流中
         pw.println(jsonStr);
     }
     @RequestMapping("/doHealth")
     public String doHealth(Model model) {
        model.addAttribute("username","張三");
        model.addAttribute("state","亞健康");
        return "default"; //返回的字符串交給ViewResolver視圖解析器,會自動分析,傳參且呈現頁面
     }
     @RequestMapping("/health.html")
     @ResponseBody
     //使用此註解描述控制方法時,用於告訴spring框架,這個方法返回值能夠按照特定格式(例json字符串)進行轉換,來響應客戶端
     //將轉換之後的結果寫到response對象的響應體中
     //f昂發的返回值再也不封裝爲ModelAndView對象,不會再交給視圖解析器進行解析,而是直接基於response對象響應到客戶端
     public Map<String, Object> doHealth(){
         Map<String,Object> map =new HashMap<>();
         map.put("username", "tony");
         map.put("state", true);
         return map ;
     }
    //public ModelAndView doHealth(){//此方法由DispatcherServlet對象經過反射調用
        //ModelAndView mv =new ModelAndView();
        //mv.setViewName("default");//viewname
        //mv.addObject("username","李四");
        //mv.addObject("state","亞健康");//傳的是個對象,因此能夠傳的不止字符串
        //return mv;
     //1.返回值會交給DispatcherServlet對象進行處理
     //2.DispatcherServlet對象會調用viewresolver對結果進行解析
     //2.1基於viewname找對應的view頁面(prefix+viewname+suffix)
     //2.2將model中的數據填充到view頁面上
     //2.3返回一個帶有module數據的頁面給DispatcherServlet
     //3.DispatcherServlet將帶有model數據的頁面返回給客戶端
    
    //public String doHealth(){
    //   return "default" ;// 能夠直接返回對應名字的頁面
    //    }
}

JSON數據響應

咱們有一業務不須要頁面,只須要將響應數據轉換爲json,而後響應到客戶端,如何實現呢?
第一步:定義ResponseResult對象用於封裝響應數據,例如:

package com.cy.pj.module.pojo;
public class ResponseResult {
    private Integer code;
    private String message;
    public Integer getCode() {
        return code;
    }
    public void setCode(Integer code) {
        this.code = code;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
}

第二步:定義JsonObjectController以及方法,代碼以下:

package com.cy.pj.health.controller;
import com.cy.pj.health.pojo.ResponseResult;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
@RestController//=@Controller+@ResponseBody
public class JsonObjectController {
    @RequestMapping("/doConvertResponseToJson")
    public ResponseResult doConvertResponseToJson(){
        ResponseResult rs=new ResponseResult();
 rs.setCode(200);
 rs.setMessage("OK");
 return rs;
 }
    @RequestMapping("/doConvertMapToJson")
    public Map<String,Object> doConvertMapToJson(){
        Map<String,Object> map=new HashMap<>();
 map.put("username","劉德華");
 map.put("state",true);
 return map;
 }
    @RequestMapping("/doPrintJSON")
    public void doPrint(HttpServletResponse response)throws Exception{
        Map<String,Object> map=new HashMap<>();
 map.put("username","劉德華");
 map.put("state",true);
 //將map中的數據轉換爲json格式字符串
 ObjectMapper om=new ObjectMapper();
 String jsonStr=om.writeValueAsString(map);
 System.out.println("jsonStr="+jsonStr);
 //將字符串響應到客戶端
 //設置響應數據的編碼
 response.setCharacterEncoding("utf-8");
 //告訴客戶端,要向它響應的數據類型爲text/html,編碼爲utf-8.請以這種編碼進行數據呈現
 response.setContentType("text/html;charset=utf-8");
 PrintWriter pw=response.getWriter();
 pw.println(jsonStr);
 }
}

SpingMVC 請求參數數據處理

咱們在執行業務的過程當中一般會將一些請求參數傳遞到服務端,服務端如何獲取參數並注入給咱們的方法參數的呢?

package com.cy.pj.health.controller;
import com.cy.pj.health.pojo.RequestParameter;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@RestController
public class ParamObjectController {
//    @GetMapping
//    @PostMapping
 //對請求加了限制類型,若是類型不匹配客戶端會報405錯誤(請求類型不匹配)
 @RequestMapping("/doParam01")
    public String doMethodParam(@RequestParam(required = false) String name){//直接量接收請求參數,參數名要與請求參數名相同
 //加了@RequestParam(required = false) 表示能夠傳參能夠不傳 若是註解不加required參數 會報錯400(參數類型數量不匹配)
 return "request params" +name;
 }
    @RequestMapping("/doParam02")
    public String doMethodParam(RequestParameter param){//pojo對象接收請求參數,pojo對象中需提供與參數名相匹配的set方法
 return "request params" +param.toString();
 }
    @RequestMapping("/doParam03")
    public String doMethodParam(@RequestParam Map<String,Object> param){//使用map接收參數時需使用註解@RequestParam對參數進行描述
 return "request params" +param.toString();
 }
}

POJO對象方式

定義pojo對象,用於接受客戶端請求參數,例如:

package com.cy.pj.module.pojo;
public class RequestParameter {
    private String name;
    //......
 public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
 public String toString() {
        return "RequestParam{" +
                "name='" + name + ''' +
                '}';
    }
}
相關文章
相關標籤/搜索