文档章节

基于注解的SpringMVC简单介绍

肥猫钓鱼
 肥猫钓鱼
发布于 2014/11/20 11:35
字数 3218
阅读 28
收藏 0
点赞 0
评论 0

基于注解的SpringMVC简单介绍

博客分类:
SpringMVC

mvcspringSpringMVC注解简单用法

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文件中声明的。

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参数的值。

Xml代码 收藏代码

<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,它会要求一个前缀和一个后缀

Xml代码 收藏代码

<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 />进行声明。

Xml代码 收藏代码

<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

Java代码 收藏代码

@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就是绝对路径了。

Java代码 收藏代码

@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映射还支持通配符*,如: Java代码 收藏代码

@Controller  
@RequestMapping("/blog")  
public class BlogController {  
    @RequestMapping("/*/index")  
    public String index(Map<String, Object> map) {  
        return "blog/index";  
    }  
}  

在@RequestMapping中还有一个属性params,可以通过该属性指定请求参数中必须包含某一参数,或必须不包含某一参数,或某参数的值必须是什么,以此来缩小指定的映射范围。 Java代码 收藏代码

@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来缩小映射范围,如: Java代码 收藏代码

@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标记在方法的参数上,利用它标记的参数可以利用请求路径传值,看下面一个例子

Java代码 收藏代码

@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变量的。 Java代码 收藏代码

@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("参数名"),如下所示: Java代码 收藏代码

@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注解来指定,否则将默认使用该返回类名称作为属性名称。

下面是一个简单的实例 Java代码 收藏代码

       @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加上需要传递到视图的键值对,这样在视图中就可以直接访问对应的键值对

本文转载自:http://haohaoxuexi.iteye.com/blog/1343761

共有 人打赏支持
肥猫钓鱼
粉丝 1
博文 52
码字总数 9287
作品 0
深圳
程序员
Spring实战 (一) 一切从Bean开始

Spring可以做很多事情,但是归根究底.Spring的核心仅仅是依赖注入(DI)/控制反转(IoC)和面向切面编程(AOP)而已.Spring的一切都是基于这2点 Spring的一切都是从Bean开始的.什么是Bean?凡是被Spr...

kenshiro
2013/09/05
0
0
Spring Cloud学习:02服务消费者(Ribbon&Feign)

在微服务架构中,业务会拆分成一个独立的服务,服务与服务之间基于http restful进行通信。Spring Cloud有两种服务调用方式,一种是Ribbon+restTemplate,另一种是Feign。 1 Ribbon+restTempl...

寒武没有纪
2017/10/21
0
0
Spring Data(一)概念和仓库的定义

Spring Data(一)概念和仓库的定义 Spring Data的主要任务是为数据访问提供一个相似的、一致的、基于Spring的编程模型,同时又保留着下面各个数据存储的特征。它使得使用数据访问技术非常的...

小忽悠
06/21
0
0
【Spring reference】Spring基于java的配置

1、简述 spring reference写到: Java-based configuration: Starting with Spring 3.0, many features provided by the Spring JavaConfig project became part of the core Spring Framewo......

666B
2014/07/01
0
0
Java面试题之Spring(二)

Spring常用的注解? spring 在2.5版本以后开始支持注解的方式来配置依赖注入,可以用注解的方式来代替xml中的bean的描述,注解注入将会被容器在xml注入之前被处理,所以后者会被覆盖掉前者对...

年轻诠释我们的梦想_705b
06/24
0
0
spring梳理(二) 基于注解的方式注册bean

我们知道,如果想要将bean交由spring容器管理,就需要首先将bean注册在spring容器中,而bean可以通过xml或者注解的方式进行注册,基于xml的配置一般是通过、等xml标签进行配置,然后由sprin...

wyn_lin
05/25
0
0
Spring基于注解的缓存配置--EHCache AND OSCache

本文将构建一个普通工程来说明spring注解缓存的使用方式,关于如何在web应用中使用注解缓存,请参见: Spring基于注解的缓存配置--web应用实例 一.简介 在spring的modules包中提供对许多第三...

小样
2012/02/28
0
0
Spring实战 (四) AOP

在软件开发中,分布于应用多出的功能被称为和横切关注点. 通常,这些横切关注点从概念上是与应用的业务逻辑相分离的(但是往往直接嵌入到应用的业务逻辑中).将这些横切关注点与业务逻辑相分离正...

kenshiro
2013/09/15
0
0
Spring3.1 Cache注解

需要感慨一下,spring3.0时丢弃了2.5时的spring-modules-cache.jar,致使无法使用spring来方便的管理cache注解,好在3.1.M1中增加了对cache注解的支持,可喜可贺啊! 希望了解spring2.5的cac...

小样
2012/02/28
0
0
Spring核心——JSR250与资源控制

JSR-175与元编程 要说明JSR-250先要解释清楚JSR-175,要解释清楚JSR就的先了解JCP是什么。网上资料很多,就不细说了,简单的说JCP(Java Community Process)是管理Java生态(包括J2SE、J2E...

随风溜达的向日葵
07/18
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

大数据教程(2.13):keepalived+nginx(多主多活)高可用集群搭建教程【自动化脚本】

上一章节博主为大家介绍了目前大型互联网项目的keepalived+nginx(主备)高可用系统架构体系,相信大家应该看了博主的文章对keepalived/nginx技术已经有一定的了解,在本节博主将为大家分享k...

em_aaron
1分钟前
0
0
Git 2.18版本发布:支持Git协议v2,提升性能

在最新的官方 Git 客户端正式版2.18中添加了对 Git wire 协议 v2 的支持,并引入了一些性能与 UI 改进的新特性。在 Git 的核心团队成员 Brandon Williams 公开宣布这一消息前几周,Git 协议 ...

六库科技
6分钟前
0
0
Java8新特性之接口

在JDK8以前,我们定义接口类中,方法都是抽象的,并且不能存在静态方法。所有的方法命名规则基本上都是 public [返回类型] [方法名](参数params) throws [异常类型] {}。 JDK8为接口的定义带...

developlee的潇洒人生
44分钟前
0
0
aop + annotation 实现统一日志记录

aop + annotation 实现统一日志记录 在开发中,我们可能需要记录异常日志。由于异常比较分散,每个 service 方法都可能发生异常,如果我们都去做处理,会出现很多重复编码,也不好维护。这种...

长安一梦
54分钟前
2
0
将博客搬至CSDN

AHUSKY
今天
1
0
Python web框架Django学习(1)

1.Django简介 (1)Python下有许多款不同的 Web 框架。Django是重量级选手中最有代表性的一位。许多成功的网站和APP都基于Django。Django是一个开放源代码的Web应用框架,由Python写成。 (2...

十年磨一剑3344
今天
0
0
Databook-数据之书

Databook-数据之书 用于数据分析的Jupyter Notebooks。 不需购买服务器,快速开始自己的数据分析过程。 源码:https://github.com/openthings/databook 作者:openthings,https://github.co...

openthings
今天
5
0
Python PIPEs

https://www.python-course.eu/pipes.php https://www.tutorialspoint.com/python/os_pipe.htm

zungyiu
今天
1
0
gRPC学习笔记

gRPC编程流程 1. proto文件定义 proto文件用于定义需要通过gRPC生成的接口,可以理解为接口定义文档 2. 通过构建工具生成服务基类代码-Maven或Gradle 3. 服务端开发 服务端实现类须实现通过构...

OSC_fly
今天
0
0
Docker Mac (三) Dockerfile 及命令

Dockerfile 最近学习docker的时候,遇到一件怪事,关于docker镜像可能会被破坏,还不知道它会有此措施 所以需要了解构建Dockerfile的正确方法 Dockerfile是由一系列命令和参数构成的脚本,这些命...

___大侠
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部