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注解从而实现 ...
随机推荐
- Git命令收集【不断更新中】
git stash 可以用来保存暂时不想提交但又被修改过的文件. git stash pop 用来取出被保存在stash栈中的修改过的所有文件. git stash show 查询哪些文件被存放在了s ...
- SQL 查询分析器操作(修改、添加、删除)表及字段等
一.库操作1..创建数据库命令:create database <数据库名>例如:建立一个名为xhkdb的数据库mysql> create database xhkdb; 2.显示所 ...
- C# 顺序表操作
虽然.NET已经是现实了Reverse(),但是学习算法有必要知道其是怎么实现的: private static void ReverseArray(int[] array) { int temp; ...
- 安装360后,visual studio 经常报各种莫名其妙的错误的解决方案
安装360后,visual studio 经常报各种莫名其妙的错误,每次都要查找错误的解决方案 而且网上关于这个的好少,以后只要碰到了这种情况我就记录下吧 今天碰到的情况是打开WCF服务时出现 ...
- IIS本地服务器,设置IP地址问题
IIS启动本地网站的时候,设置了IP地址为本地IP,并绑定特定的端口号,电脑无法打开,但是同个局域网的手机可以打开.
- 自定义更新Hibernate Ehcache
最近在做一个项目中需要用缓存,项目持久层用的是Hibernate,然后就考虑用二级缓存来实现,但是后来项目扩展,由第三方修改数据这样缓存就会要等到失效后重新获取数据库的数据,本来这样是没问题的,可是领 ...
- Ubuntu 下为 Idea 创建启动图标.
默认情况下,ubuntu将自动安装的软件快捷方式保存在/usr/share/applications目录下,如果我们要创建桌面快捷方式,需要在该目录下创建一个名为“Idea.desktop”的文件.通 ...
- iOS 10的23个隐藏新特性-b
上周iOS 10正式版推送后,24小时的更新率已经超过15%,实在惊人.虽然有着初期变砖.5S6卡顿.移动VoLTE无法使用.美版无信号等BUG,但不可忽视的是,iOS 10还是带来了很多从前没有的功 ...
- UML类图关系-转
1.关联 双向关联: C1-C2:指双方都知道对方的存在,都可以调用对方的公共属性和方法. 在GOF的设计模式书上是这样描述的:虽然在分析阶段这种关系是适用的,但我们觉得它对于描述设计模式内的类关系来 ...
- Leetcode#80 Remove Duplicates from Sorted Array II
原题地址 简单模拟题. 从先向后遍历,如果重复出现2次以上,就不移动,否则移动到前面去 代码: int removeDuplicates(int A[], int n) { ) return n; ; ...