基于注解的 SpringMVC 简单介绍

简介: SpringMVC是一个基于DispatcherServlet的MVC框架,每一个请求最先访问的都是DispatcherServlet,DispatcherServlet负责转发每一个Request请求给相应的Handler,Handler处理以后再返回相应的视图(View)和模型(Model),返回的视图和模型都可以不指定,即可以只返回Model或只返回View或都不返回。



SpringMVC是一个基于DispatcherServlet的MVC框架,每一个请求最先访问的都是DispatcherServlet,DispatcherServlet负责转发每一个Request请求给相应的Handler,Handler处理以后再返回相应的视图(View)和模型(Model),返回的视图和模型都可以不指定,即可以只返回Model或只返回View或都不返回。

DispatcherServlet是继承自HttpServlet的,既然SpringMVC是基于DispatcherServlet的,那么我们先来配置一下DispatcherServlet,好让它能够管理我们希望它管理的内容。HttpServlet是在web.xml文件中声明的。

01 <servlet>
02     <servlet-name>blog</servlet-name>
03  
04     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
05     <load-on-startup>1</load-on-startup>
06 </servlet>
07 <servlet-mapping>
08     <servlet-name>blog</servlet-name>
09  
10     <url-pattern>*.do</url-pattern>
11 </servlet-mapping>

上面声明了一个名为blog的DispatcherServlet,该Servlet将处理所有以“.do”结尾的请求。在初始化DispatcherServlet的时候,SpringMVC默认会到/WEB-INF目录下寻找一个叫[servlet-name]-servlet.xml的配置文件,来初始化里面的bean对象,该文件中对应的bean对象会覆盖spring配置文件中声明的同名的bean对象。如上面的就会在/WEB-INF目录下寻找一个叫blog-servlet.xml的文件;当然也可以在Servlet中声明配置文件的位置。

01 <servlet>
02  
03     <servlet-name>blog</servlet-name>
04     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
05     <init-param>
06         <param-name>contextConfigLocation</param-name>
07  
08         <param-value>/WEB-INF/blog-servlet.xml</param-value>
09     </init-param>
10     <load-on-startup>1</load-on-startup>
11 </servlet>
12 <servlet-mapping>
13  
14     <servlet-name>blog</servlet-name>
15     <url-pattern>*.do</url-pattern>
16 </servlet-mapping>

DispatcherServlet会利用一些特殊的bean来处理Request请求和生成相应的视图返回。

关于视图的返回,Controller只负责传回来一个值,然后到底返回的是什么视图,是由视图解析器控制的,在jsp中常用的视图解析器是InternalResourceViewResovler,它会要求一个前缀和一个后缀

1 <bean
2     class="org.springframework.web.servlet.view.InternalResourceViewResolver">
3     <property name="prefix" value="/WEB-INF/" />
4     <property name="suffix" value=".jsp" />
5 </bean>

在上述视图解析器中,如果Controller返回的是blog/index,那么通过视图解析器解析之后的视图就是/WEB-INF/blog/index.jsp。

要使用注解的SpringMVC需要在SpringMVC的配置文件中进行声明,具体方式为先引入mvc命名空间,然后利用<mvc:annotation-driven />进行声明。

01 <beans xmlns="http://www.springframework.org/schema/beans"
02     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"
03     <span style="background-color:#00ff00;"><spanstyle="color:#ff0000;">xmlns:mvc="http://www.springframework.org/schema/mvc"</span></span>    xsi:schemaLocation="http://www.springframework.org/schema/beans
04      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
05      http://www.springframework.org/schema/context
06      http://www.springframework.org/schema/context/spring-context-3.0.xsd
07     <spanstyle="background-color:#00ff00;color:#ff0000;"> http://www.springframework.org/schema/mvc
08      http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"</span>>
09  
10 <mvc:annotation-driven />
11  
12 </beans>

主要是说说Controller.

一个类使用了@Controller进行标记的都是Controller

1 @Controller
2 public class BlogController {
3  
4 }

有了Controller之后,那么到底是怎样请求一个Controller具体的方法的呢,那是通过@RequestMapping来标记的,@RequestMapping可以标记在类上面,也可以标记在方法上,当方法上和类上都标记了@RequestMapping的时候,那么对应的方法对应的Url就是类上的加方法上的,如下面的index方法,其对应的URL应为类上的/blog加上index方法上的/index,所以应为/blog/index,所以当请求/blog/index.do的时候就会访问BlogController的index方法。

01 @Controller
02 @RequestMapping("/blog")
03 public class BlogController {
04  
05      
06     @RequestMapping("/index")
07     public String index(Map<String, Object> map) {
08         return "blog/index";
09     }
10 }

在上面的代码中,如果index方法上没有RequestMapping注解,而只有BlogController类上有,且该类只有一个方法的时候,直接请求类上的URL就会调用里面的方法,即直接请求/blog.do的时候就会调用index方法。

在RequestMapping中还可以指定一个属性method,其主要对应的值有RequestMethod.GET和RequestMethod.POST,利用该属性可以严格的控制某一方法只能被标记的请求路径对应的请求方法才能访问,如指定method的值为GET,则表示只有通过GET方式才能访问该方法,默认是都可以访问。

在SpringMVC中常用的注解还有@PathVariable,@RequestParam,@PathVariable标记在方法的参数上,利用它标记的参数可以利用请求路径传值,看下面一个例子

1 @RequestMapping(value="/comment/{blogId}", method=RequestMethod.POST)
2 public void comment(Comment comment,@PathVariable intblogId, HttpSession session, HttpServletResponse response) throws IOException {
3      
4 }

在该例子中,blogId是被@PathVariable标记为请求路径变量的,如果请求的是/blog/comment/1.do的时候就表示blogId的值为1. 同样@RequestParam也是用来给参数传值的,但是它是从头request的参数里面取值,相当于request.getParameter("参数名")方法。

在Controller的方法中,如果需要WEB元素HttpServletRequest,HttpServletResponse和HttpSession,只需要在给方法一个对应的参数,那么在访问的时候SpringMVC就会自动给其传值,但是需要注意的是在传入Session的时候如果是第一次访问系统的时候就调用session会报错,因为这个时候session还没有生成。

接下来讨论一下方法的返回值,主要有一下情况:

  • 返回一个ModelAndView,其中Model是一个Map,里面存放的是一对对的键值对,其可以直接在页面上使用,View是一个字符串,表示的是某一个View的名称
  • 返回一个View,也就是一个字符串,这个时候如果需要给页面传值,可以给方法一个Map参数,该Map就相当于一个Model,往该Model里面存入键值对就可以在页面上进行访问了
  • 返回一个Model也就是一个Map,这个时候将解析默认的生成的view name。
  • 什么也不返回,这个时候可以利用HttpServletResponse进行返回,也可以直接使用printStream进行返回
下面是一个简单的实例
01     @RequestMapping("/{owner}/index")
02 public String userIndex(Map<String, Object> map,@PathVariableString owner, HttpServletRequest request) throws ParserException {
03     List<DefCategory> categories = categoryService.find(owner);
04     int offset = Util.getOffset(request);
05     Pager<Blog> pager = blogService.find(owner, 0, offset, maxResults);
06     int totalRecords = pager.getTotalRecords();
07     List<Blog> blogs = pager.getData();
08     Util.shortBlog(blogs);
09      
10     List<Message> messages = messageService.find(owner, 05).getData();
11     Util.shortMessage(messages, 20);
12     map.put("messages", messages);
13     map.put("totalRecords", totalRecords);
14     List<BlogStore> stores = storeService.find(owner, 05).getData();
15     map.put("maxResults", maxResults);
16     map.put("blogs", blogs);
17     map.put("totalRecords", totalRecords);
18     map.put("owner", userService.find(owner));
19     map.put("defCategories", categories);
20     map.put("stores", stores);
21     return "blog/userIndex";
22 }
相关文章
|
18小时前
|
存储 机器学习/深度学习 人工智能
打破硬件壁垒!煎饺App:强悍AI语音工具,为何是豆包AI手机平替?
直接上干货!3000 字以上长文,细节拉满,把核心功能、使用技巧和实测结论全给大家摆明白,读完你就知道这款 “安卓机通用 AI 语音工具"——煎饺App它为何能打破硬件壁垒?它接下来,咱们就深度拆解煎饺 App—— 先给大家扒清楚它的使用逻辑,附上“操作演示”和“🚀快速上手不踩坑 : 4 条核心操作干货(必看)”,跟着走零基础也能快速上手;后续再用真实实测数据,正面硬刚煎饺 App的语音助手口令效果——创建京东「牛奶自动下单神器」口令 ,从修改口令、识别准确率到场景实用性,逐一测试不掺水,最后,再和豆包 AI 手机语音助手的普通版——豆包App对比测试下,简单地谈谈煎饺App的能力边界在哪?
|
3天前
|
云安全 监控 安全
|
8天前
|
机器学习/深度学习 人工智能 自然语言处理
Z-Image:冲击体验上限的下一代图像生成模型
通义实验室推出全新文生图模型Z-Image,以6B参数实现“快、稳、轻、准”突破。Turbo版本仅需8步亚秒级生成,支持16GB显存设备,中英双语理解与文字渲染尤为出色,真实感和美学表现媲美国际顶尖模型,被誉为“最值得关注的开源生图模型之一”。
1000 5
|
10天前
|
机器学习/深度学习 人工智能 数据可视化
1秒生图!6B参数如何“以小博大”生成超真实图像?
Z-Image是6B参数开源图像生成模型,仅需16GB显存即可生成媲美百亿级模型的超真实图像,支持中英双语文本渲染与智能编辑,登顶Hugging Face趋势榜,首日下载破50万。
680 40
|
13天前
|
人工智能 Java API
Java 正式进入 Agentic AI 时代:Spring AI Alibaba 1.1 发布背后的技术演进
Spring AI Alibaba 1.1 正式发布,提供极简方式构建企业级AI智能体。基于ReactAgent核心,支持多智能体协作、上下文工程与生产级管控,助力开发者快速打造可靠、可扩展的智能应用。
1113 41
|
13天前
|
人工智能 前端开发 算法
大厂CIO独家分享:AI如何重塑开发者未来十年
在 AI 时代,若你还在紧盯代码量、执着于全栈工程师的招聘,或者仅凭技术贡献率来评判价值,执着于业务提效的比例而忽略产研价值,你很可能已经被所谓的“常识”困住了脚步。
816 70
大厂CIO独家分享:AI如何重塑开发者未来十年
|
9天前
|
存储 自然语言处理 测试技术
一行代码,让 Elasticsearch 集群瞬间雪崩——5000W 数据压测下的性能避坑全攻略
本文深入剖析 Elasticsearch 中模糊查询的三大陷阱及性能优化方案。通过5000 万级数据量下做了高压测试,用真实数据复刻事故现场,助力开发者规避“查询雪崩”,为您的业务保驾护航。
497 31
|
16天前
|
数据采集 人工智能 自然语言处理
Meta SAM3开源:让图像分割,听懂你的话
Meta发布并开源SAM 3,首个支持文本或视觉提示的统一图像视频分割模型,可精准分割“红色条纹伞”等开放词汇概念,覆盖400万独特概念,性能达人类水平75%–80%,推动视觉分割新突破。
957 59
Meta SAM3开源:让图像分割,听懂你的话
|
1天前
|
机器学习/深度学习 传感器 自动驾驶
具身智能核心突破:物理模拟器与世界模型协同技术拆解
本文系统综述了物理模拟器与世界模型在具身智能发展中的协同作用,提出五级智能机器人分类体系(IR-L0至IR-L4),分析其在运动、操作与交互中的进展,并对比主流仿真平台与世界模型架构,探讨其在自动驾驶与关节机器人中的应用及未来挑战。
160 113