SpringMVC学习总结(四)——基于注解的SpringMVC简单介绍
SpringMVC是一个基于DispatcherServlet的MVC框架,每一个请求最先访问的都是 DispatcherServlet,DispatcherServlet负责转发每一个Request请求给相应的Handler,Handler处理 以后再返回相应的视图(View)和模型(Model),返回的视图和模型都可以不指定,即可以只返回Model或只返回View或都不返回。在使用注解 的SpringMVC中,处理器Handler是基于@Controller和@RequestMapping这两个注解的,@Controller声明 一个处理器类,@RequestMapping声明对应请求的映射关系,这样就可以提供一个非常灵活的匹配和处理方式。
DispatcherServlet是继承自HttpServlet的,既然SpringMVC是基于DispatcherServlet的,那么 我们先来配置一下DispatcherServlet,好让它能够管理我们希望它管理的内容。HttpServlet是在web.xml文件中声明的。
<servlet>
<servlet-name>blog</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>blog</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
上面声明了一个名为blog的DispatcherServlet,该Servlet将处理所有以“.do”结尾的请求。在初始化 DispatcherServlet的时候,SpringMVC默认会到/WEB-INF目录下寻找一个叫[servlet-name]- servlet.xml的配置文件,来初始化里面的bean对象,该文件中对应的bean对象会覆盖spring配置文件中声明的同名的bean对象。如 上面的就会在/WEB-INF目录下寻找一个叫blog-servlet.xml的文件;当然也可以在Servlet中声明配置文件的位置,那就是通过 Servlet的初始化参数来设置contextConfigLocation参数的值。
<servlet>
<servlet-name>blog</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/blog-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>blog</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
DispatcherServlet会利用一些特殊的bean来处理Request请求和生成相应的视图返回。
关于视图的返回,Controller只负责传回来一个值,然后到底返回的是什么视图,是由视图解析器控制的,在jsp中常用的视图解析器是InternalResourceViewResovler,
它会要求一个前缀和一个后缀
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/" />
<property name="suffix" value=".jsp" />
</bean>
在上述视图解析器中,如果Controller返回的是blog/index,那么通过视图解析器解析之后的视图就是/WEB-INF/blog/index.jsp。
要使用注解的SpringMVC需要在SpringMVC的配置文件中进行声明,具体方式为先引入mvc命名空间,然后利用<mvc:annotation-driven />进行声明。
<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"
<span style="background-color: #00ff00;"><span style="color: #ff0000;">xmlns:mvc="http://www.springframework.org/schema/mvc"</span>
</span> xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
<span style="background-color: #00ff00; color: #ff0000;"> http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"</span> >
<mvc:annotation-driven /> </beans>
主要是说说Controller.
在SpringMVC中Controller不需要继承什么类,也不需要实现什么接口,一切使用了@Controller进行标记的类都是Controller
@Controller
public class BlogController { }
有了Controller之后,那么到底是怎样请求一个Controller具体的方法的呢,那是通过@RequestMapping来标记 的,@RequestMapping可以标记在类上面,也可以标记在方法上,当方法上和类上都标记了@RequestMapping的时候,那么对应的方 法对应的Url就是类上的加方法上的,如下面的index方法,其对应的URL应为类上的/blog加上index方法上的/index,所以应为 /blog/index,所以当请求/blog/index.do的时候就会访问BlogController的index方法。加在类上的 @RequestMapping不是必须的,当Controller类上加上了@RequestMapping的时候,那么Controller方法上的 @RequestMapping就是相对于类上的@RequestMapping而言的,也就是前面说的请求映射的时候是类上的地址加方法上的地址,而当 Controller类上没有加@RequestMapping的时候,方法上的@RequestMapping就是绝对路径了。
@Controller
@RequestMapping("/blog")
public class BlogController { @RequestMapping("/index")
public String index(Map<String, Object> map) {
return "blog/index";
}
}
在上面的代码中,如果index方法上没有RequestMapping注解,而只有BlogController类上有,且该类只有一个方法的时候,直接请求类上的URL就会调用里面的方法,即直接请求/blog.do的时候就会调用index方法。
在RequestMapping中还可以指定一个属性method,其主要对应的值有RequestMethod.GET和 RequestMethod.POST,利用该属性可以严格的控制某一方法只能被标记的请求路径对应的请求方法才能访问,如指定method的值为 GET,则表示只有通过GET方式才能访问该方法,默认是都可以访问。
RequestMapping中的URL映射还支持通配符*,如:
@Controller
@RequestMapping("/blog")
public class BlogController {
@RequestMapping("/*/index")
public String index(Map<String, Object> map) {
return "blog/index";
}
}
在@RequestMapping中还有一个属性params,可以通过该属性指定请求参数中必须包含某一参数
,或必须不包含某一参数,或某参数的值必须是什么,以此来缩小指定的映射范围。
@Controller
@RequestMapping("/blog")
public class BlogController { @RequestMapping(value="/index", params="param1=value1")
public String index(Map<String, Object> map) {
return "blog/index";
}
}
在上面示例中,只有当请求/blog/index.do并且请求参数param1的值为value1的时候才能访问到对应的index方法。
如果 params的值为"param1",则表示请求参数只要包含param1就可以了,至于它的值是什么无所谓;如果params的值 为"!param1",
则表示请求参数必须不包含param1才可以。@RequestMapping中还可以使用header来缩小映射范围,如:
@Controller
@RequestMapping("/blog")
public class BlogController {
@RequestMapping(value="/index",headers="content-type=text/html")
public String index(Map<String, Object> map) {
return "blog/index";
}
}
在SpringMVC中常用的注解还有@PathVariable,@RequestParam,@PathVariable标记在方法的参数上,
利用它标记的参数可以利用请求路径传值,看下面一个例子
@RequestMapping(value="/comment/{blogId}", method=RequestMethod.POST)
public void comment(Comment comment,@PathVariable int blogId, HttpSession session, HttpServletResponse response) throws IOException { }
在该例子中,blogId是被@PathVariable标记为请求路径变量的,如果请求的是/blog/comment/1.do的时候就表示 blogId的值为1,
@PathVariable在进行赋值的时候如果像上面那样没有指定后面接的变量是对应URL中的哪个变量时默认是从URL中取跟 后面接的变量名相同的变量,
如上面示例中的@PathVariable int blogId,没有指明要获取URL中的哪个变量,这个时候就默认取URL中的blogId变量对应的值赋给方法参数中的blogId,
那如果方法参数的 名称跟RequestMapping中定义的访问路径中的变量名不一样,或者我要利用PathVariable明确指定后面接的方法参数是对应于URL中 的哪个变量时,
可以像下面这样做,在PathVariable中给定一个value="blogId"(只有一个参数的时候value是可以省略的)值明 确指定方法参数中的id变量是对应请求路径定义中的blogId变量的。
@RequestMapping(value="/comment/{blogId}", method=RequestMethod.POST)
public void comment(Comment comment,@PathVariable("blogId") int id, HttpSession session, HttpServletResponse response) throws IOException { }
同样@RequestParam也是用来给参数传值的,但是它是从头request的参数里面取值,相当于request.getParameter(" 参数名")方法。它的取值规则跟@PathVariable是一样的,
当没有指定的时候,默认是从request中取名称跟后面接的变量名同名的参数值, 当要明确从request中取一个参数的时候使用@RequestParam("参数名"),如下所示:
@RequestMapping("/show")
public void showParam(@RequestParam int id, @RequestParam("name") String username) {
//这样做进行URL请求访问这个方法的时候,就会先从request中获取参数id的值赋给参数变量id,从request中获取参数name的值赋给参数变量username
}
在Controller的方法中,如果需要WEB元素HttpServletRequest,HttpServletResponse和 HttpSession,只需要在给方法一个对应的参数,那么在访问的时候SpringMVC就会自动给其传值,但是需要注意的是在传入Session的 时候如果是第一次访问系统的时候就调用session会报错,因为这个时候session还没有生成。
接下来讨论一下方法的返回值,主要有以下情况:
- 返回一个ModelAndView,其中Model是一个Map,里面存放的是一对对的键值对,其可以直接在页面上使用,View是一个字符串,表示的是某一个View的名称
- 返回一个字符串,这个时候如果需要给页面传值,可以给方法一个Map参数,该Map就相当于一个Model,往该Model里面存入键值对就可以在页面上进行访问了
- 返回一个View对象
- 返回一个Model也就是一个Map,这个时候将解析默认生成的view name,默认情况view name就是方法名, 这里之前搞错了,感谢网友的指正。
- 默认的View Name是由RequestToViewNameTranslator来解析的,顾名思义就是把request翻译成viewName,在没有指定 RequestToViewNameTranslator时,Spring将使用其自身的默认实现 DefaultRequestToViewNameTranslator的默认配置,即取到当前请求的URI,去掉最前和最后的斜杠“/”,以及对应的后 缀。所以当你请求“http://localhost/app/abc”的时候,对应的默认viewName就是请求URI——“/abc”去掉最前最后 的斜杠和后缀之后的结果,即“abc”,请求“http://localhost/app/abc/efg”时对应的默认视图名称是“abc /efg”,“http://localhost/app/abc/efg/hi.html”——>“abc/efg/hi”。如果需要改变默认的 视图名称的解析方式,可以在SpringMVC的配置文件中配置一个名称为viewNameTranslator,类型为 RequestToViewNameTranslator的bean。如果该bean是 DefaultRequestToViewNameTranslator,那么你可以通过prefix属性指定视图名称的前缀,通过suffix指定后 缀,通过stripLeadingSlash指定是否需要去掉最前面的斜杠,更多可指定的属性请参考 DefaultRequestToViewNameTranslator的实现。当然你也可以定义自己的 RequestToViewNameTranslator实现类,实现RequestToViewNameTranslator接口的 getViewName(HttpServletRequest request)方法,实现自己的获取默认视图名称的逻辑。
- 什么也不返回,这个时候可以在方法体中直接往HttpServletResponse写入返回内容,否则将会由RequestToViewNameTranslator来决定
- 任何其他类型的对象。这个时候就会把该方法返回类型对象当做返回Model模型的一个属性返回给视图使用,这个属性名称可以通过在方法上给定@ModelAttribute注解来指定,否则将默认使用该返回类名称作为属性名称。
@RequestMapping("/{owner}/index")
public String userIndex(Map<String, Object> map,@PathVariable String owner, HttpServletRequest request) throws ParserException {
List<DefCategory> categories = categoryService.find(owner);
int offset = Util.getOffset(request);
Pager<Blog> pager = blogService.find(owner, 0, offset, maxResults);
int totalRecords = pager.getTotalRecords();
List<Blog> blogs = pager.getData();
Util.shortBlog(blogs); List<Message> messages = messageService.find(owner, 0, 5).getData();
Util.shortMessage(messages, 20);
map.put("messages", messages);
map.put("totalRecords", totalRecords);
List<BlogStore> stores = storeService.find(owner, 0, 5).getData();
map.put("maxResults", maxResults);
map.put("blogs", blogs);
map.put("totalRecords", totalRecords);
map.put("owner", userService.find(owner));
map.put("defCategories", categories);
map.put("stores", stores);
return "blog/userIndex";
}
给页面传值
在Controller中把请求转发给业务逻辑层进行处理之后需要把业务逻辑层的处理结果进行展现,在展现的过程中就需要我们把处理结果传给展示层进行展 示。
那么处理结果是怎么进行传递的呢?前面已经说了Controller的返回结果可以是一个包含模型和视图的ModelAndView,也可以仅仅是一 个视图View,当然也可以什么都不返回,
还可以是仅仅返回一个Model。我们知道模型Model是用来封装数据给视图View进行展示的,那么,在 SpringMVC中,如果要把我们后台的信息传递给前台进行展示的话应该怎么做呢
?这主要有两种方式:
1.返回包含模型Model的ModelAndView,或者是直接返回一个Model(这个时候就需要考虑默认的视图),这种类型的返回结果是包含Model的,这个Model对象里面的对应属性列都
可以直接在视图里面使用。
2.如果是直接返回一个视图View,这个时候SpringMVC提供了一种类似于在Controller方法中获取HttpRequest对象的机
制,这个时候我们只需要给定Controller方法一个Map参数,
然后在方法体里面给这个Map加上需要传递到视图的键值对,这样在视图中就可以直接
访问对应的键值对
SpringMVC学习总结(四)——基于注解的SpringMVC简单介绍的更多相关文章
- SpringMVC札集(03)——基于注解的SpringMVC入门完整详细示例
自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程03–onL ...
- SpringMVC学习笔记一:采用注解式搭建简单springMVC环境
搭建的环境使用的是maven项目 项目目录树: 搭建环境使用的jar包,pom.xml文件 <project xmlns="http://maven.apache.org/POM/4. ...
- 【转】基于注解的SpirngMVC简单介绍
转载地址:http://haohaoxuexi.iteye.com/blog/1343761 SpringMVC是一个基于DispatcherServlet的MVC框架,每一个请求最先访问的都是 Di ...
- 基于注解的springmvc开发
原理简析 1. 背景知识:org.springframework.web.ServletContainerInitializer接口 在基于注解的servlet开发中,ServletContainer ...
- ensorflow学习笔记四:mnist实例--用简单的神经网络来训练和测试
http://www.cnblogs.com/denny402/p/5852983.html ensorflow学习笔记四:mnist实例--用简单的神经网络来训练和测试 刚开始学习tf时,我们从 ...
- 基于注解的SpringMVC简单介绍
SpringMVC是一个基于DispatcherServlet的MVC框架,每一个请求最先访问的都是DispatcherServlet,DispatcherServlet负责转发每一个Request请 ...
- springMVC学习记录2-使用注解配置
前面说了一下使用xml配置springmvc,下面再说说注解配置.项目如下: 业务很简单,主页和输入用户名和密码进行登陆的页面. 看一下springmvc的配置文件: <?xml version ...
- 【转载】基于注解的SpringMVC简单介绍
SpringMVC是一个基于DispatcherServlet的MVC框架,每一个请求最先访问的都是DispatcherServlet,DispatcherServlet负责转发每一个Request请 ...
- SpringMVC 学习笔记(五) 基于RESTful的CRUD
1.1. 概述 当提交的表单带有_method字段时,通过HiddenHttpMethodFilter 将 POST 请求转换成 DELETE.PUT请求,加上@PathVariable注解从而实现 ...
随机推荐
- SequoiaDB数据库的一般概念介绍
SequoiaDB数据库的主要对象包括文档.集合.集合空间与索引等. 文档 SequoiaDB中的文档为JSON格式,一般又被称为记录.在数据库内部使用BSON,即二进制的方式存放JSON数据.一般情 ...
- php + apache + mysql环境搭建
别人写的很好,若是不改变php默认访问路径的话,能够成功搭建是没问题的 http://www.cnblogs.com/pharen/archive/2012/02/06/2340628.html
- VB最新使用教程
Visual Basic是一种由 微软公司开发的结构化的.模块化的.面向对象的.包含协助开发环境的事件驱动为机制的可视化程序设计语言.这是一种可用于微软自家产品开发的语言.它源自于BASIC编程语言. ...
- 12、在XAML中定义处理程序
<Grid> <Button x:Name="btnTest" Width="120" Height="36" Conte ...
- 我应该直接学Swift还是Objective-C?
当我们发布了Swift语言学习课程之后,收到了很多邮件和私信来问自己是否还需要学习C或者Objective-C.此外,人们似乎还在迷惑Swift到底适合iOS开发生态中的哪些部分.通过这篇文章,我希望 ...
- nginx——内存池篇
nginx--内存池篇 一.内存池概述 内存池是在真正使用内存之前,预先申请分配一定数量的.大小相等(一般情况下)的内存块留作备用.当有新的内存需求时,就从内存池中分出一部分内存块,若内存块不够再继续 ...
- 分布式文件系统 - FastDFS
分布式文件系统 - FastDFS 别问我在哪里 也许我早已不是我自己,别问我在哪里,我一直在这里. 突然不知道说些什么了... 初识 FastDFS 记得那是我刚毕业后进入的第一家公司,一个技术小白 ...
- cocos2dx中的实现地图卷动的两种方式
在游戏当中,实现地图卷动是最基本的功能,具体的实现的方法,大致有两类: 方法一:加载两张图片,轮流显示, 优点: 1.无论是地图上下卷动,还是左右卷动都可以 2.支持各种图片,(png,jpg...) ...
- Bluetooth
Android provides a default Bluetooth stack, BlueDroid, that is divided into two layers: The Bluetoot ...
- 常见的装置与其在Linux当中的档名
需要特别留意的是硬盘机(不论是IDE/SCSI/U盘都一样),每个磁碟机的磁盘分区(partition)不同时, 其磁碟档名还会改变呢!下一小节我们会介绍磁盘分区的相关概念啦!需要特别注意的是磁带机的 ...