springmvc常用注解 注解 启动时报错

SpringMVC常用注解實例詳解3:@ResponseBody-Java-第七城市
SpringMVC常用注解實例詳解3:@ResponseBody
我的開發環境框架: & & & &springmvc+spring+freemarker開發工具: springsource-tool-suite-2.9.0JDK版本: 1.6.0_29tomcat版本:apache-tomcat-7.0.26前置文章-SpirngMVC配置入門&/sunang/p/3419544.html     &Spring整合Freemarker&/sunang/p/3419676.html@ResponseBody用于在controller方法中直接返回一個數據對象,常用于Ajax交互中,本文用Ajax交互的例子來演示下該註釋的用法。step1.由於Ajax傳輸數據用到JSON,所以要先添加JSON依賴如下:&Maven代碼如下:&!-- JSON --&&dependency&
&groupId&org.codehaus.jackson&/groupId&
&artifactId&jackson-core-asl&/artifactId&
&version&1.8.4&/version&&/dependency&&dependency&
&groupId&org.codehaus.jackson&/groupId&
&artifactId&jackson-mapper-asl&/artifactId&
&version&1.8.4&/version&&/dependency&在spring配置文件中加入JSON所需配置,此處以spring-servlet.xml為例,代碼如下:&!-- JSON所需配置 --&&bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"&
&property name="messageConverters"&
&ref bean="mappingJacksonHttpMessageConverter" /&
&/property&&/bean&&bean id="mappingJacksonHttpMessageConverter"
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"&
&property name="supportedMediaTypes"&
&value&application/charset=UTF-8&/value&
&/property&&/bean&&step2.編寫頁面ajaxGetMsg.ftl,代碼如下:&!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&&html xmlns="http://www.w3.org/1999/xhtml"&&html&&head&&meta http-equiv="Content-Type" content="text/ charset=UTF-8"&&!-- 引入jquery文件--&&script type="text/javascript" src="../js/jquery.js"&&/script&&title&Insert title here&/title&&/head&&body&&span id="content"&&!-- 點擊按鈕后調用getMsg()方法--&&button type="button" onclick="javascript:getMsg();"&@ResponseBody結合Ajax例子演示&/button&&/span&&/body&&/html&&script type="text/javascript"&function getMsg(){
var content = "";
//ajax訪問controller方法,利用@ResponseBody返回數據對象
async:false,
cache : false,
type : 'POST',
dataType : "json",
url:"ajaxGetMsg.htm",
success:function(data){
$.each(data, function(i,obj){
content=content+
$("#content").html(content);
error:function(){
alert("加载失败");
});}&/script&step3.編寫controller方法,代碼如下:package .import java.util.ArrayLimport java.util.Limport org.springframework.stereotype.Cimport org.springframework.web.bind.annotation.RequestMimport org.springframework.web.bind.annotation.ResponseB@Controller@RequestMapping("/learnMVC")public class LearnMVCController {
//前往初始頁面
@RequestMapping("/indexPage")
public String indexPage(){
return "ajaxGetMsg.ftl";
//Ajax交互方法
@RequestMapping("/ajaxGetMsg")
@ResponseBody
public List&String& ajaxGetMsg() {
List&String& strList = new ArrayList&String&();
strList.add("學");
strList.add("習");
strList.add("Spring");
strList.add("M");
strList.add("V");
strList.add("C");
return strL
}}indexPage()方法用於訪問初始頁面,ajaxGetMsg()方法上加了@ResponseBody註釋,所以該方法可以直接向頁面返回數據對象,該方法的返回數據類型為List&String&.step4.運行調試部署運行項目,瀏覽器訪問:http://localhost:8080/你的工程名/learnMVC/indexPage.htm運行結果如下:點擊按鈕,ajax加載數據得到如下結果:complete!系列文章鏈接:SpringMVC常用注解實例詳解:@Controller,@RequestMapping,@RequestParam,@PathVariable &&/sunang/p/3421707.html&SpringMVC常用注解實例詳解:@ModelAttribute & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &/sunang/p/3423227.html&&&& &文章主题:
交流经验:3830
总积分:261644
级别:VIP5
文章: 1162
6.1、注解式控制器简介
一、Spring2.5之前,我们都是通过实现Controller接口或其实现来定义我们的处理器类。已经@Deprecated。
二、Spring2.5引入注解式处理器支持,通过@Controller 和 @RequestMapping注解定义我们的处理器类。并且提供了一组强大的注解:
需要通过处理器映射DefaultAnnotationHandlerMapping和处理器适配器AnnotationMethodHandlerAdapter来开启支持@Controller 和 @RequestMapping注解的处理器。
@Controller:用于标识是处理器类;
@RequestMapping:请求到处理器功能方法的映射规则;
@RequestParam:请求参数到处理器功能处理方法的方法参数上的绑定;
@ModelAttribute:请求参数到命令对象的绑定;
@SessionAttributes:用于声明session级别存储的属性,放置在处理器类上,通常列出模型属性(如@ModelAttribute)对应的名称,则这些属性会透明的保存到session中;
@InitBinder:自定义数据绑定注册支持,用于将请求参数转换到命令对象属性的对应类型;
三、Spring3.0引入RESTful架构风格支持(通过@PathVariable注解和一些其他特性支持),且又引入了更多的注解支持:
@CookieValue:cookie数据到处理器功能处理方法的方法参数上的绑定;
@RequestHeader:请求头(header)数据到处理器功能处理方法的方法参数上的绑定;
@RequestBody:请求的body体的绑定(通过HttpMessageConverter进行类型转换);
@ResponseBody:处理器功能处理方法的返回值作为响应体(通过HttpMessageConverter进行类型转换);
@ResponseStatus:定义处理器功能处理方法/异常处理器返回的状态码和原因;
@ExceptionHandler:注解式声明异常处理器;
@PathVariable:请求URI中的模板变量部分到处理器功能处理方法的方法参数上的绑定,从而支持RESTful架构风格的URI;
四、Spring3.1使用新的HandlerMapping 和 HandlerAdapter来支持@Contoller和@RequestMapping注解处理器。
新的@Contoller和@RequestMapping注解支持类:处理器映射RequestMappingHandlerMapping 和 处理器适配器RequestMappingHandlerAdapter组合来代替Spring2.5开始的处理器映射DefaultAnnotationHandlerMapping和处理器适配器AnnotationMethodHandlerAdapter,提供更多的扩展点。
接下来,我们一起开始学习基于注解的控制器吧。
(1、控制器实现
java代码:
package cn.javass.chapter6.web.
//省略import
@Controller
// 或 @RequestMapping
//①将一个POJO类声明为处理器
public class HelloWorldController {
@RequestMapping(value = &/hello&)
//②请求URL到处理器功能处理方法的映射
public ModelAndView helloWorld() {
//1、收集参数
//2、绑定参数到命令对象
//3、调用业务对象
//4、选择下一个页面
ModelAndView mv = new ModelAndView();
//添加模型数据 可以是任意的POJO对象
mv.addObject(&message&, &Hello World!&);
//设置逻辑视图名,视图解析器会根据该名字解析到具体的视图页面
mv.setViewName(&hello&);
//○3 模型数据和逻辑视图名
1 可以通过在一个POJO类上放置@Controller或@RequestMapping,即可把一个POJO类变身为处理器;
2&@RequestMapping(value = &/hello&) 请求URL(/hello) 到 处理器的功能处理方法的映射;
3 模型数据和逻辑视图名的返回。
现在的处理器无需实现/继承任何接口/类,只需要在相应的类/方法上放置相应的注解说明下即可,非常方便。
(2、Spring配置文件chapter6-servlet.xml
(2.1、HandlerMapping和HandlerAdapter的配置
如果您使用的是Spring3.1之前版本,开启注解式处理器支持的配置为:DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter。
java代码:
&!—Spring3.1之前的注解 HandlerMapping --&
class=&org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping&/&
&!—Spring3.1之前的注解 HandlerAdapter --&
class=&org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter&/&
如果您使用的Spring3.1开始的版本,建议使用RequestMappingHandlerMapping和RequestMappingHandlerAdapter。
java代码:
&!--Spring3.1开始的注解 HandlerMapping --&
class=&org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping&/&
&!--Spring3.1开始的注解 HandlerAdapter --&
class=&org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter&/&
下一章我们介绍DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter 与RequestMappingHandlerMapping和RequestMappingHandlerAdapter 的区别。
(2.2、视图解析器的配置
还是使用之前的org.springframework.web.servlet.view.InternalResourceViewResolver。
(2.3、处理器的配置
java代码:
&!-- 处理器 --&
&bean class=&cn.javass.chapter6.web.controller.HelloWorldController&/&
只需要将处理器实现类注册到spring配置文件即可,spring的DefaultAnnotationHandlerMapping或RequestMappingHandlerMapping能根据注解@Controller或@RequestMapping自动发现。
(2.3、视图页面(/WEB-INF/jsp/hello.jsp)
java代码:
&%@ page language=&java& contentType=&text/ charset=UTF-8& pageEncoding=&UTF-8&%&
&!DOCTYPE html PUBLIC &-//W3C//DTD HTML 4.01 Transitional//EN& &http://www.w3.org/TR/html4/loose.dtd&&
&meta http-equiv=&Content-Type& content=&text/ charset=UTF-8&&
&title&Hello World&/title&
${message}
${message}:表示显示由HelloWorldController处理器传过来的模型数据。
(4、启动服务器测试
地址栏输入,我们将看到页面显示“Hello World!”,表示成功了。
整个过程和我们第二章中的Hello World 类似,只是处理器的实现不一样。接下来我们来看一下具体流程吧。
6.3、运行流程
和第二章唯一不同的两处是:
1、HandlerMapping实现:使用DefaultAnnotationHandlerMapping(spring3.1之前)或RequestMappingHandlerMapping(spring3.1)替换之前的BeanNameUrlHandlerMapping。
注解式处理器映射会扫描spring容器中的bean,发现bean实现类上拥有@Controller或@RequestMapping注解的bean,并将它们作为处理器。
2、HandlerAdapter实现:使用AnnotationMethodHandlerAdapter(spring3.1之前)或RequestMappingHandlerAdapter(spring3.1)替换之前的SimpleControllerHandlerAdapter。
注解式处理器适配器会通过反射调用相应的功能处理方法(方法上拥有@RequestMapping注解)。
好了到此我们知道Spring如何发现处理器、如何调用处理的功能处理方法了,接下来我们详细学习下如何定义处理器、如何进行请求到功能处理方法的定义。
6.4、处理器定义
6.4.1、@Controller
java代码:
@Controller
public class HelloWorldController {
推荐使用这种方式声明处理器,它和我们的@Service、@Repository很好的对应了我们常见的三层开发架构的组件。
6.4.2、@RequestMapping
java代码:
@RequestMapping
public class HelloWorldController {
这种方式也是可以工作的,但如果在类上使用@ RequestMapping注解一般是用于窄化功能处理方法的映射的,详见6.4.3。
package cn.javass.chapter6.web.
@Controller
@RequestMapping(value=&/user&)&&&&&&&&&&&&&&&& //①处理器的通用映射前缀
public class HelloWorldController2 {
&&& @RequestMapping(value = &/hello2&)&&&&&&& //②相对于①处的映射进行窄化
&&& public ModelAndView helloWorld() {
&&&&&&&& //省略实现
6.4.3、窄化请求映射
java代码:
package cn.javass.chapter6.web.
@Controller
@RequestMapping(value=&/user&)
//①处理器的通用映射前缀
public class HelloWorldController2 {
@RequestMapping(value = &/hello2&)
//②相对于①处的映射进行窄化
public ModelAndView helloWorld() {
//省略实现
①类上的@RequestMapping(value=&/user&) 表示处理器的通用请求前缀;
②处理器功能处理方法上的是对①处映射的窄化。
因此的 helloWorld功能处理方法;而是可以的。
窄化请求映射可以认为是方法级别的@RequestMapping继承类级别的@RequestMapping。
窄化请求映射还有其他方式,如在类级别指定URL,而方法级别指定请求方法类型或参数等等,后续会详细介绍。
到此,我们知道如何定义处理器了,接下来我们需要学习如何把请求映射到相应的功能处理方法进行请求处理。
6.5、请求映射
处理器定义好了,那接下来我们应该定义功能处理方法,接收用户请求处理并选择视图进行渲染。首先我们看一下图6-1:
http请求信息包含六部分信息:
①请求方法,如GET或POST,表示提交的方式;
②URL,请求的地址信息;
③协议及版本;
④请求头信息(包括Cookie信息);
⑤回车换行(CRLF);
⑥请求内容区(即请求的内容或数据),如表单提交时的参数数据、URL请求参数(?abc=123 ?后边的)等。
想要了解HTTP/1.1协议,请访问。
那此处我们可以看到有①、②、④、⑥一般是可变的,因此我们可以这些信息进行请求到处理器的功能处理方法的映射,因此请求的映射分为如下几种:
URL路径映射:使用URL映射请求到处理器的功能处理方法;
请求方法映射限定:如限定功能处理方法只处理GET请求;
请求参数映射限定:如限定只处理包含“abc”请求参数的请求;
请求头映射限定:如限定只处理“Accept=application/json”的请求。
接下来看看具体如何映射吧。
原创内容()
原创内容,转载请注明私塾在线【】
这篇文章被编辑了 1 次. 最近一次更新是在
精品视频课程推荐
WebLogic基础知识:WebLogic基本概念、正确安装WebLogic、建域、应用部署于JDBC选择、对WebLogic的监控和日志查看、集群的高可用性;课程目标:彻底掌握WebLogic的基本概念,在理解基本概念的基础上做到正确的安装WebLogic,根据不同的需求创建域,合理选择应用部署和JDBC配置。熟练掌握WebLogic的console监控,了解各种性能和运行指标,以及对监控结果的分析,运用集群的高可用性,对集群架设。
本视频课程是北京Java私塾原创精品书籍《研磨设计模式》一书的配套学习视频,由《研磨设计模式》的第一作者CC录制
课程目标:全面、系统的掌握GoF设计模式的知识,达到可以在实际项目开发中运用的能力
技术要点:如何实现可配置、如何实现缓存以及缓存的管理、如何实现用缓存来控制多实例的创建、如何实现参数化工厂、 如何实现可扩展工厂、如何实现原型管理器、如何实现Java的静态代理和动态代理、如何实现多线程处理队列请求、 如何实现命令的参数化配置、可撤销的操作、宏命令、队列请求和日志请求、如何实现翻页迭代、如何检测环状结构、 如何实现通用的增删改查、如何模拟工作流来处理流程、如何实现简单又通用的XML读取、如何实现模拟AOP的功能......
本课程专注于数据结构和算法的内容,使用Java来进行代码示例,不空洞的讲解概念和理论,重点放在代码的实现和示例上。
从零开始、全面系统、成体系的讲解数据结构和基本算法,循序渐进的讲述构建软件系统所常见的数据结构和算法。
系统、完整的学习Spring Web MVC开发的知识。包括:Spring Web MVC入门;理解DispatcherServlet;注解式控制器开发详解;数据类型转换;数据格式化;数据验证; 拦截器;对Ajax的支持;文件上传下载;表单标签等内容;最后以一个综合的CRUD带翻页的应用示例来综合所学的知识
深入浅出的讲解Struts2对AJAX的支持,包括使用stream的Result Type来应用Ajax;使用Struts2提供的Ajax标签;使用JSON插件
&& &文章主题:
交流经验:0
总积分:300
级别:普通会员
狠狠的学习了。
选择一个版面
软件设计专版
Web前端技术
学习问题讨论
面试、就业
版权所有 Copyright(C) 私塾在线学习网SpringMVC强大的数据绑定(2)——第六章 注解式控制器详解——跟着开涛学SpringMVC - 开涛的博客 - ITeye技术网站
博客分类:
6.6.2、@RequestParam绑定单个请求参数值
@RequestParam用于将请求参数区数据映射到功能处理方法的参数上。
public String requestparam1(@RequestParam String username)
请求中包含username参数(如/requestparam1?username=zhang),则自动传入。
此处要特别注意:右击项目,选择“属性”,打开“属性对话框”,选择“Java Compiler”然后再打开的选项卡将“Add variable attributes to generated class files”取消勾选,意思是不将局部变量信息添加到类文件中,如图6-12所示:
当你在浏览器输入URL,如“requestparam1?username=123”时会报如下错误
Name for argument type [java.lang.String] not available, and parameter name information not found in class file either,表示得不到功能处理方法的参数名,此时我们需要如下方法进行入参:
public String requestparam2(@RequestParam("username") String username)
即通过@RequestParam("username")明确告诉Spring Web MVC使用username进行入参。
接下来我们看一下@RequestParam注解主要有哪些参数:
value:参数名字,即入参的请求参数名字,如username表示请求的参数区中的名字为username的参数的值将传入;
required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报404错误码;
defaultValue:默认值,表示如果请求中没有同名参数时的默认值,默认值可以是SpEL表达式,如“#{systemProperties['java.vm.version']}”。
public String requestparam4(@RequestParam(value="username",required=false) String username)
表示请求中可以没有名字为username的参数,如果没有默认为null,此处需要注意如下几点:
原子类型:必须有值,否则抛出异常,如果允许空值请使用包装类代替。
Boolean包装类型类型:默认Boolean.FALSE,其他引用类型默认为null。
public String requestparam5(
@RequestParam(value="username", required=true, defaultValue="zhang") String username)
表示如果请求中没有名字为username的参数,默认值为“zhang”。
如果请求中有多个同名的应该如何接收呢?如给用户授权时,可能授予多个权限,首先看下如下代码:
public String requestparam7(@RequestParam(value="role") String roleList)
如果请求参数类似于url?role=admin&rule=user,则实际roleList参数入参的数据为“admin,user”,即多个数据之间使用“,”分割;我们应该使用如下方式来接收多个请求参数:
public String requestparam7(@RequestParam(value="role") String[] roleList)
public String requestparam8(@RequestParam(value="list") List&String& list)
到此@RequestParam我们就介绍完了,以上测试代码在cn.javass.chapter6.web.controller. paramtype.RequestParamTypeController中。
6.6.3、@PathVariable绑定URI模板变量值
@PathVariable用于将请求URL中的模板变量映射到功能处理方法的参数上。
@RequestMapping(value="/users/{userId}/topics/{topicId}")
public String test(
@PathVariable(value="userId") int userId,
@PathVariable(value="topicId") int topicId)
如请求的URL为“控制器URL/users/123/topics/456”,则自动将URL中模板变量{userId}和{topicId}绑定到通过@PathVariable注解的同名参数上,即入参后userId=123、topicId=456。代码在PathVariableTypeController中。
6.6.4、@CookieValue绑定Cookie数据值
@CookieValue用于将请求的Cookie数据映射到功能处理方法的参数上。
public String test(@CookieValue(value="JSESSIONID", defaultValue="") String sessionId)
如上配置将自动将JSESSIONID值入参到sessionId参数上,defaultValue表示Cookie中没有JSESSIONID时默认为空。
public String test2(@CookieValue(value="JSESSIONID", defaultValue="") Cookie sessionId)
传入参数类型也可以是javax.servlet.http.Cookie类型。
测试代码在CookieValueTypeController中。@CookieValue也拥有和@RequestParam相同的三个参数,含义一样。
6.6.5、@RequestHeader绑定请求头数据
@RequestHeader用于将请求的头信息区数据映射到功能处理方法的参数上。
@RequestMapping(value="/header")
public String test(
@RequestHeader("User-Agent") String userAgent,
@RequestHeader(value="Accept") String[] accepts)
如上配置将自动将请求头“User-Agent”值入参到userAgent参数上,并将“Accept”请求头值入参到accepts参数上。测试代码在HeaderValueTypeController中。
@RequestHeader也拥有和@RequestParam相同的三个参数,含义一样。
6.6.6、@ModelAttribute绑定请求参数到命令对象
@ModelAttribute一个具有如下三个作用:
①绑定请求参数到命令对象:放在功能处理方法的入参上时,用于将多个请求参数绑定到一个命令对象,从而简化绑定流程,而且自动暴露为模型数据用于视图页面展示时使用;
②暴露表单引用对象为模型数据:放在处理器的一般方法(非功能处理方法)上时,是为表单准备要展示的表单引用对象,如注册时需要选择的所在城市等,而且在执行功能处理方法(@RequestMapping注解的方法)之前,自动添加到模型对象中,用于视图页面展示时使用;
③暴露@RequestMapping方法返回值为模型数据:放在功能处理方法的返回值上时,是暴露功能处理方法的返回值为模型数据,用于视图页面展示时使用。
一、绑定请求参数到命令对象
如用户登录,我们需要捕获用户登录的请求参数(用户名、密码)并封装为用户对象,此时我们可以使用@ModelAttribute绑定多个请求参数到我们的命令对象。
public String test1(@ModelAttribute("user") UserModel user)
和6.6.1一节中的五、命令/表单对象功能一样。只是此处多了一个注解@ModelAttribute("user"),它的作用是将该绑定的命令对象以“user”为名称添加到模型对象中供视图页面展示使用。我们此时可以在视图页面使用${user.username}来获取绑定的命令对象的属性。
绑定请求参数到命令对象支持对象图导航式的绑定,如请求参数包含“?username=zhang&password=123&workInfo.city=bj”自动绑定到user中的workInfo属性的city属性中。
@RequestMapping(value="/model2/{username}")
public String test2(@ModelAttribute("model") DataBinderTestModel model) {
DataBinderTestModel相关模型请从第三章拷贝过来,请求参数到命令对象的绑定规则详见【4.16.1、数据绑定】一节,URI模板变量也能自动绑定到命令对象中,当你请求的URL中包含“bool=yes&schooInfo.specialty=computer&hobbyList[0]=program&hobbyList[1]=music&map[key1]=value1&map[key2]=value2&state=blocked”会自动绑定到命令对象上。
当URI模板变量和请求参数同名时,URI模板变量具有高优先权。
二、暴露表单引用对象为模型数据
@ModelAttribute("cityList")
public List&String& cityList() {
return Arrays.asList("北京", "山东");
如上代码会在执行功能处理方法之前执行,并将其自动添加到模型对象中,在功能处理方法中调用Model 入参的containsAttribute("cityList")将会返回true。
@ModelAttribute("user")
public UserModel getUser(@RequestParam(value="username", defaultValue="") String username) {
//TODO 去数据库根据用户名查找用户对象
UserModel user = new UserModel();
user.setRealname("zhang");
如你要修改用户资料时一般需要根据用户的编号/用户名查找用户来进行编辑,此时可以通过如上代码查找要编辑的用户。
也可以进行一些默认值的处理。
@RequestMapping(value="/model1") //②
public String test1(@ModelAttribute("user") UserModel user, Model model)
此处我们看到①和②有同名的命令对象,那Spring Web MVC内部如何处理的呢:
(1、首先执行@ModelAttribute注解的方法,准备视图展示时所需要的模型数据;@ModelAttribute注解方法形式参数规则和@RequestMapping规则一样,如可以有@RequestParam等;
(2、执行@RequestMapping注解方法,进行模型绑定时首先查找模型数据中是否含有同名对象,如果有直接使用,如果没有通过反射创建一个,因此②处的user将使用①处返回的命令对象。即②处的user等于①处的user。
三、暴露@RequestMapping方法返回值为模型数据
public @ModelAttribute("user2") UserModel test3(@ModelAttribute("user2") UserModel user)
大家可以看到返回值类型是命令对象类型,而且通过@ModelAttribute("user2")注解,此时会暴露返回值到模型数据(名字为user2)中供视图展示使用。那哪个视图应该展示呢?此时Spring Web MVC会根据RequestToViewNameTranslator进行逻辑视图名的翻译,详见【4.15.5、RequestToViewNameTranslator】一节。
此时又有问题了,@RequestMapping注解方法的入参user暴露到模型数据中的名字也是user2,其实我们能猜到:
(3、@ModelAttribute注解的返回值会覆盖@RequestMapping注解方法中的@ModelAttribute注解的同名命令对象。
四、匿名绑定命令参数
public String test4(@ModelAttribute UserModel user, Model model)
public String test5(UserModel user, Model model)
此时我们没有为命令对象提供暴露到模型数据中的名字,此时的名字是什么呢?Spring Web MVC自动将简单类名(首字母小写)作为名字暴露,如“cn.javass.chapter6.model.UserModel”暴露的名字为“userModel”。
public @ModelAttribute List&String& test6()
public @ModelAttribute List&UserModel& test7()
对于集合类型(Collection接口的实现者们,包括数组),生成的模型对象属性名为“简单类名(首字母小写)”+“List”,如List&String&生成的模型对象属性名为“stringList”,List&UserModel&生成的模型对象属性名为“userModelList”。
其他情况一律都是使用简单类名(首字母小写)作为模型对象属性名,如Map&String, UserModel&类型的模型对象属性名为“map”。
6.6.7、@SessionAttributes绑定命令对象到session
有时候我们需要在多次请求之间保持数据,一般情况需要我们明确的调用HttpSession的API来存取会话数据,如多步骤提交的表单。Spring Web MVC提供了@SessionAttributes进行请求间透明的存取会话数据。
//1、在控制器类头上添加@SessionAttributes注解
@SessionAttributes(value = {"user"})
public class SessionAttributeController
//2、@ModelAttribute注解的方法进行表单引用对象的创建
@ModelAttribute("user")
public UserModel initUser()
//3、@RequestMapping注解方法的@ModelAttribute注解的参数进行命令对象的绑定
@RequestMapping("/session1")
public String session1(@ModelAttribute("user") UserModel user)
//4、通过SessionStatus的setComplete()方法清除@SessionAttributes指定的会话数据
@RequestMapping("/session2")
public String session(@ModelAttribute("user") UserModel user, SessionStatus status) {
if(true) { //④
status.setComplete();
return "success";
@SessionAttributes(value = {"user"})含义:
@SessionAttributes(value = {"user"}) 标识将模型数据中的名字为“user” 的对象存储到会话中(默认HttpSession),此处value指定将模型数据中的哪些数据(名字进行匹配)存储到会话中,此外还有一个types属性表示模型数据中的哪些类型的对象存储到会话范围内,如果同时指定value和types属性则那些名字和类型都匹配的对象才能存储到会话范围内。
包含@SessionAttributes的执行流程如下所示:
① 首先根据@SessionAttributes注解信息查找会话内的对象放入到模型数据中;
② 执行@ModelAttribute注解的方法:如果模型数据中包含同名的数据,则不执行@ModelAttribute注解方法进行准备表单引用数据,而是使用①步骤中的会话数据;如果模型数据中不包含同名的数据,执行@ModelAttribute注解的方法并将返回值添加到模型数据中;
③ 执行@RequestMapping方法,绑定@ModelAttribute注解的参数:查找模型数据中是否有@ModelAttribute注解的同名对象,如果有直接使用,否则通过反射创建一个;并将请求参数绑定到该命令对象;
此处需要注意:如果使用@SessionAttributes注解控制器类之后,③步骤一定是从模型对象中取得同名的命令对象,如果模型数据中不存在将抛出HttpSessionRequiredException Expected session attribute ‘user’(Spring3.1)
或HttpSessionRequiredException Session attribute ‘user’ required - not found in session(Spring3.0)异常。
④ 如果会话可以销毁了,如多步骤提交表单的最后一步,此时可以调用SessionStatus对象的setComplete()标识当前会话的@SessionAttributes指定的数据可以清理了,此时当@RequestMapping功能处理方法执行完毕会进行清理会话数据。
我们通过Spring Web MVC的源代码验证一下吧,此处我们分析的是Spring3.1的RequestMappingHandlerAdapter,读者可以自行验证Spring3.0的AnnotationMethodHandlerAdapter,流程一样:
(1、RequestMappingHandlerAdapter.invokeHandlerMethod
//1、RequestMappingHandlerAdapter首先调用ModelFactory的initModel方法准备模型数据:
modelFactory.initModel(webRequest, mavContainer, requestMappingMethod);
//2、调用@RequestMapping注解的功能处理方法
requestMappingMethod.invokeAndHandle(webRequest, mavContainer);
//3、更新/合并模型数据
modelFactory.updateModel(webRequest, mavContainer);
(2、ModelFactory.initModel
Map&String, ?& attributesInSession = this.sessionAttributesHandler.retrieveAttributes(request);
//1.1、将与@SessionAttributes注解相关的会话对象放入模型数据中
mavContainer.mergeAttributes(attributesInSession);
//1.2、调用@ModelAttribute方法添加表单引用对象
invokeModelAttributeMethods(request, mavContainer);
//1.3、验证模型数据中是否包含@SessionAttributes注解相关的会话对象,不包含抛出异常
for (String name : findSessionAttributeArguments(handlerMethod)) {
if (!mavContainer.containsAttribute(name)) {
//1.4、此处防止在@ModelAttribute注解方法又添加了会话对象
//如在@ModelAttribute注解方法调用session.setAttribute("user", new UserModel());
Object value = this.sessionAttributesHandler.retrieveAttribute(request, name);
if (value == null) {
throw new HttpSessionRequiredException("Expected session attribute '" + name + "'");
mavContainer.addAttribute(name, value);
(3、ModelFactory.invokeModelAttributeMethods
for (InvocableHandlerMethod attrMethod : this.attributeMethods) {
String modelName = attrMethod.getMethodAnnotation(ModelAttribute.class).value();
//1.2.1、如果模型数据中包含同名数据则不再添加
if (mavContainer.containsAttribute(modelName)) {
//1.2.2、调用@ModelAttribute注解方法并将返回值添加到模型数据中,此处省略实现代码
(4、requestMappingMethod.invokeAndHandle 调用功能处理方法,此处省略
(5、ModelFactory.updateMode 更新模型数据
//3.1、如果会话被标识为完成,此时从会话中清除@SessionAttributes注解相关的会话对象
if (mavContainer.getSessionStatus().isComplete()){
this.sessionAttributesHandler.cleanupAttributes(request);
//3.2、如果会话没有完成,将模型数据中的@SessionAttributes注解相关的对象添加到会话中
this.sessionAttributesHandler.storeAttributes(request, mavContainer.getModel());
//省略部分代码
到此@SessionAtrribute介绍完毕,测试代码在cn.javass.chapter6.web.controller.paramtype.SessionAttributeController中。
另外cn.javass.chapter6.web.controller.paramtype.WizardFormController是一个类似于【4.11、AbstractWizardFormController】中介绍的多步骤表单实现,此处不再贴代码,多步骤提交表单需要考虑会话超时问题,这种方式可能对用户不太友好,我们可以采取隐藏表单(即当前步骤将其他步骤的表单隐藏)或表单数据存数据库(每步骤更新下数据库数据)等方案解决。
6.6.8、@Value绑定SpEL表示式
@Value用于将一个SpEL表达式结果映射到到功能处理方法的参数上。
public String test(@Value("#{systemProperties['java.vm.version']}") String jvmVersion)
到此数据绑定我们就介绍完了,对于没有介绍的方法参数和注解(包括自定义注解)在后续章节进行介绍。接下来我们学习下数据类型转换吧。
转载请注明出处【】
浏览 44920
您好,想请教一个Spring MVC 数据绑定的问题:需求是这样的,在表单提前之前,我希望表单提交时,比较Bean哪些属性已经被修改。但是使用@ModelAttribute 注解在Controler里面根据ID再去数据库(使用Hibernate)捞原始对象的时候,Bean已经被自动数据绑定为新的值,无法得到原来的修改之前(数据绑定之前)的值。请问您有什么解决方案?谢谢1\使用 bean merge工具 如Dozer2\在页面中隐藏所有其他的3\写一个类似于@ModelAttribute的注解,实现:& 先根据id查出数据,然后覆盖4\使用hibernate merge(如果传了所有数据)5\只能自己覆盖了
& 你好,tao哥!我用spring_mvc架构通过js向后台传递form表单,在对form表单进行序列化的时候,直接使用$form.find("input[name='persistent']").val("false")是正常的,序列化以后格式和url参数的格式一样,我在controller里直接获取VO实体就行了。但是如果在一个js里涉及到的三张表中有同名的字段,该怎么传递呢?用“实体对象名.属性名”不行,我试过$form.find("input[name='datameta.persistent']").val("false");但这样序列化以后是空值……1、在做个聚合Model如Merge {&& A&& B&& C}2、使用我之前的@FormModel
灵魂跳舞· 写道tao哥,一直有一个疑问,因为项目经验不是很丰富,一直不明白:@RequestMapping(value="/users/{userId}/topics/{topicId}")& public String test(& &&&&&& @PathVariable(value="userId") int userId,&& &&&&&& @PathVariable(value="topicId") int topicId)&&&&&& }就是类似这种带有ant风格(即?、*和**)与{}这种类型的URL,适用与一些什么场合?还有就是@RequestParam这些参数注解标签,我用Spring一直没写过,都是直接定义好与URL对应的属性名,就能直接接收,是因为HandleMapping解析的时候就默认有@RequestParam的功能?(见谅,可能您其他文章有提及,但是其他文章我还没来得及看,但是有疑问又憋的慌)其实这种情况确实很少,比如在用过滤器时这个用的比较多一点,比如权限的控制关于注解写于不写,在前面问问题的兄弟那里看到了您的回答,明白了,非常感谢
tao哥,一直有一个疑问,因为项目经验不是很丰富,一直不明白:@RequestMapping(value="/users/{userId}/topics/{topicId}")& public String test(& &&&&&& @PathVariable(value="userId") int userId,&& &&&&&& @PathVariable(value="topicId") int topicId)&&&&&& }就是类似这种带有ant风格(即?、*和**)与{}这种类型的URL,适用与一些什么场合?还有就是@RequestParam这些参数注解标签,我用Spring一直没写过,都是直接定义好与URL对应的属性名,就能直接接收,是因为HandleMapping解析的时候就默认有@RequestParam的功能?(见谅,可能您其他文章有提及,但是其他文章我还没来得及看,但是有疑问又憋的慌)其实这种情况确实很少,比如在用过滤器时这个用的比较多一点,比如权限的控制
你好,有个问题请教一下假如我的controller有一个功能方法,形参是两个相同类型的对象,比如都是User,一个user1,一个user2,此时我该如何绑定@RequestMapping(value="/login",method=RequestMethod.POST)
public String login(User user1,User user1)
下面的意思是,当返回一个视图,或不返回时,都可以在页面通过${user.username}来取值吗?==============================================================一、绑定请求参数到命令对象如用户登录,我们需要捕获用户登录的请求参数(用户名、密码)并封装为用户对象,此时我们可以使用@ModelAttribute绑定多个请求参数到我们的命令对象。public String test1(@ModelAttribute("user") UserModel user)& 和6.6.1一节中的五、命令/表单对象功能一样。只是此处多了一个注解@ModelAttribute("user"),它的作用是将该绑定的命令对象以“user”为名称添加到模型对象中供视图页面展示使用。我们此时可以在视图页面使用${user.username}来获取绑定的命令对象的属性。是的 不加xmlConfigApplicationContext一样&
public String test1(@ModelAttribute("user") UserModel user)这里面的@ModelAttribute("user")可以不用写吧,我试了不写也是可以填充到model里面的。一、绑定请求参数到命令对象如用户登录,我们需要捕获用户登录的请求参数(用户名、密码)并封装为用户对象,此时我们可以使用@ModelAttribute绑定多个请求参数到我们的命令对象。&& public String test1(@ModelAttribute("user") UserModel user)& 和6.6.1一节中的五、命令/表单对象功能一样。只是此处多了一个注解@ModelAttribute("user"),它的作用是将该绑定的命令对象以“user”为名称添加到模型对象中供视图页面展示使用。我们此时可以在视图页面使用${user.username}来获取绑定的命令对象的属性。是的,不写会通过字节码查找属性名 默认就是局部变量名(局部变量名必须开启编译器的 存变量名,否则可能拿不到)@ModelAttribute("user")& 可以指定其他名字 或自己预先实例化(即从model中拿到一个已存在的同名模型,然后再绑定数据)
有个问题我想问一下,就是@ModelAttribute注解的方法,是不是会在这个controller中所有的@RequestMapping方法调用之前就调用?如果某些方法不需要这个调用是不是也会调用?也就是说ModelAttribute注解的方法已经跟这个controller中的RequestMapping方法绑定了,无论执行哪个都会调用@ModelAttribute注解的方法?是的
您好,我是springMVC的初学者,我遇到了一个问题,在我的Controller的方法里有两个参数,一个是javaBean,一个是String如下
@RequestMapping("test.do")
@ResponseBody
public boolean test(String test,@RequestBody TMailAccount account){
System.out.println(account);
System.out.println(test);
我在客户端使用httpPost进行发送请求:
HttpPost post = new HttpPost("http://localhost:8080/mailbill.dataserver"+url);
post.addHeader("Accept","application/json");
post.addHeader("Content-Type", "application/json");
TMailAccount account = new TMailAccount();
account.setMailaccount("");
Map&String,Object& map = new HashMap&String, Object&();
map.put("test", "test");
map.put("account", account);
String json = JsonUtil.objectToJackson(map);
System.out.println(json);
StringEntity para = new StringEntity(json, "UTF-8");
post.setEntity(para);
response = client.execute(post, new BasicResponseHandler());
可是controller接收后的参数值为空,请问客户端发送json数据该怎么写?谢谢!你好,@RequestBody 是把http的body部分转换,你的body是{&& test:test,&& account : account}怎么可能给@RequestBody TMailAccount account, 而如果只传account是没问题的。 所以解决方案:1、ModelAttribute + RequestParam2、使用Map来接,然后再获取 这需要传的过程中加上类型信息
上面那个问题我等了好几天,以为没回复了,想不到还有回复。 在Controller中支持用@RequestBody把json绑定成List&object&吗(public String update(Model model ,@RequestBody List&Color& list)),我用list.get(i)获取类型显示为String,我实际上想获取Object,能指点下吗?jackson的问题1、 定义一个Wrapper Wrapper { List&Color& }2、启动默认类型识别objectMapper.enableDefaultTyping();数据中带类型信息{"2":["com.mon.entity.User",{"id":2,"username":"li","password":null,"registerDate":null,"baseInfo":{"id":null,"realname":"lisan","sex":"male","birthday":7,"age":0},"schoolInfoSet":["java.util.HashSet",[{"id":null,"name":null,"type":"high_school"}]]}],"1":["com.mon.entity.User",{"id":1,"username":"zhang","password":null,"registerDate":null,"baseInfo":{"id":null,"realname":"zhangsan","sex":"female","birthday":7,"age":0},"schoolInfoSet":["java.util.HashSet",[{"id":null,"name":null,"type":"high_school"}]]}]}
& 上一页 1
jinnianshilongnian
浏览: 3776368 次
浏览量:773958
浏览量:693183
浏览量:1212182
浏览量:94078
浏览量:269526
浏览量:96046
浏览量:421580
浏览量:12752
天涯陌路 写道A208JASON 写道楼主,我碰到一种情况,按 ...
“tao哥”呀,我用泛型注入+spring-data-jpa就 ...
freeboat 写道这种方法用过之后一直有一个问题没解决,就 ...
这种方法用过之后一直有一个问题没解决,就是查询出来之后总是会自 ...
学习啦,必须膜拜

我要回帖

更多关于 springmvc常用注解 的文章

 

随机推荐