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

禾白少二 2020-11-10 23:11:51
spring SpringBoot 框架 MVC 强化


Spring MVC 简介

在大型软件系统设计时,业务一般会相对复杂,假如所有业务实现的代码都纠缠在一起,会出现逻辑不清晰、可读性差,维护困难,改动一处就牵一发而动全身等问题。为了更好解决这个问题就有了我们现在常说的分层架构设计。

MVC 是什么

MVC是一种软件架构设计思想,基于MVC架构将我们的应用软件进行分层设计和实现,例如可以分为视图层(View),控制层(Controller),模型层(Model),通过这样的分层设计让我们程序具备更好的灵活性和可可扩展性.因为这样可以将一个复杂应用程序进行简化,实现各司其职,各尽所能.比较适合一个大型应用的开发.
视图(View) - UI设计人员进行图形界面设计,负责实现与用户交互。
控制器(Controller)- 负责获取请求,处理请求,响应结果。
模型(Model) - 实现业务逻辑,数据逻辑实现。
image.png

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,基本信息如图所示:

image.png

第二步:添加项目依赖(可以在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,这些资源可以在启动服务器以后,直接在浏览器进行访问。
image

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//[email protected][email protected]
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 + ''' +
'}';
}
}
版权声明
本文为[禾白少二]所创,转载请带上原文链接,感谢
https://segmentfault.com/a/1190000037792495

  1. 【计算机网络 12(1),尚学堂马士兵Java视频教程
  2. 【程序猿历程,史上最全的Java面试题集锦在这里
  3. 【程序猿历程(1),Javaweb视频教程百度云
  4. Notes on MySQL 45 lectures (1-7)
  5. [computer network 12 (1), Shang Xuetang Ma soldier java video tutorial
  6. The most complete collection of Java interview questions in history is here
  7. [process of program ape (1), JavaWeb video tutorial, baidu cloud
  8. Notes on MySQL 45 lectures (1-7)
  9. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  10. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  11. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  12. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  13. 【递归,Java传智播客笔记
  14. [recursion, Java intelligence podcast notes
  15. [adhere to painting for 386 days] the beginning of spring of 24 solar terms
  16. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)
  17. K8s Series Part 8 (service, endpoints and high availability kubeadm deployment)
  18. 【重识 HTML (3),350道Java面试真题分享
  19. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  20. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  21. [re recognize HTML (3) and share 350 real Java interview questions
  22. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  23. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  24. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  25. RPC 1: how to develop RPC framework from scratch
  26. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  27. RPC 1: how to develop RPC framework from scratch
  28. 一次性捋清楚吧,对乱糟糟的,Spring事务扩展机制
  29. 一文彻底弄懂如何选择抽象类还是接口,连续四年百度Java岗必问面试题
  30. Redis常用命令
  31. 一双拖鞋引发的血案,狂神说Java系列笔记
  32. 一、mysql基础安装
  33. 一位程序员的独白:尽管我一生坎坷,Java框架面试基础
  34. Clear it all at once. For the messy, spring transaction extension mechanism
  35. A thorough understanding of how to choose abstract classes or interfaces, baidu Java post must ask interview questions for four consecutive years
  36. Redis common commands
  37. A pair of slippers triggered the murder, crazy God said java series notes
  38. 1、 MySQL basic installation
  39. Monologue of a programmer: despite my ups and downs in my life, Java framework is the foundation of interview
  40. 【大厂面试】三面三问Spring循环依赖,请一定要把这篇看完(建议收藏)
  41. 一线互联网企业中,springboot入门项目
  42. 一篇文带你入门SSM框架Spring开发,帮你快速拿Offer
  43. 【面试资料】Java全集、微服务、大数据、数据结构与算法、机器学习知识最全总结,283页pdf
  44. 【leetcode刷题】24.数组中重复的数字——Java版
  45. 【leetcode刷题】23.对称二叉树——Java版
  46. 【leetcode刷题】22.二叉树的中序遍历——Java版
  47. 【leetcode刷题】21.三数之和——Java版
  48. 【leetcode刷题】20.最长回文子串——Java版
  49. 【leetcode刷题】19.回文链表——Java版
  50. 【leetcode刷题】18.反转链表——Java版
  51. 【leetcode刷题】17.相交链表——Java&python版
  52. 【leetcode刷题】16.环形链表——Java版
  53. 【leetcode刷题】15.汉明距离——Java版
  54. 【leetcode刷题】14.找到所有数组中消失的数字——Java版
  55. 【leetcode刷题】13.比特位计数——Java版
  56. oracle控制用户权限命令
  57. 三年Java开发,继阿里,鲁班二期Java架构师
  58. Oracle必须要启动的服务
  59. 万字长文!深入剖析HashMap,Java基础笔试题大全带答案
  60. 一问Kafka就心慌?我却凭着这份,图灵学院vip课程百度云