spring2.5全面支持了annotation方式(当然spring3肯定支持了),使用annotation的方式,可以大大减少xml的维护量。现在写一个hello world例子
web.xml和原来一样,没有变化。可以见《我的第一个springMVC例子之Hello world》里面的web.xml配置。也就说“分发器(Dispatcher)”没有变。主要变化在“控制器”和“映射处理器”方面。“视图解析器”也没有变化。见roadrantz-servlet.xml的内容,这里面变化挺大的。
roadrantz-servlet.xml
<?xml version="1.0"encoding="UTF-8"?>
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config></context:annotation-config>
<context:component-scanbase-package="com.baidu"></context:component-scan>
<beanid="viewResolver"class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<propertyname="prefix">
<value>/</value>
</property>
<propertyname="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>
在这里,不用在指定具体的Controller了,只需要指定Controller 具体的包(base-package="com.baidu")即可,spring回到此包下的所有注解进行扫描。这样配置就结束了。再看HomePageControler.java的代码:
HomePageController.java
packagecom.baidu;
importorg.springframework.stereotype.Controller;
importorg.springframework.ui.Model;
importorg.springframework.web.bind.annotation.RequestMapping;
/**
* Created by IntelliJ IDEA.
* User: liuzhaoyang
* Date: 2011-2-28
* Time: 22:43:08 */
@Controller
public class HomePageController {
@RequestMapping("/home.htm")
public String sayHello(Model model) {
model.addAttribute("rants","hello,world");
return "index";
}
@RequestMapping("/url/homePage.htm")
public String sayHelloHomePage(Model model) {
model.addAttribute("rants","spring MVC");
return "index";
}
}
----------------------------------------------
用“@Controller ”指定控制类,用@RequestMapping("/home.htm")指定“映射器”的映射路径。用“@RequestMapping()”指定控制器的执行方法,以及返回的对象。在这里,HomePageController不需要在继承什么Controller对象了。如果访问http://localhost:8080/url/homePage.htm就触发sayHelloHomePage(Model model)方法,如果访问http://localhost:8080/home.htm,就会触发sayHello(Model model)。这样就OK了,当然,如果不需要向页面传值,Model model参数可以不要。index.jsp不需要修改。运行一下,看看结果:
[img] http://hiphotos.baidu.com/hivemind/pic/item/2f599811f44dba2acb80c43a.jpg[/img]
在使用同一个Controller处理多个URL时,可以通过一个URL地址,不同的请求参数来区别,如
@Controller
public class HomePageController {
@RequestMapping("/home.htm")
public String sayHello(Model model) {
model.addAttribute("rants","hello,world");
return "index";
}
@RequestMapping("/home.htm")
public String sayHelloHomePage(Model model) {
model.addAttribute("rants","spring MVC");
return "index";
}
}
执行结果如图:
另外,还可以通过HTTP Method来区别这些相同的URL请求
@RequestMapping(method = RequestMethod.GET,value = "/home.htm")
public String sayHello(Model model) {
model.addAttribute("rants","hello,world");
return "index";
}
@RequestMapping(method = RequestMethod.POST,value = "/home.htm")
public String sayHelloHomePage(Model model) {
model.addAttribute("rants","spring MVC");
return "index";
}
执行结果如图:
通过Controller方法返回一个ModelMap对象,在这种情况下,视图名由请求的URL决定
@RequestMapping(value = "/home.htm")
public String sayHelloModelMap() {
ModelMap model = new ModelMap();
model.addAttribute("rants", "spring ModelMap");
return model;
}
访问的路径必须是 http://localhost:8080/index.htm,需要和 @RequestMapping(value = "/home.htm") 对应
执行结果如下图示:
spring MVC还可以向Controller方法传入request,session等HttpServlet等特殊的对象
例如:
@RequestMapping(value = "/index.htm")
public void sayHelloHandleRequest(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
String param = request.getParameter("param");
logger.debug("parma value is: " + param);
if (param != null) {
session.setAttribute("param", param);
}
}
通过访问 http://localhost:8080/index.htm?param=hi,world ,可以得到如下结果:
请求参数的获取
在Controller方法中声明方法参数,那么同名的HTTP请求参数会自动转换为响应的类型,并传入到方法中。
如下面的代码,方法中的参数会自动和地址栏的参数做对应。
@RequestMapping(value = "/index.htm")
public void sayHelloParam(String username, String password, int age) {
logger.debug("username is: " + username);
logger.debug("password is: " + password);
logger.debug("age is: " + age);
}
执行截图:
参数自动映射到对象
具体就不多说了,见截图即可。
小结如下:
1、处理多个请求
>> 在每个方法前面使用@RequestMapping("/名称.htm"),不同的名称,处理不同的请求 缺点:xxx.htm太多不利于跟踪,复制程度增加。
>>在controller类前面定义@RequestMapping("/名称.htm"),在方法前面添加注释@RequestMapping(params="param=sec")来处理,分发器通过参数来决定执行哪个方法。
2、处理不同的http请求:
>>在方法前面增加注释:RequestMethod 有Post,get,put...如@RequestMapping(params="param=sec",method=RequestMethod.POST)
3、参数处理(自由转换类型):
>>普通属性:如果入参是基本数据类型(如int、long、float等),URL请求参数中一定要有对应的参数,否则将抛出TypeMismatchException异常,提示无法将null转换为基本数据类型。
>>对象及属性:Userbean的userID属性的类型是基本数据类型,但是如果URL中不存在userID参数,spring也不会报错,此时UserBean.userID的值为0 。如果userBean对象拥有一个dep.deptId的级联属性,那么它将和dept.deptId参数绑定。
4、参数处理(明确指定参数 匹配 自动转换类型)
>>普通属性和对象及属性:@RequestParam("id")注解,所以它将和id的URL参数绑定
5、绑定域中的某个属性
>> request ModelMap类,它作为通用的模型数据承载对象,传递数据供视图所用,代替request.setParam
>> Session @SessionAttributes("currUser") //(1)将ModelMap中属性名为currUser的属性放到session属性列表中,以便这个属性可以跨请求访问(写在类目的前面)
>> Session 多参数 @SessionAttributes({“attr1”,”attr2”})
>> 取值绑定到方法上 (@ModelAttribute("currUser") User user)。
web.xml和原来一样,没有变化。可以见《我的第一个springMVC例子之Hello world》里面的web.xml配置。也就说“分发器(Dispatcher)”没有变。主要变化在“控制器”和“映射处理器”方面。“视图解析器”也没有变化。见roadrantz-servlet.xml的内容,这里面变化挺大的。
roadrantz-servlet.xml
<?xml version="1.0"encoding="UTF-8"?>
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config></context:annotation-config>
<context:component-scanbase-package="com.baidu"></context:component-scan>
<beanid="viewResolver"class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<propertyname="prefix">
<value>/</value>
</property>
<propertyname="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>
在这里,不用在指定具体的Controller了,只需要指定Controller 具体的包(base-package="com.baidu")即可,spring回到此包下的所有注解进行扫描。这样配置就结束了。再看HomePageControler.java的代码:
HomePageController.java
packagecom.baidu;
importorg.springframework.stereotype.Controller;
importorg.springframework.ui.Model;
importorg.springframework.web.bind.annotation.RequestMapping;
/**
* Created by IntelliJ IDEA.
* User: liuzhaoyang
* Date: 2011-2-28
* Time: 22:43:08 */
@Controller
public class HomePageController {
@RequestMapping("/home.htm")
public String sayHello(Model model) {
model.addAttribute("rants","hello,world");
return "index";
}
@RequestMapping("/url/homePage.htm")
public String sayHelloHomePage(Model model) {
model.addAttribute("rants","spring MVC");
return "index";
}
}
----------------------------------------------
用“@Controller ”指定控制类,用@RequestMapping("/home.htm")指定“映射器”的映射路径。用“@RequestMapping()”指定控制器的执行方法,以及返回的对象。在这里,HomePageController不需要在继承什么Controller对象了。如果访问http://localhost:8080/url/homePage.htm就触发sayHelloHomePage(Model model)方法,如果访问http://localhost:8080/home.htm,就会触发sayHello(Model model)。这样就OK了,当然,如果不需要向页面传值,Model model参数可以不要。index.jsp不需要修改。运行一下,看看结果:
[img] http://hiphotos.baidu.com/hivemind/pic/item/2f599811f44dba2acb80c43a.jpg[/img]
在使用同一个Controller处理多个URL时,可以通过一个URL地址,不同的请求参数来区别,如
@Controller
public class HomePageController {
@RequestMapping("/home.htm")
public String sayHello(Model model) {
model.addAttribute("rants","hello,world");
return "index";
}
@RequestMapping("/home.htm")
public String sayHelloHomePage(Model model) {
model.addAttribute("rants","spring MVC");
return "index";
}
}
执行结果如图:
另外,还可以通过HTTP Method来区别这些相同的URL请求
@RequestMapping(method = RequestMethod.GET,value = "/home.htm")
public String sayHello(Model model) {
model.addAttribute("rants","hello,world");
return "index";
}
@RequestMapping(method = RequestMethod.POST,value = "/home.htm")
public String sayHelloHomePage(Model model) {
model.addAttribute("rants","spring MVC");
return "index";
}
执行结果如图:
通过Controller方法返回一个ModelMap对象,在这种情况下,视图名由请求的URL决定
@RequestMapping(value = "/home.htm")
public String sayHelloModelMap() {
ModelMap model = new ModelMap();
model.addAttribute("rants", "spring ModelMap");
return model;
}
访问的路径必须是 http://localhost:8080/index.htm,需要和 @RequestMapping(value = "/home.htm") 对应
执行结果如下图示:
spring MVC还可以向Controller方法传入request,session等HttpServlet等特殊的对象
例如:
@RequestMapping(value = "/index.htm")
public void sayHelloHandleRequest(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
String param = request.getParameter("param");
logger.debug("parma value is: " + param);
if (param != null) {
session.setAttribute("param", param);
}
}
通过访问 http://localhost:8080/index.htm?param=hi,world ,可以得到如下结果:
请求参数的获取
在Controller方法中声明方法参数,那么同名的HTTP请求参数会自动转换为响应的类型,并传入到方法中。
如下面的代码,方法中的参数会自动和地址栏的参数做对应。
@RequestMapping(value = "/index.htm")
public void sayHelloParam(String username, String password, int age) {
logger.debug("username is: " + username);
logger.debug("password is: " + password);
logger.debug("age is: " + age);
}
执行截图:
参数自动映射到对象
具体就不多说了,见截图即可。
小结如下:
1、处理多个请求
>> 在每个方法前面使用@RequestMapping("/名称.htm"),不同的名称,处理不同的请求 缺点:xxx.htm太多不利于跟踪,复制程度增加。
>>在controller类前面定义@RequestMapping("/名称.htm"),在方法前面添加注释@RequestMapping(params="param=sec")来处理,分发器通过参数来决定执行哪个方法。
2、处理不同的http请求:
>>在方法前面增加注释:RequestMethod 有Post,get,put...如@RequestMapping(params="param=sec",method=RequestMethod.POST)
3、参数处理(自由转换类型):
>>普通属性:如果入参是基本数据类型(如int、long、float等),URL请求参数中一定要有对应的参数,否则将抛出TypeMismatchException异常,提示无法将null转换为基本数据类型。
>>对象及属性:Userbean的userID属性的类型是基本数据类型,但是如果URL中不存在userID参数,spring也不会报错,此时UserBean.userID的值为0 。如果userBean对象拥有一个dep.deptId的级联属性,那么它将和dept.deptId参数绑定。
4、参数处理(明确指定参数 匹配 自动转换类型)
>>普通属性和对象及属性:@RequestParam("id")注解,所以它将和id的URL参数绑定
5、绑定域中的某个属性
>> request ModelMap类,它作为通用的模型数据承载对象,传递数据供视图所用,代替request.setParam
>> Session @SessionAttributes("currUser") //(1)将ModelMap中属性名为currUser的属性放到session属性列表中,以便这个属性可以跨请求访问(写在类目的前面)
>> Session 多参数 @SessionAttributes({“attr1”,”attr2”})
>> 取值绑定到方法上 (@ModelAttribute("currUser") User user)。