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简单介绍的更多相关文章

  1. SpringMVC札集(03)——基于注解的SpringMVC入门完整详细示例

    自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程03–onL ...

  2. SpringMVC学习笔记一:采用注解式搭建简单springMVC环境

    搭建的环境使用的是maven项目 项目目录树: 搭建环境使用的jar包,pom.xml文件 <project xmlns="http://maven.apache.org/POM/4. ...

  3. 【转】基于注解的SpirngMVC简单介绍

    转载地址:http://haohaoxuexi.iteye.com/blog/1343761 SpringMVC是一个基于DispatcherServlet的MVC框架,每一个请求最先访问的都是 Di ...

  4. 基于注解的springmvc开发

    原理简析 1. 背景知识:org.springframework.web.ServletContainerInitializer接口 在基于注解的servlet开发中,ServletContainer ...

  5. ensorflow学习笔记四:mnist实例--用简单的神经网络来训练和测试

    http://www.cnblogs.com/denny402/p/5852983.html ensorflow学习笔记四:mnist实例--用简单的神经网络来训练和测试   刚开始学习tf时,我们从 ...

  6. 基于注解的SpringMVC简单介绍

    SpringMVC是一个基于DispatcherServlet的MVC框架,每一个请求最先访问的都是DispatcherServlet,DispatcherServlet负责转发每一个Request请 ...

  7. springMVC学习记录2-使用注解配置

    前面说了一下使用xml配置springmvc,下面再说说注解配置.项目如下: 业务很简单,主页和输入用户名和密码进行登陆的页面. 看一下springmvc的配置文件: <?xml version ...

  8. 【转载】基于注解的SpringMVC简单介绍

    SpringMVC是一个基于DispatcherServlet的MVC框架,每一个请求最先访问的都是DispatcherServlet,DispatcherServlet负责转发每一个Request请 ...

  9. SpringMVC 学习笔记(五) 基于RESTful的CRUD

    1.1. 概述 当提交的表单带有_method字段时,通过HiddenHttpMethodFilter 将 POST 请求转换成 DELETE.PUT请求,加上@PathVariable注解从而实现  ...

随机推荐

  1. Nginx之负载均衡

    转自:http://www.360doc.com/content/13/1114/12/7694408_329125489.shtml 注,大家可以看到,由于我们网站是发展初期,nginx只代理了后端 ...

  2. 关于JS异步加载方案

    javascript延迟加载的解决方案: 1.使用defer标签 <span style="font-size: small;"><script type=&qu ...

  3. RouterOS的MikroTik脚本从DNS更新IPSEC端的IP地址

    #Script for changing IPSEC address when DNS changes. #Script will iterate through all peers looking ...

  4. Mysql主从同步(复制)

    目录: mysql主从同步定义      主从同步机制 配置主从同步      配置主服务器      配置从服务器 使用主从同步来备份      使用mysqldump来备份      备份原始文件 ...

  5. mysql-5.5.46源码编译安装

    1.安装准备 cat /etc/redhat-release uname -r yum install ncurses-devel cmake automake autoconf make gcc g ...

  6. 【转】RunTime.getRunTime().addShutdownHook用法

    Runtime.getRuntime().addShutdownHook(shutdownHook); 这个方法的含义说明: 这个方法的意思就是在jvm中增加一个关闭的钩子,当jvm关闭的时候,会执行 ...

  7. linux 标准io笔记

    三种缓冲 1.全缓冲:在缓冲区写满时输出到指定的输出端. 比如对磁盘上的文件进行读写通常是全缓冲的. 2.行缓冲:在遇到'\n'时输出到指定的输出端. 比如标准输入和标准输出就是行缓冲, 回车后就会进 ...

  8. ASP.NET对HTML元素进行权限控制(二)

    这是这个权限控制的第一步,扫描界面把要分配权限的元素的信息获取出来存入到数据库中. 这一步分三小步: (1).标出界面所要分配权限的元素 (2).扫描界面获取所要分配权限的元素信息.(ID,标题,层级 ...

  9. SetTimeOut jquery的作用

    1. SetTimeOut() 1.1 SetTimeOut()语法例子 1.2 用SetTimeOut()执行Function 1.3 SetTimeOut()语法例子 1.4 设定条件使SetTi ...

  10. java中封装

    .什么是封装? 封装就是将属性私有化,提供公有的方法访问私有属性. 做法就是:修改属性的可见性来限制对属性的访问,并为每个属性创建一对取值(getter)方法和赋值(setter)方法,用于对这些属性 ...