SpringMVC
ssm:mybatis+Spring+SpringMVC MVC三层架构
JavaSE:认真学习,老师带,入门快
JavaWeb:认真学习,老师带,入门快
SSM框架:研究官方文档,锻炼自学能力,锻炼笔记能力,锻炼项目能力
SpringMVC+Vue+SpringBoot+SpringCloud+Linux
https://www.cnblogs.com/hellokuangshen 狂神博客园
SSM=JavaWeb做项目
Spring:IOC 和 AOP
文档:https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc
SpringMVC:SpringMVC的执行流程!
SpringMVC:SSM框架整合!
Spring
MVC:模型(dao,service) 视图(jsp) 控制器(Servlet)
dao
service
servlet:转发,重定向
jsp/html
前端 数据传输 实体类
实体类:用户名,密码,生日,爱好,……20个
前端:用户名 密码
pojo:User
vo:UserVo
dto:
JSP:本质就是一个Servlet
假设:你的项目的架构,是设计好的,还是引进的?
- Alibaba PHP
- 随着用户大,Java
- 王坚 去 IOE MySQL
- MySQL:MySQL---->AliSQL、AliRedis
- All in one —> 微服务
MVC:
MVVM:M V VM ViewModel:双向绑定
Spring:大杂烩,我们可以将SpringMVC中所有要用到的bean,注册到Spring中!
@Component 组件
@Service service
@Controller controller
@Repository dao
1、回顾MVC
1.什么是MVC
- MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范。
- 是将业务逻辑、数据、显示分离的方法来组织代码。
- MVC主要作用是降低了视图与业务逻辑间的双向偶合。
- MVC不是一种设计模式,MVC是一种架构模式。当然不同的MVC存在差异。
MVC:模型(dao,service) 视图(jsp) 控制器(Servlet)
最典型的MVC就是JSP + servlet + javabean的模式。
2.回顾Servlet(项目1)
-
新建一个maven工程当做父工程!pom依赖!
<!--依赖--> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.1.9.RELEASE</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> </dependencies>
-
建立一个Moudle:springmvc-01-servlet , 添加Web app的支持!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-flVIw7Q9-1623566172781)(SpringMVC.assets/添加Web app的支持.PNG)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TgVxXy2F-1623566172783)(SpringMVC.assets/添加Web app的支持-2.PNG)]
-
子工程!springmvc-01-servlet中pom导入servlet 和 jsp 的 jar 依赖
<dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.2</version> </dependency> </dependencies>
-
编写一个Servlet类,用来处理用户的请求
public class HelloServlet extends HttpServlet { //全栈:后台+前端+数据库+运维 //前端:后台+前端 //Python!=人工智能 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1.获取前端参数 String method=req.getParameter("method"); if (method.equals("add")){ req.getSession().setAttribute("msg","执行了add方法"); } if (method.equals("delete")){ req.getSession().setAttribute("msg","执行了delete方法"); } //2.调用业务层 //3.视图转发或者重定向 req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
-
编写Hello.jsp,在WEB-INF目录下新建一个jsp的文件夹,新建hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> ${msg} </body> </html>
-
在web.xml中注册Servlet
<?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"> <servlet> <servlet-name>hello</servlet-name> <servlet-class>com.kuang.servlet.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> <!--<session-config>--> <!--<session-timeout>15</session-timeout>--> <!--</session-config>--> <!--<welcome-file-list>--> <!--<welcome-file>index.jsp</welcome-file>--> <!--</welcome-file-list>--> </web-app>
-
配置Tomcat,并启动测试
-
- localhost:8080/springmvc_01_servlet_war_exploded/hello?method=add
- localhost:8080/springmvc_01_servlet_war_exploded/hello?method=delete
-
2、什么是SpringMVC
1.概述
Spring MVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架。
查看官方文档:https://docs.spring.io/spring/docs/5.2.0.RELEASE/spring-framework-reference/web.html#spring-web
我们为什么要学习SpringMVC呢?
Spring MVC的特点:
- 轻量级,简单易学
- 高效 , 基于请求响应的MVC框架
- 与Spring兼容性好,无缝结合
- 约定优于配置
- 功能强大:RESTful、数据验证、格式化、本地化、主题等
- 简洁灵活
我们为什么要学习SpringMVC呢?
Spring MVC的特点:
- 轻量级,简单易学
- 高效 , 基于请求响应的MVC框架
- 与Spring兼容性好,无缝结合
- 约定优于配置
- 功能强大:RESTful、数据验证、格式化、本地化、主题等
- 简洁灵活
我们为什么要学习SpringMVC呢?
Spring MVC的特点:
-
轻量级,简单易学
-
高效 , 基于请求响应的MVC框架
-
与Spring兼容性好,无缝结合
-
约定优于配置
-
功能强大:RESTful、数据验证、格式化、本地化、主题等
-
简洁灵活
Spring的web框架围绕DispatcherServlet [ 调度Servlet ] 设计。
最重要的一点还是用的人多 , 使用的公司多 .
2.中心控制器
Spring的web框架围绕DispatcherServlet设计。
Spring MVC框架像许多其他MVC框架一样, 以请求为驱动 , 围绕一个中心Servlet分派请求及提供其他功能,DispatcherServlet是一个实际的Servlet (它继承自HttpServlet 基类)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UitKm67e-1623566172784)(SpringMVC.assets/2-2中心控制器.PNG)]
3.SpringMVC执行原理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K6S9MhSF-1623566172787)(SpringMVC.assets/2-3SpringMVC执行原理.PNG)]
图为SpringMVC的一个较完整的流程图,实线表示SpringMVC框架提供的技术,不需要开发者实现,虚线表示需要开发者实现。
4.第一个MVC程序(项目2)
配置版
-
新建一个Moudle , springmvc-02-hellomvc , 添加web的支持!
-
确定导入了SpringMVC 的依赖!
-
配置web.xml , 注册DispatcherServlet
<?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"> <!--1.注册DispatcherServlet--> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--关联一个springmvc的配置文件:【servlet-name】-servlet.xml--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc-servlet.xml</param-value> </init-param> <!--启动级别-1--> <load-on-startup>1</load-on-startup> </servlet> <!--/匹配所有的请求:(不包括.jsp)--> <!--/*匹配所有的请求:(包括.jsp)--> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
-
编写SpringMVC 的 配置文件!名称:springmvc-servlet.xml : [servletname]-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" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> </beans>
-
在springmvc-servlet.xml 中添加 处理映射器
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
-
在springmvc-servlet.xml 中添加 处理器适配器
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
-
在springmvc-servlet.xml 中添加 视图解析器
<!--视图解析器:DispatcherServlet给他的ModelAndView 1.获取了ModelAndView的数据 2.解析ModelAndView的视图名字 3.拼接视图名字,找到对应的视图 4.将数据渲染到这个视图上--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver"> <!--前缀--> <property name="prefix" value="/WEB-INF/jsp/"/> <!--后缀--> <property name="suffix" value=".jsp"/> </bean>
-
编写我们要操作业务Controller ,要么实现Controller接口,要么增加注解;需要返回一个ModelAndView,装数据,封视图;
package com.kuang.controller;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 { public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { //ModelAndView 模型和视图 ModelAndView mv=new ModelAndView(); //封装对象,放在ModelAndView中,Model mv.addObject("msg","HelloSpringMVC!"); //封装要跳转的视图,放在ModelAndView中 mv.setViewName("hello");//:/WEB-INF/hello.jsp return mv; }}
-
在springmvc-servlet.xml 中 添加将自己的类交给SpringIOC容器,注册bean
<!--Handler--> <bean id="/hello" class="com.kuang.controller.HelloController"/>
-
写要跳转的jsp页面,显示ModelandView存放的数据,以及我们的正常页面;
<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>Title</title></head><body>${msg}</body></html>
-
配置Tomcat 启动测试!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b94loYbh-1623566172789)(SpringMVC.assets/2-4第一个MVC程序.PNG)]
可能遇到的问题:访问出现404,排查步骤:
-
查看控制台输出,看一下是不是缺少了什么jar包。
-
如果jar包存在,显示无法输出,就在IDEA的项目发布中,添加lib依赖!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TdA4Wpm3-1623566172789)(SpringMVC.assets/2-4第一个MVC程序-2.PNG)]
-
重启Tomcat 即可解决!
-
5.注解MVC程序(项目3)
注解版
-
新建一个Moudle,springmvc-03-annotation 。添加web支持!
-
由于Maven可能存在资源过滤的问题,我们将配置完善
子工程!在springmvc-03-annotation prom中配置!
<build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources></build>
-
在pom.xml文件引入相关的依赖:主要有Spring框架核心库、Spring MVC、servlet , JSTL等。我们在父依赖中已经引入了!
-
配置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"> <!--1.注册DispatcherServlet--> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--关联一个springmvc的配置文件:【servlet-name】-servlet.xml--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc-servlet.xml</param-value> </init-param> <!--启动级别-1--> <load-on-startup>1</load-on-startup> </servlet> <!--/匹配所有的请求:(不包括.jsp)--> <!--/*匹配所有的请求:(包括.jsp)--> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping></web-app>
注意点:
/ 和 /* 的区别:< url-pattern > / </ url-pattern > 不会匹配到.jsp, 只针对我们编写的请求;即:.jsp 不会进入spring的 DispatcherServlet类 。< url-pattern > /* </ url-pattern > 会匹配 *.jsp,会出现返回 jsp视图 时再次进入spring的DispatcherServlet 类,导致找不到对应的controller所以报404错。
-
-
注意web.xml版本问题,要最新版!
-
注册DispatcherServlet
-
关联SpringMVC的配置文件
-
启动级别为1
-
映射路径为 / 【不要用/*,会404】
-
-
-
添加Spring MVC配置文件
<?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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 --> <context:component-scan base-package="com.kuang.controller"/> <!-- 让Spring MVC不处理静态资源 --> <mvc:default-servlet-handler /> <!-- 支持mvc注解驱动 在spring中一般采用@RequestMapping注解来完成映射关系 要想使@RequestMapping注解生效 必须向上下文中注册DefaultAnnotationHandlerMapping 和一个AnnotationMethodHandlerAdapter实例 这两个实例分别在类级别和方法级别处理。 而annotation-driven配置帮助我们自动完成上述两个实例的注入。 --> <mvc:annotation-driven /> <!-- 视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver"> <!-- 前缀 --> <property name="prefix" value="/WEB-INF/jsp/" /> <!-- 后缀 --> <property name="suffix" value=".jsp" /> </bean></beans>
-
在视图解析器中我们把所有的视图都存放在/WEB-INF/目录下,这样可以保证视图安全,因为这个目录下的文件,客户端不能直接访问。
-
-
让IOC的注解生效
-
静态资源过滤 :HTML . JS . CSS . 图片 , 视频 …
-
MVC的注解驱动
-
配置视图解析器
-
-
-
创建Controller
package com.kuang.controller;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;@Controller@RequestMapping("/hello")public class HelloController { //localhost:8080/hello/h1 @RequestMapping("/h1") public String hello(Model model){ //封装数据 model.addAttribute("msg","Hello,SpringMVCAnnotation"); return "hello";//会被视图解析器处理; }}
-
创建视图层
<%@ page contentType="text/html;charset=UTF-8" language="java" %><html> <head> <title>$Title$</title> </head> <body> $END$ </body></html>
-
配置Tomcat运行
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dJIYZoii-1623566172790)(SpringMVC.assets/2-5注解MVC程序.PNG)]
小结:
实现步骤其实非常的简单:
- 新建一个web项目
- 导入相关jar包
- 编写web.xml , 注册DispatcherServlet
- 编写springmvc配置文件
- 接下来就是去创建对应的控制类 , controller
- 最后完善前端视图和controller之间的对应
- 测试运行调试.
3、RestFul和控制器(项目4)
1.控制器Controller
- 控制器复杂提供访问应用程序的行为,通常通过接口定义或注解定义两种方法实现。
- 控制器负责解析用户的请求并将其转换为一个模型。
- 在Spring MVC中一个控制器类可以包含多个方法
- 在Spring MVC中,对于Controller的配置方式有很多种
-
新建一个Moudle,springmvc-04-controller 。将刚才的03 拷贝一份, 我们进行操作!
-
-
删掉HelloController
-
mvc的配置文件只留下 视图解析器!
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/></bean>
-
-
-
编写一个Controller类,ControllerTest1
//定义控制器//注意点:不要导错包,实现Controller接口,重写方法;//只要实现了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; }}
-
编写完毕后,去在springmvc-servlet.xml 置文件中注册请求的bean;name对应请求路径,class对应处理请求的类
<bean name="/t1" class="com.kuang.controller.ControllerTest1"/>
-
编写前端test.jsp,注意在WEB-INF/jsp目录下编写,对应我们的视图解析器
<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>Title</title></head><body>${msg}</body></html>
-
配置Tomcat运行测试,我这里没有项目发布名配置的就是一个 / ,所以请求不用加项目名,OK!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CcxjIJ4K-1623566172791)(SpringMVC.assets/2-5注解MVC程序.PNG)]
说明:
- 实现接口Controller定义控制器是较老的办法
- 缺点是:一个控制器中只有一个方法,如果要多个方法则需要定义多个Controller;定义的方式比较麻烦;
2.使用注解@Controller
-
@Controller注解类型用于声明Spring类的实例是一个控制器(在讲IOC时还提到了另外3个注解);
-
Spring可以使用扫描机制来找到应用程序中所有基于注解的控制器类,为了保证Spring能找到你的控制器,需要在配置文件中声明组件扫描。
<!-- 自动扫描指定的包,下面所有注解类交给IOC容器管理 --><context:component-scan base-package="com.kuang.controller"/>
<?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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <context:component-scan base-package="com.kuang.controller"/> <!--<mvc:default-servlet-handler/>--> <!--<mvc:annotation-driven/>--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean></beans>
-
增加一个ControllerTest2类,使用注解实现;
package com.kuang.controller;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;@Controller//代表这个类会被Spring接管//被这个注解的类,中的所有方法,如果返回值是String,并且有具体页面可以跳转,那么就会被视图解析器解析;public class ControllerTest2 { @RequestMapping("/t2") public String test1(Model model){ model.addAttribute("msg","ControllerTest2"); return "test";//解析为 WEB-INF/jsp/test.jsp } @RequestMapping("/t3") public String test2(Model model){ model.addAttribute("msg","ControllerTest2"); return "test";//解析为 WEB-INF/jsp/test.jsp }}
-
运行tomcat测试
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qT6GC0NE-1623566172792)(SpringMVC.assets/3控制器Controller-2.PNG)]
可以发现,我们的两个请求都可以指向一个视图,但是页面结果的结果是不一样的,从这里可以看出视图是被复用的,而控制器与视图之间是弱偶合关系。
注解方式是平时使用的最多的方式!
3.RequestMapping
@RequestMapping
-
@RequestMapping注解用于映射url到控制器类或一个特定的处理程序方法。可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
-
为了测试结论更加准确,我们可以加上一个项目名测试 myweb
-
只注解在方法上面
@Controllerpublic class ControllerTest3 { @RequestMapping("/t1") public String test1(Model model){ model.addAttribute("msg","ControllerTest3"); return "test"; }}
访问路径:http://localhost:8080 / 项目名 / t1
-
同时注解类与方法
@Controller@RequestMapping("/c3")public class ControllerTest3 { @RequestMapping("/t1") public String test1(Model model){ model.addAttribute("msg","ControllerTest3"); return "test"; }}
访问路径:http://localhost:8080 / 项目名/ c3/t1 , 需要先指定类的路径再指定方法的路径;
4.RestFul 风格
概念
Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
功能
资源:互联网所有的事物都可以被抽象为资源
资源操作:使用POST、DELETE、PUT、GET,使用不同方法对资源进行操作。
分别对应 添加、 删除、修改、查询。
传统方式操作资源 :通过不同的参数来实现不同的效果!方法单一,post 和 get
http://127.0.0.1/item/queryItem.action?id=1 查询,GET
http://127.0.0.1/item/saveItem.action 新增,POST
http://127.0.0.1/item/updateItem.action 更新,POST
http://127.0.0.1/item/deleteItem.action?id=1 删除,GET或POST
使用RESTful操作资源 :可以通过不同的请求方式来实现不同的效果!如下:请求地址一样,但是功能可以不同!
http://127.0.0.1/item/1 查询,GET
http://127.0.0.1/item 新增,POST
http://127.0.0.1/item 更新,PUT
http://127.0.0.1/item/1 删除,DELETE
传统:
@Controllerpublic class RestFulController { //原来的: http://localhost:8080/springmvc_04_controller_war_exploded/add?a=1&b=2 @RequestMapping("/add") public String test1(int a,int b, Model model){ int res=a+b; model.addAttribute("msg","结果为"+res); return "test"; }}
测试结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dyVGqJdO-1623566172792)(SpringMVC.assets/3-4-1.PNG)]
RESTful操作:
@Controllerpublic class RestFulController { //原来的: http://localhost:8080/springmvc_04_controller_war_exploded/add?a=1&b=2 //RestFul: http://localhost:8080/springmvc_04_controller_war_exploded/add/a/b @RequestMapping("/add/{a}/{b}") public String test1(@PathVariable int a,@PathVariable int b, Model model){ int res=a+b; model.addAttribute("msg","结果为"+res); return "test"; }}
测试结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qJdTW8QU-1623566172793)(SpringMVC.assets/3-4-2.PNG)]
我们来修改下对应的参数类型,再次测试:
//映射访问路径@RequestMapping("/commit/{p1}/{p2}")public String index(@PathVariable int p1, @PathVariable String p2, Model model){ String result = p1+p2; //Spring MVC会自动实例化一个Model对象用于向视图中传值 model.addAttribute("msg", "结果:"+result); //返回视图位置 return "test";}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ppofNFZx-1623566172793)(SpringMVC.assets/640)]
使用method属性指定请求类型
用于约束请求的类型,可以收窄请求范围。指定请求谓词的类型如GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE等
我们来测试一下:
-
增加一个方法
-
@RequestMapping(value = “/add/{a}/{b}”,method = RequestMethod.POST)
@Controllerpublic class RestFulController { //原来的: http://localhost:8080/springmvc_04_controller_war_exploded/add?a=1&b=2 //RestFul: http://localhost:8080/springmvc_04_controller_war_exploded/add/a/b @RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.POST ) public String test1(@PathVariable int a,@PathVariable int b, Model model){ int res=a+b; model.addAttribute("msg","结果为"+res); return "test"; }}
我们使用浏览器地址栏进行访问默认是Get请求,会报错405:
-
如果将POST修改为GET则正常了;
@RequestMapping(value = “/add/{a}/{b}”,method = RequestMethod.GET )
@Controllerpublic class RestFulController { //原来的: http://localhost:8080/springmvc_04_controller_war_exploded/add?a=1&b=2 //RestFul: http://localhost:8080/springmvc_04_controller_war_exploded/add/a/b @RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.GET ) public String test1(@PathVariable int a,@PathVariable int b, Model model){ int res=a+b; model.addAttribute("msg","结果为"+res); return "test"; }}
测试结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l3Kt94h6-1623566172794)(SpringMVC.assets/3-4-3.PNG)]
@GetMapping方式:@GetMapping("/add/{a}/{b}")
@Controllerpublic class RestFulController { //原来的: http://localhost:8080/springmvc_04_controller_war_exploded/add?a=1&b=2 //RestFul: http://localhost:8080/springmvc_04_controller_war_exploded/add/a/b// @RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.GET ) @GetMapping("/add/{a}/{b}") public String test1(@PathVariable int a,@PathVariable int b, Model model){ int res=a+b; model.addAttribute("msg","结果为"+res); return "test"; }}
@PostMapping方式:@PostMapping("/add/{a}/{b}")
@Controllerpublic class RestFulController { //原来的: http://localhost:8080/springmvc_04_controller_war_exploded/add?a=1&b=2 //RestFul: http://localhost:8080/springmvc_04_controller_war_exploded/add/a/b// @RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.GET ) @PostMapping("/add/{a}/{b}") public String test1(@PathVariable int a,@PathVariable int b, Model model){ int res=a+b; model.addAttribute("msg","结果为"+res); return "test"; }}
-
-
思考:使用路径变量的好处?(安全)
-
- 使路径变得更加简洁;
- 获得参数更加方便,框架会自动进行类型转换。
- 通过路径变量的类型可以约束访问参数,如果类型不一样,则访问不到对应的请求方法,如这里访问是的路径是/commit/1/a,则路径与方法不匹配,而不会是参数转换失败。
-
小结:
Spring MVC 的 @RequestMapping 注解能够处理 HTTP 请求的方法, 比如 GET, PUT, POST, DELETE 以及 PATCH。
所有的地址栏请求默认都会是 HTTP GET 类型的。
方法级别的注解变体有如下几个:组合注解
@GetMapping@PostMapping@PutMapping@DeleteMapping@PatchMapping
@GetMapping 是一个组合注解,平时使用的会比较多!
它所扮演的是 @RequestMapping(method =RequestMethod.GET) 的一个快捷方式。
4.数据处理及跳转
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类
//只要实现了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实现转发
@Controllerpublic class ModelTest1 { @RequestMapping("m1/t1") public String test1(HttpServletRequest request, HttpServletResponse response){ HttpSession session = request.getSession(); System.out.println(session.getId()); return "test"; }}
@Controllerpublic 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来实现转发和重定向 - 无需视图解析器;
测试前,需要将视图解析器注释掉
@Controllerpublic class ModelTest1 { @RequestMapping("/m1/t1") public String test1(Model model){ model.addAttribute("msg","ModelTest1"); //转发 return "/WEB-INF/jsp/test.jsp"; } @RequestMapping("m1/t2") public String test2(Model model){ model.addAttribute("msg","ModelTest2"); //转发二 return "forward:/WEB-INF/jsp/test.jsp"; } @RequestMapping("/m1/t3") public String test3(Model model){ model.addAttribute("msg","ModelTest3"); //重定向 return "redirect:/index.jsp"; }}
通过SpringMVC来实现转发和重定向 - 有视图解析器;
重定向 , 不需要视图解析器 , 本质就是重新请求一个新地方嘛 , 所以注意路径问题.
可以重定向到另外一个请求实现 .
@Controllerpublic 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为另一个请求/ }}
4.处理提交数据
-
提交的域名称和处理方法的参数名一致
提交数据 :http://localhost:8080/springmvc_04_controller_war_exploded/user/t1?name=qingjiang
处理方法 :
//localhost:8080/user/t1?name=xxx;@GetMapping("/t1")public String test1(String name, Model model){ //1.接受前端参数 System.out.println("接收到前端的参数为:"+name); //2.将返回的结果传递给前端 ,Model model.addAttribute("msg",name); //3.视图跳转 return "test";}
后台输出 : qingjiang
-
提交的域名称和处理方法的参数名不一致
提交数据 :http://localhost:8080/springmvc_04_controller_war_exploded/user/t1?username=qingjiang
处理方法 :
//localhost:8080/user/t1?name=xxx;@GetMapping("/t1")public String test1(@RequestParam("username") String name, Model model){ //1.接受前端参数 System.out.println("接收到前端的参数为:"+name); //2.将返回的结果传递给前端 ,Model model.addAttribute("msg",name); //3.视图跳转 return "test";}
后台输出 : qingjiang
-
提交的是一个对象
要求提交的表单域和对象的属性名一致 , 参数使用对象即可
1、实体类
@Data@AllArgsConstructor@NoArgsConstructorpublic class User { private int id; private String name; private int age;}
2、提交数据 : http://localhost:8080/springmvc_04_controller_war_exploded/user/t2?id=1&name=qiangjiang&age=11
3、处理方法 :
```java
//前端接收的是一个对象:id,name,age
@GetMapping("/t2")
public String test2(User user){
System.out.println(user);
return “test”;
}
```
后台输出 : User(id=1, name=qiangjiang, age=11)
说明:如果使用对象的话,前端传递的参数名和对象名必须一致,否则就是null。
5.数据显示到前端
LinkedHashMapModelMap:继承了LinkedHashMap,所以他拥有LinkedHashMap的全部功能!Model:精简版(大部分情况,我们都直接使用Model)
第一种 : 通过ModelAndView
我们前面一直都是如此 . 就不过多解释
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; }}
第二种 : 通过ModelMap
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";}
第三种 : 通过Model
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";}
对比
就对于新手而言简单来说使用区别就是:
Model 只有寥寥几个方法只适合用于储存数据,简化了新手对于Model对象的操作和理解;ModelMap 继承了 LinkedMap ,除了实现了自身的一些方法,同样的继承 LinkedMap 的方法和特性;ModelAndView 可以在储存数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的跳转。
当然更多的以后开发考虑的更多的是性能和优化,就不能单单仅限于此的了解。
请使用80%的时间打好扎实的基础,剩下18%的时间研究框架,2%的时间去学点英文,框架的官方文档永远是最好的教程。