Spring MVC 简介

在大型软件系统设计时,业务个别会绝对简单,如果所有业务实现的代码都纠缠在一起,会呈现逻辑不清晰、可读性差,保护艰难,改变一处就牵一发而动全身等问题。为了更好解决这个问题就有了咱们当初常说的分层架构设计。

MVC 是什么

MVC是一种软件架构设计思维,基于MVC架构将咱们的应用软件进行分层设计和实现,例如能够分为视图层(View),管制层(Controller),模型层(Model),通过这样的分层设计让咱们程序具备更好的灵活性和可可扩展性.因为这样能够将一个简单应用程序进行简化,实现各司其职,各尽所能.比拟适宜一个大型利用的开发.
▪ 视图(View) - UI设计人员进行图形界面设计,负责实现与用户交互。
▪ 控制器(Controller)- 负责获取申请,解决申请,响应后果。
▪ 模型(Model) - 实现业务逻辑,数据逻辑实现。

Spring MVC 概述

Spring MVC是MVC设计思维在Spring框架中的一种实现,基于这样的思维spring框架设计了一些相干对象,用于更好的基于MVC架构解决申请和响应,其繁难架构如图所示:

1.前端控制器 DispatcherServlet是客户端所有申请解决的入口,负责申请转发。
2.处理器映射器 RequestMapping负责存储申请url到后端handler对象之间的映射。
3.处理器适配器 Handler 用于解决DispatcherServlet对象转发过去的申请数据。
4.视图解析器 ViewResolver负责解决所有Handler对象响应后果中的view。

Spring MVC 疾速入门

筹备工作

第一步:创立我的项目module,根本信息如图所示:

第二步:增加我的项目依赖(能够在module创立时,也能够创立后),代码如下:

Spring Web 依赖(提供了spring mvc反对并且会嵌入一个tomcat)

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

Thymeleaf 依赖(提供了以html作为页面模板进行解析和操作的相干对象)

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

static 目录剖析及利用

static 目录为springboot工程创立时增加了web依赖当前主动创立的目录,此目录中能够存储html、css、js、image,这些资源能够在启动服务器当前,间接在浏览器进行拜访。

templates 目录剖析及利用

templates 目录为springboot工程创立时增加了thymeleaf依赖当前主动创立的目录,此目录中要存储一些html模板,这个模板页面不能间接通过浏览器url进行拜访,须要基于后端控制器,在办法中定义页面响应

其中,如果default.html要在放在templates子目录中,则还须要在配置文件中配置thymeleaf的前缀

#server portserver.port=80#spring webspring.thymeleaf.prefix=classpath:/templates/health/spring.thymeleaf.suffix=.html#spring thymeleafspring.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;@Controllerpublic 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+@ResponseBodypublic 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;@RestControllerpublic 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 + ''' +                '}';    }}