SpringMVC基础学习之Controller的两种实现方式和RequstMapping注解的使用
前言:
小伙伴们,大家好,我是狂奔の蜗牛rz,当然你们可以叫我蜗牛君,我是一个学习Java半年多时间的小菜鸟,同时还有一个伟大的梦想,那就是有朝一日,成为一个优秀的Java架构师。
这个SpringMVC基础学习系列是用来记录我学习SpringMVC框架基础知识的全过程 (这个系列是参照B站狂神的SpringMVC最新教程来写的,由于是之前整理的,但当时没有发布出来,所以有些地方可能有错误,希望大家能够及时指正!)
之后我将尽量以两天一更的速度更新这个系列,还没有学习SpringMVC框架的小伙伴可以参照我的博客学习一下;当然学习过的小伙伴,也可以顺便跟我一起复习一下基础。最后,希望能够和大家一同进步吧,加油吧,编程人!
特别提醒:如果对SpringMVC基础学习系列感兴趣,可以阅读本系列往期博客:
第一篇:SpringMVC基础学习之简单回顾MVC架构和Servlet的使用
第二篇:SpringMVC基础学习之初识SpringMVC
第三篇:SpringMVC基础学习之初识
第四篇:SpringMVC基础学习之使用注解开发
今天我们来到了SpringMVC基础学习的第五站:Controller的两种实现方式和RequstMapping注解的使用 。废话不多说,让我们开始今天的学习内容吧。
5.Controller的两种实现方式和RequstMapping注解的使用
5.1 什么是Controller?
- Controller (即控制器) ,它主要负责提供访问应用程序的行为和解析用户的请求,并将其转换为一个模型,通常通过接口定义或注解定义这两种方式来实现
- 在Spring MVC中一个控制器类可以包含多个方法,并且对于 Controller的配置方式 包含多种,包括接口定义和注解定义
5.2 实现Controller接口
5.1.1 了解Controller接口
- Controller是一个接口,在org.springframework.web.servlet.mvc包下,为了进一步了解它,我们可以查看其源代码:
// 实现该接口的类获得控制器功能
public interface Controller {// 处理请求并返回一个模型与视图对象ModelAndView handleRequest(HttpServletRequest var1, HttpServletResponse var2) throws Exception;}
查看Controller接口的源码后,发现该接口中只有一个方法,即handleRequest方法,用来处理请求并返回一个ModelAndView(模型和视图)对象
5.1.2 创建HelloController类
- 在src源文件下的java目录中创建一个com.kuang.controller包,创建HelloController类并且实现Controller接口
package com.kuang.controller;import org.springframework.web.servlet.ModelAndView;
// 注意: 该Controller接口是servlet.mvc包下
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;// 只要实现了Controller接口的类,说明这就是一个控制器了
public class HelloController implements Controller {/** * 用于处理请求并返回一个模型与视图对象* @param: httpServletRequest http请求* @param: httpServletResponse http响应* @return ModelAndView 视图模型对象*/public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {// 获取ModelAndView(模型视图)对象ModelAndView mv = new ModelAndView();// 封装数据到ModelAndView对象中mv.addObject("msg","Hello,Controller!");// 设置跳转视图, 存入到ModelAndView对象中mv.setViewName("hello");// 返回视图模型对象给视图解析器return mv;}}
5.1.3 编写核心配置文件
1.编写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"><!-- 配置DispatcherServlet(前端控制器), SpringMVC中的核心,相当于请求分发器 --><!-- 配置servlet --><servlet><!-- servlet的名字,自行设置 --><servlet-name>springmvc</servlet-name><!-- DispatcherServlet类的位置 --><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><!-- 设置启动优先级为1 --><load-on-startup>1</load-on-startup></servlet><!-- 配置servlet映射 --><servlet-mapping><servlet-name>springmvc</servlet-name><!-- 注意:在SpringMVC中, / 和 /* 作用不同/ : 匹配所有的请求,不会匹配jsp页面/*: 匹配所有的请求,包括jsp页面 --><url-pattern>/</url-pattern></servlet-mapping></web-app>
2.编写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"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 显式引入处理器映射和处理器适配器,也可以不写,因为Spring已经帮我们引入了 --> <!-- 配置处理器映射器 --><bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/><!-- 配置处理器适配器 --><bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/><!-- 配置internalResourceViewResolver(视图解析器), 主要作用是解析DispatcherServlet(中心控制器)给它的ModelAndView --><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"id="internalResourceViewResolver"><!-- 前缀 --><property name="prefix" value="/WEB-INF/jsp/"/><!-- 后缀 --><property name="suffix" value=".jsp"/><!-- 注意: 在视图解析器中我们吧所有的视图都放在/WEB-INF/目录下, 这样可以保证视图安全,因为这个目录下的文件,客户端不能直接访问) --></bean><!-- 注册控制器HelloController的Bean信息,交由Spring的IOC容器进行管理;该bean标签中的包含两个属性class和name, 其中"class"对应处理请求的控制类, 而"name"对应请求路径--><bean class="com.kuang.controller.HelloController" name="/hello"/></beans>
5.1.4 实现Controller接口使用总结
优点:
- 逻辑简单,易于理解
- 比起使用传统的Servlet,配置文件的编写简便了许多
缺点:
- 与使用注解相比,配置文件和控制层代码还是略过繁琐
- 每个控制层只能控制一个跳转页面,页面无法复用
5.3 使用@Controller注解
5.1.1 了解常用注解
@Component:注册为组件
@Repository:注册为Dao持久层
@Service:注册为Service服务层
@Controller:注册为Controller控制层
5.1.2 创建HelloController控制器类
- 在src源文件下的java目录下创建一个com.kuang.controller包,创建HelloController2类
package com.kuang.controller;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;// 使用@Controller注解, 将其注册为控制层, 由Spring的IOC容器统一管理
@Controller
public class HelloController2 {/*** 使用@Controller注解注解的类中的所有方法, * 如果返回类型是String, 并且有具体的页面可以跳转, 那么就会被视图解析器解析 */// 使用@RequestMapping注解, 设置请求映射, 其作用域是类或者方法@RequestMapping("/h1")public String hello(Model model) {// 封装数据:向模型中添加属性msg与其值,可以在JSP页面取出并且渲染model.addAttribute("msg","Hello,Controller!");// 会被视图解析器处理,注意:这里的hello对应的是JSP页面的名字return "hello";}// 使用@RequestMapping注解, 设置请求映射, 其作用域是类或者方法@RequestMapping("/h2") public String hello2(Model model) {// 封装数据: 向模型中添加属性msg与其值,可以在JSP页面取出并且渲染model.addAttribute("msg","Hello,World!");// 会被视图解析器处理(注意: 这里的hello对应的是JSP页面的名字)return "hello";}}
5.1.3 编写核心配置文件
1.编写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"><!-- 配置DispatcherServlet(前端控制器), SpringMVC中的核心,相当于请求分发器 --><!-- 配置servlet --><servlet><!-- servlet的名字,自行设置 --><servlet-name>springmvc</servlet-name><!-- DispatcherServlet类的位置 --><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><!-- 设置配置文件的位置 --><param-name>contextConfigLocation</param-name><!-- 配置文件的路径 --><param-value>classpath:springmvc-servlet2.xml</param-value></init-param><!-- 设置启动优先级为1 --><load-on-startup>1</load-on-startup></servlet><!-- 配置servlet映射 --><servlet-mapping><servlet-name>springmvc</servlet-name><!-- 注意:在SpringMVC中, / 和 /* 作用不同/ : 匹配所有的请求,不会匹配jsp页面/*: 匹配所有的请求,包括jsp页面 --><url-pattern>/</url-pattern></servlet-mapping></web-app>
2.编写springmvc-servlet2.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:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd"><!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 --><context:component-scan base-package="com.kuang.controller"/><!-- 设置default-servlet-handler用来防止静态资源被过滤 --><mvc:default-servlet-handler/><!-- 设置mvc的注解驱动, 让@RequstMapping注解生效以及引入DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter实例;使用annotation-driven会帮助我们自动完成上述两个实例的注入 --><mvc:annotation-driven/><!-- 配置internalResourceViewResolve(视图解析器): 主要作用是解析DispatcherServlet(中心控制器)给它的ModelAndView --><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"id="internalResourceViewResolver"><!-- 前缀 --><property name="prefix" value="/WEB-INF/jsp/"/><!-- 后缀 --><property name="suffix" value=".jsp"/></bean></beans>
5.1.4 测试结果
1.访问h1页面
2.访问h2页面
结果:可以发现,我们的两个请求都指向一个视图,但是页面结果却是不一样的,从这里可以看出视图是被复用的,因此控制器与视图之间是弱耦合关系
5.1.5 使用@Controller注解使用总结
优点:
- 使用注解开发,代码量大大减少,开发起来很方便
- 配置文件的编写比实现Controller接口的更加简便
- 一个控制器中可以写多个请求映射,从而实现跳转不同的视图
- 也可以跳转同一视图,但显示结果不同,视图可以被复用
缺点:
- 配置信息少,使用大量注解,导致查看代码结构时不太方便
- 代码可读性降低,不方便后期的代码维护
5.4 使用@RequstMapping注解
5.4.1 只在方法上使用
1.编写HelloController3对象
1-1 使用正常路径
- hello.jsp页面的存放路径为WEB-INF/jsp/hello.jsp
package com.kuang.controller;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;// 使用@Controller注解, 将该类注册为Controller接口, 交由Spring的IOC容器统一管理
@Controller
public class HelloController3 {/** * 在hello()方法上使用@RequestMapping, 设置请求映射路径* 而真实访问路径为:http://localhost:8080/项目名称/hello*/@RequestMapping("/hello")public String hello(Model model) {// 封装数据: 向模型中添加属性msg与其值,进行视图渲染model.addAttribute("msg","Hello,RequestMapping!");// 返回视图逻辑名,让视图解析器进行解析(注意:这里的hello是要跳转的视图逻辑名)return "hello"; }}
1-2 修改路径后
- 将hello.jsp的存放路径修改为WEB-INF/jsp/user/hello.jsp,即在jsp文件下创建一个user,将hello.jsp放入其中
package com.kuang.controller;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;// 使用@Controller注解, 将该类注册为Controller接口, 交由Spring的IOC容器统一管理
@Controller
public class HelloController3 {/** * 使用@RequestMapping, 设置请求映射路径 (注意: 直接在方法上把路径补全)* 真实访问路径为:http://localhost:8080/项目名称/user/hello*/@RequestMapping("/user/hello3") public String hello3(Model model) {// 封装数据: 向模型中添加属性msg与其值,进行视图渲染model.addAttribute("msg","Hello,User!");// 返回视图逻辑名,让视图解析器进行解析 (注意: 由于路径发生了改变,因此要跳转的视图逻辑名也要相应变化)return "hello/user"; }}
建议这样使用@RequestMapping注解,即在方法前的映射请求中设置全路径
2.测试结果
2-1 使用正常路径
结果:成功查询到了hello2页面,并且显示“Hello,RequestMapping!”信息
2-2 修改路径后
结果:成功查询到了user/hello3页面,并且显示“Hello,User”信息!
5.4.2 在类和方法上同时使用
1.修改HelloController3控制类
- hello.jsp的存放路径仍然为WEB-INF/jsp/user/hello.jsp
package com.kuang.controller;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;// 使用@Controller注解, 将该类注册为Controller接口, 交由Spring的IOC容器统一管理
@Controller
// 在控制类上使用@RequestMapping: 相当于在URL链接上再加一个父目录进行区分
@RequestMapping("/user") // 先访问类上的/user
public class HelloController3 {// 真实访问路径变为了:http://localhost:8080/项目名称/user/hello2@RequestMapping("/hello2") //再访问/hello2public String hello2(Model model) {// 封装数据:向模型中添加属性msg与值,进行视图渲染model.addAttribute("msg","Hello,RequestMapping2!");// 返回视图逻辑名,让视图解析器进行解析 (注意: 由于路径发生了改变,因此要跳转的视图逻辑名也要相应变化)return "user/hello"; }}
2.测试结果
结果:成功查询到了user/hello2页面,并且显示“Hello,RequestMapping2!”信息
5.4.3 使用总结
- 只在方法上使用@RequestMapping注解,代码编写更加简便,只用在每个方法前设置映射关系,而且方法中的页面的路径选择更加宽泛
- 在类和方法上同时使用@RequestMapping注解,逻辑更加清晰,但页面的调用范围也受到了限制,即只能调用在类上的映射关系中设置的父目录下的页面
好了,今天的有关 Controller的两种实现方式和RequstMapping注解的使用 的学习就到此结束啦。欢迎小伙伴们积极学习和讨论,喜欢的可以给蜗牛君点个关注,顺便来个一键三连。我们下期见,拜拜啦!
参考视频链接:【狂神说Java】SpringMVC最新教程IDEA版通俗易懂
SpringMVC基础学习之Controller的两种实现方式和RequstMapping注解的使用相关推荐
- SpringMVC基础学习之Restful风格的简单使用
前言: 小伙伴们,大家好,我是狂奔の蜗牛rz,当然你们可以叫我蜗牛君,我是一个学习Java半年多时间的小菜鸟,同时还有一个伟大的梦想,那就是有朝一日,成为一个优秀的Java架构师. 这个SpringM ...
- React基础学习笔记(一)-react前端项目的两种搭建方式
1.运行环境准备 需要先进行react项目的运行环境nodeJS的安装,具体安装流程可以参考: windows版本的安装配置帮助文档:https://www.cnblogs.com/liuqiyun/ ...
- controller 有两种写法,讨论一下两种写法的区别:
controller 有两种写法,讨论一下两种写法的区别: 写法 1: app.controller('myCtrl', function($scope, $location) { $scope.my ...
- android中资源文件的两种访问方式,Android_Android学习笔记-保存文件(Saving Files),Android设备有两种文件存储区域 - phpStudy...
Android学习笔记-保存文件(Saving Files) Android设备有两种文件存储区域: 内部存储和外部存储 ("internal" and "externa ...
- JavaSE学习总结(八)常用类(上)Object类==与equals方法的区别浅克隆的特点Scanner类String类String两种创建对象方式的区别String类的各种功能
JavaSE学习总结(八)常用类(上)/Object类/==与equals方法的区别/浅克隆的特点/Scanner类/String类/String两种创建对象方式的区别/String类的各种功能 常用 ...
- 【Django】项目中调用深度学习模型model.predict()(Django两种启动方式runserver和uwsgi的区别)
目录 问题 测试 解决方法 Django两种启动方式runserver和uwsgi的区别 问题 部署含有深度学习模型的Django项目的uWSGI.Nginx服务器的时候,所有模块都可以正常运行,也可 ...
- php文本框限制字节,js限制文本框输入长度两种限制方式(长度、字节数)_基础知识...
功能/特点: 1.实时显示可输入的字数(字节数) 2.两种限制方式(长度.字节数) 3.中文输入法下可正常使用,无BUG 4.同一页面可以使用多个,相互不干扰 limit.js function li ...
- python定义字符串变量有两种常用方式_Python 1基础语法二(标识符、关键字、变量和字符串)...
一.标识符 标识符就是程序员自己命名的变量名.名字需要有见名知义的效果,不要随意起名 :比如 a=1 a是个变量,a这个变量名属于标识符 1 company = '小米 2 employeeNum = ...
- 方向gravity_两种对齐方式,layout_gravity和gravity大不同
原标题:两种对齐方式,layout_gravity和gravity大不同 上一期我们一起学习了LinearLayout线性布局的方向.填充模型和权重,本期来一起学习LinearLayout线性布局的对 ...
最新文章
- OpenGL材质和光照(转)part2
- [bzoj2893] 集合计数
- c++ uint32转为int_【转】用python将GBK编码文件转为UTF-8编码文件
- 【redis】在windos下的redis服务器的搭建
- android 隐藏所有 fragment,Android 隐藏Fragment
- 有关Silverlight TreeView组件的研究[2]——Silverlight学习笔记(7)
- 初始化 数组 java_如何用Java初始化数组
- mysql 5.5加服务器_mysql 5.5 安装配置方法图文教程
- 扩展方法:给 IEnumerableTSource 扩展一个自定义数据源绑定的方法
- 那些年使用Android studio遇到的问题
- java调用WebService接口工具
- 服务器的主板芯片组,关于P8系列服务器主板芯片组的一些事儿
- volatility内存取证分析与讲解(持续更新)
- codeforces水题100道 第九题 Codeforces Beta Round #63 (Div. 2) Young Physicist (math)
- Linux运维工程师笔试题系列6(30题)
- Caché的studio如何Debug
- 知乎版ChatGPT「知海图AI」加入国产大模型乱斗,称效果与GPT-4持平
- oracle及shell相关学习记录
- VPP使用介绍(route、tun、memif、abf)
- Jenkins mavn多模块单独编译一个模块