IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Spring MVC(一) -> 正文阅读

[Java知识库]Spring MVC(一)

一、SpringMVC

1、MVC

M:Model,模型层,指工程中的JavaBean,作用是处理数据

JavaBean分为两类:

  • 一类称为实体类Bean:专门存储业务数据的,如 Student、User 等

  • 一类称为业务处理 Bean:指 Service 或 Dao 对象,专门用于处理业务逻辑和数据访问。

V:View,视图层,指工程中的html或jsp等页面,作用是与用户进行交互,展示数据

C:Controller,控制层,指工程中的servlet,作用是接收请求和响应浏览器

MVC的工作流程:? 用户通过视图层发送请求到服务器,在服务器中请求被Controller接收,Controller调用相应的Model层处理请求,处理完毕将结果返回到Controller,Controller再根据请求处理的结果找到相应的View视图,渲染数据后最终响应给浏览器

2、SpringMVC概念

SpringMVC是spring框架的一个模块,springmvc和spring无需通过中间整合层进行整合。是一个WEB框架,基于MVC的理念而设计,是目前最主流的MVC框架之一。MVC的三个核心部件分别是:Model(模型)、View(视图)、Controller(控制器)。SpringMVC是Spring框架的一个模块,SpringMVC和Spring无需通过中间整合层进行整合。

  • SpringMVC3.0之后的版本超越了Struts2,成为最优秀的web框架。

  • SpringMVC通过MVC注解,让POJO成为处理请求的控制器,而且它不需要实现任何额外的接口。

  • SpringMVC支持REST风格的URL请求。

  • SpringMVC和其他MVC框架相比,具有更高的灵活性和可扩展性。

3、原理

客户端(浏览器)发送请求,直接请求到DispatcherServlet。

  1. DispatcherServlet根据请求信息调用HandlerMapping,解析请求对应的Handler。

  2. 解析到对应的Handler后,开始由HandlerAdapter适配器处理。

  3. HandlerAdapter会根据Handler来调用真正的处理器开处理请求,并处理相应的业务逻辑。

  4. 处理器处理完业务后,会返回一个ModelAndView对象,Model是返回的数据对象,View是个逻辑上的View。

  5. ViewResolver会根据逻辑View查找实际的View。

  6. DispaterServlet把返回的Model传给View。

  7. 通过View返回给请求者(浏览器)

4、优点

  • 利用一个Controller类, 完成某项业务的全部调用

  • 简化了配置

  • 参数获取非常灵活

5、组件

前端控制器

DispatcherServlet:Spring提供的前端控制器,所有的请求都有经过它来统一分发。在DispatcherServlet将请求分发给Spring Controller之前,需要借助于Spring提供的HandlerMapping定位到具体的Controller。

处理器映射器

HandlerMapping:它的作用是请求派发,负责请求和控制器建立对应的关系。它是由 DispatcherServlet 调用,DispatcherServlet 会从容器中取出所有 HandlerMapping 实例并遍历,让 HandlerMapping 实例根据自己实现类的方式去尝试查找 Handler。也就是说,DispatcherServlet要将一个请求交给哪个特定的Controller,它需要咨询一个Bean,这个Bean的名字为“HandlerMapping”。

控制器

Controller:负责处理由DispatcherServlet?分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model?,然后再把该Model?返回给对应的View?进行展示。

封装数据信息和视图信息的模型

ModelAndView:使用ModelAndView类用来存储处理完后的结果数据,以及显示该数据的视图。从名字上看ModelAndView中的Model代表模型,View代表视图,这个名字就很好地解释了该类的作用。业务处理器调用模型层处理完用户请求后,把结果数据存储在该类的model属性中,把要返回的视图信息存储在该类的view属性中,然后让该ModelAndView返回该Spring MVC框架。框架通过调用配置文件中定义的视图解析器,对该对象进行解析,最后把结果数据显示在指定的页面上。 ? ? ?

视图解析器

ViewResolver?的主要作用是把一个逻辑上的视图名称解析为一个真正的视图。

6、三层架构

dao->数据层

service -> 业务实现

web? ->? web 接口

或者

common—>公共方法,公共类,工具类,只有关键地方加日志

dao->数据层,不加日志

domain->实体类,不加日志

rpc->调用接口,出入参加日志

sdk->? 给外部提供sdk,例如对外接口,只是提供接口定义,该层没有业务逻辑,真实的sdk逻辑实现是在service层,不加日志

service -> 业务实现逻辑,单元测试进行层,日志接入:关键地方可以加, 实现sdk层的接口方法出入参加日志

web? ->? web 接口,对外提供http 接口,一般都有逻辑,http 是直接对 c的,看到的ip 是c端用户的,出入参加日志

(1)、service层

业务层,用来实现业务逻辑。能调用dao层或者service层,返回数据对象DO或者业务对象BO,BO通常由DO转化、整合而来,可以包含多个DO的属性,也可以是只包含一个DO的部分属性。通常为了简便,如果无需转化,service也可以直接返回DO。外部调用(HTTP、RPC)方法也在这一层,对于外部调用来说,service一般会将外部调用返回的DTO转化为BO。是专注业务逻辑,对于其中需要的数据库操作,都通过Dao层去实现。主要去负责一些业务处理,比如取得连接、关闭数据库连接、事务回滚,一些复杂的逻辑业务处理就放到service层。

(2)、DAO层

负责访问数据库进行数据的操作,取得结果集,之后将结果集中的数据取出封装到VO类对象之后返回给service层。数据层,直接进行数据库的读写操作,返回数据对象DO,DO与数据库表一一对应。Dao的作用是封装对数据库的访问:增删改查,不涉及业务逻辑,只是达到按某个条件获得指定数据的要求。

在实际开发中dao层要先定义出自己的操作标准即标准接口,就是为了解耦合。

(3)、Cotroller层

控制层,主要的功能是处理用户发送的请求。主要处理外部请求。调用service层,将service层返回的BO/DO转化为DTO/VO并封装成统一返回对象返回给调用方。如果返回数据用于前端模版渲染则返回VO,否则一般返回DTO。不论是DTO还是VO,一般都会对BO/DO中的数据进行一些转化和整合,比如将gender属性中的0转化“男”,1转化为“女”等。controller的功能主要有5点:参数校验、调用service层接口实现业务逻辑、转换业务/数据对象、组装返回对象、异常处理。

(4)、View层

又叫显示层,主要是负责前台jsp页面的表示

二、HelloSpringMVC

使用注解开发SpringMVC程序

导入依赖

<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
? ? <groupId>org.springframework</groupId>
? ? <artifactId>spring-webmvc</artifactId>
? ? <version>5.2.9.RELEASE</version>
</dependency>

<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
<dependency>
? ? <groupId>javax.servlet.jsp</groupId>
? ? <artifactId>jsp-api</artifactId>
? ? <version>2.2.1-b03</version>
? ? <scope>provided</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
? ? <groupId>javax.servlet</groupId>
? ? <artifactId>javax.servlet-api</artifactId>
? ? <version>4.0.1</version>
? ? <scope>provided</scope>
</dependency>

<dependency>
? ? <groupId>org.springframework</groupId>
? ? <artifactId>spring-webmvc</artifactId>
? ? <version>5.3.9</version>
</dependency>

编写Web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
? ? ? ?? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
? ? ? ?? xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
? ? ? ?? version="4.0">

? ? <display-name>Archetype Created Web Application</display-name>
? ? <!--配置DispachServlet-->
? ? <servlet>
? ? ? ? <servlet-name>springmvc</servlet-name>
? ? ? ? <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
? ? ? ? <init-param>
? ? ? ? ? ? <param-name>contextConfigLocation</param-name>
? ? ? ? ? ? <param-value>classpath:springmvc-servlet.xml</param-value>
? ? ? ? </init-param>
? ? ? ? <load-on-startup>1</load-on-startup>
? ? </servlet>
? ? <servlet-mapping>
? ? ? ? <servlet-name>springmvc</servlet-name>
? ? ? ? <url-pattern>/hellomvc</url-pattern>
? ? </servlet-mapping>
</web-app>

编写springmvc-servlet.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
? ? ?? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
? ? ?? xsi:schemaLocation="http://www.springframework.org/schema/beans
? ? ? ? https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">

? ? <!-- 添加处理映射器 -->
? ? <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
? ? <!-- 添加处理器适配器 -->
? ? <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
? ? <!--视图解析器:DispatcherServlet给他的ModeLAndView-->
? ? <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver"/>
? ? <!--前缀-->
? ? <!--前缀-->
? ? <property name="prefix" value="/WEB-INF/jsp/"/>
? ? <!--后缀-->
? ? <property name="suffix" value=".jsp"/>

? ? ? ? <!-- handler -->
? ? <bean name="/hello" class="com.biibili.spring.HelloController" />
</beans>

编写HelloController

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

//注意: 这里我们先导入Controller接口
public class HelloController implements Controller {
? ? @Override
? ? public ModelAndView handleRequest (HttpServletRequest request, HttpServletResponse response) throws Exception {
? ? ? ? //ModeLAndView模型和视图
? ? ? ? ModelAndView mv = new Mode1AndView();
? ? ? ? //封装对象,放在ModeLAndView中
? ? ? ? mv.addobject("msg","HelloSpringMVC!");
? ? ? ? //封装要跳转的视图,放在ModelAndView中
? ? ? ? mv.setViewName("hello"); //: /WEB-INF/jsp/hello.jsp
? ? ? ? return mv;
? ? }
}

编写hello.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
? <head>
? ? <title>springmvc</title>
? </head>
? <body>
? $END$
? </body>
</html>

三、RestFul

1、概念

一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

2、URL定义

资源:互联网所有的事物都可以被抽象为资源?? 资源操作:使用POST、DELETE、PUT、GET,使用不同方法对资源进行操作。?? 分别对应 添加、 删除、修改、查询。

3、传统方式操作资源?

http://127.0.0.1/item/queryUser.action?id=1?? 查询,GET

http://127.0.0.1/item/saveUser.action? ? ? ? ? ?? 新增,POST

http://127.0.0.1/item/updateUser.action? ? ? ? ? 更新,POST

http://127.0.0.1/item/deleteUser.action?id=1? 删除,GET或POST

4、使用RestFul操作资源?

【GET】 /users # 查询用户信息列表

【GET】 /users/1001 # 查看某个用户信息

【POST】 /users # 新建用户信息

【PUT】 /users/1001 # 更新用户信息(全部字段)

【PATCH】 /users/1001 # 更新用户信息(部分字段)

【DELETE】 /users/1001 # 删除用户信息

四、重定向和转发

1、重定向

客户发送一个请求到服务器,服务器匹配servlet,这都和请求转发一样,servlet处理完之后调用了sendRedirect()这个方法,这个方法是response的方法,所以,当这个servlet处理完之后,看到response.senRedirect()方法,立即向客户端返回这个响应,响应行告诉客户端你必须要再发送一个请求,去访问test.jsp,紧接着客户端受到这个请求后,立刻发出一个新的请求,去请求test.jsp,这里两个请求互不干扰,相互独立,在前面request里面setAttribute()的任何东西,在后面的request里面都获得不了。可见,在sendRedirect()里面是两个请求,两个响应。

redirect重定向的三种方式:

(1)、response.sendRedirect重定向跳转

@RequestMapping(value="/testredirect",method = { RequestMethod.POST, RequestMethod.GET })  
public ModelAndView testredirect(HttpServletResponse response){      
response.sendRedirect("/index");     return null; }

(2)、ViewResolver直接跳转

不带参数

@RequestMapping(value="/testredirect",method = { RequestMethod.POST, RequestMethod.GET })? 
public? String testredirect(HttpServletResponse response){? 
? ? return "redirect:/index";? 
} 

带参数

@RequestMapping("/testredirect")
public String testredirect(Model model, RedirectAttributes attr) {
	attr.addAttribute("test", "51gjie");//跳转地址带上test参数
? ? attr.addFlashAttribute("u2", "51gjie");//跳转地址不带上u2参数
	return "redirect:/user/users";
}
  • 使用RedirectAttributes的addAttribute方法传递参数会跟随在URL后面,如上代码即为http:/index.action?test=51gjie

  • 使用addFlashAttribute不会跟随在URL后面,会把该参数值暂时保存于session,待重定向url获取该参数后从session中移除,这里的redirect必须是方法映射路径,jsp无效。你会发现redirect后的jsp页面中b只会出现一次,刷新后b再也不会出现了,这验证了上面说的,b被访问后就会从session中移除。对于重复提交可以使用此来完成.

  • spring mvc设置下RequestMappingHandlerAdapter 的ignoreDefaultModelOnRedirect=true,这样可以提高效率,避免不必要的检索。

(3)、ModelAndView重定向

不带参数

@RequestMapping(value="/restredirect",method = { RequestMethod.POST, RequestMethod.GET })? 
public? ModelAndView restredirect(String userName){? 
? ? ModelAndView? model = new ModelAndView("redirect:/main/index");? ? 
? ? return model;? 
}

带参数

@RequestMapping(value="/toredirect",method = { RequestMethod.POST, RequestMethod.GET })? 
public? ModelAndView toredirect(String userName){? 
? ? ModelAndView? model = new ModelAndView("/main/index");?? 
? ? model.addObject("userName", userName);? //把userName参数带入到controller的RedirectAttributes
? ? return model;? 
}

2、转发

(1)、ModelAndView

设置ModelAndView对象 , 根据view的名称 , 和视图解析器跳到指定的页面 .

页面 : {视图解析器前缀} + viewName +{视图解析器后缀}

<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
? ? ? id="internalResourceViewResolver">
? ? <!-- 前缀 -->
? ? <property name="prefix" value="/WEB-INF/jsp/" />
? ? <!-- 后缀 -->
? ? <property name="suffix" value=".jsp" />
</bean>

对应的controller类

public class ControllerTest1 implements Controller {
 
? ? public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
? ? ? ? //返回一个模型视图对象
? ? ? ? ModelAndView mv = new ModelAndView();
? ? ? ? mv.addObject("msg","ControllerTest1");
? ? ? ? mv.setViewName("test");
? ? ? ? return mv;
? ? }
}

(2)、ServletAPI

通过设置ServletAPI , 不需要视图解析器 .

1、通过HttpServletResponse进行输出

2、通过HttpServletResponse实现重定向

3、通过HttpServletResponse实现转发

@Controller
public class ResultGo {
 
? ? @RequestMapping("/result/t1")
? ? public void test1(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
? ? ? ? rsp.getWriter().println("Hello,Spring BY servlet API");
? ? }
 
? ? @RequestMapping("/result/t2")
? ? public void test2(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
? ? ? ? rsp.sendRedirect("/index.jsp");
? ? }
 
? ? @RequestMapping("/result/t3")
? ? public void test3(HttpServletRequest req, HttpServletResponse rsp) throws Exception {
? ? ? ? //转发
? ? ? ? req.setAttribute("msg","/result/t3");
? ? ? ? req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req,rsp);
? ? }
 
}

(3)、SpringMVC

通过SpringMVC来实现转发和重定向 - 无需视图解析器;

测试前,需要将视图解析器注释掉

@Controller
public class ResultSpringMVC {
? ? @RequestMapping("/rsm/t1")
? ? public String test1(){
? ? ? ? //转发
? ? ? ? return "/index.jsp";
? ? }
 
? ? @RequestMapping("/rsm/t2")
? ? public String test2(){
? ? ? ? //转发二
? ? ? ? return "forward:/index.jsp";
? ? }
 
? ? @RequestMapping("/rsm/t3")
? ? public String test3(){
? ? ? ? //重定向
? ? ? ? return "redirect:/index.jsp";
? ? }
}

通过SpringMVC来实现转发和重定向 - 有视图解析器;

重定向 , 不需要视图解析器 , 本质就是重新请求一个新地方嘛 , 所以注意路径问题.

可以重定向到另外一个请求实现

@Controller
public class ResultSpringMVC2 {
? ? @RequestMapping("/rsm2/t1")
? ? public String test1(){
? ? ? ? //转发
? ? ? ? return "test";
? ? }
 
? ? @RequestMapping("/rsm2/t2")
? ? public String test2(){
? ? ? ? //重定向
? ? ? ? return "redirect:/index.jsp";
? ? ? ? //return "redirect:hello.do"; //hello.do为另一个请求/
? ? }
}

五、数据处理

1、处理提交数据

(1)、提交的域名称和Controller处理方法的参数名一致

提交数据 : http://localhost:8080/SpringMVC/test/t?name=张三

处理方法 :

@Controller
@RequestMapping("test")
public class RedirectController {

? ? @RequestMapping("t")
? ? public String Test3(String name){

? ? ? ? return "/test";
? ? }
}

(2)、提交的域名称和Controller处理方法的参数名不一致

通过@RequestParam映射,提交数据 : http://localhost:8080/SpringMVC/test/t?username=张三

处理方法 :

@Controller
@RequestMapping("test")
public class RedirectController {

? ? @RequestMapping("t")
? ? public String Test3(@RequestParam("username")String name){

? ? ? ? return "/test";
? ? }
}

(3)、提交的是一个对象

要求提交的表单域和对象的属性名一致 ?, 参数使用对象即可

1、实体类

public class User {
? ? private int id;
? ? private String name;
? ? private int age;
? ? //构造
? ? //get/set
? ? //tostring()
}

2、提交数据? : http://localhost:8080/SpringMVC/test/t?name=张三&sex=男&age=18

3、处理方法 :

@RequestMapping("test")
public String user(User user){
? ? System.out.println(user);
? ? return "/test";
}

2、数据显示到前端

ModelAndView 可以在储存数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的跳转;

ModelMap 继承了 LinkedMap ,除了实现了自身的一些方法,同样的继承 LinkedMap 的方法和特性;

Model 只有寥寥几个方法只适合用于储存数据,简化了新手对于Model对象的操作和理解;

(1)、通过ModelAndView

@RequestMapping("/hello")
public String hello(@RequestParam("username") String name, ModelMap model){
?? //封装要显示到视图中的数据
?? //相当于req.setAttribute("name",name);
?? model.addAttribute("name",name);
?? System.out.println(name);
?? return "hello";
}

(2)、ModelMap

@RequestMapping("/hello")
public String hello(@RequestParam("username") String name, ModelMap model){
? ? //封装要显示到视图中的数据
? ? //相当于req.setAttribute("name",name);
? ? model.addAttribute("name",name);
? ? System.out.println(name);
? ? return "hello";
}

(3)、Model

@RequestMapping("/ct2/hello")
public String hello(@RequestParam("username") String name, Model model){
?? //封装要显示到视图中的数据
?? //相当于req.setAttribute("name",name);
?? model.addAttribute("msg",name);
?? System.out.println(name);
?? return "test";
}

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-12-15 18:08:21  更:2021-12-15 18:09:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:04:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码