SpringMVC之Controller和参数绑定
在上一篇Spring+SpringMVC+Mybatis整合中说到了SSM的整合,并且在其中添加了一个简单的查询功能,目的只是将整个整合的流程进行一个梳理,下面在上一篇中工程的基础上再说一些关于SpringMVC的Controller的一些细节。
首先附上整个项目结构图,附上整个代码工程的下载地址,下面所讲到的测试用例都是在下面这个测试项目的基础上进行的。
一、关于Controller的注解形式
1、使用@Controller注解可以实现Controller的注解开发,然后在springmvc.xml的配置文件中配置注解扫描器,就可以使用注解形式进行Controller的开发,下面我们简单使用一个helloworld的例子进行说明
①在springmvc.xml中配置注解扫描器
其中也当然包含springmvc所需要的处理器映射器、处理器适配器、视图解析器(这几个组件个概念可以查看SpringMvc入门,其中开篇说到了SpringMVC的处理流程和各个组件以及之间的关系),我们这里直接使用下面的配置方式进行配置
②写一个简单的helloworld,在浏览器中请求对应的Controller,然后输出在页面上
1 package cn.test.ssm.controller;2 3 import org.springframework.stereotype.Controller;4 import org.springframework.web.bind.annotation.RequestMapping;5 import org.springframework.web.servlet.ModelAndView;6 7 @Controller8 public class HelloWorldController {9
10 @RequestMapping("/helloWorld.do")
11 public ModelAndView helloWorld() throws Exception{
12 ModelAndView modelAndView = new ModelAndView();
13 modelAndView.addObject("test","HelloSSM");
14 modelAndView.setViewName("/WEB-INF/items/hello.jsp");
15 return modelAndView;
16 }
17 }复制代码
1 <%@ page contentType="text/html;charset=UTF-8" language="java" %>2 <html>3 <head>4 <title>$Title$</title>5 </head>6 <body>7 测试Controller8 ${test}9 </body>
10 </html>复制代码
③然后在地址栏中请求http://localhost:8080/TestSSM2/helloWorld.do,输出
二、关于RequestMapping
1、使用不同的处理器映射规则
a、我们通过RequestMapping 可以使用不同的处理器映射规则,RequestMapping注解能够控制http请求的路径和方式(get、post......),在同一个Controller中可以写不同的映射方法,映射浏览器不同的请求业务。
具体的使用方式就是:@RequestMapping(value="/test.do")或@RequestMapping("/test),其中value的值是数组,可以将多个url映射到同一个方法
b、下面我们就在上一篇中查询列表的基础上增加查询详细信息的一个功能,通过RequestMapping注解来实现
①首先在mapper中将ProductDemo.xml中添加查询详细信息的Sql配置
<select id="queryProductInfo" parameterType="java.lang.Integer" resultType="cn.test.ssm.po.ProductExtend">SELECT pname,shop_price FROM product WHERE pid = #{id}</select>复制代码
②在mapper接口中添加上面的方法
③在service接口中添加相应的方法和方法实现
service接口
接口实现类
④在controller层中加上queryInfo方法,其中使用RequestMapping映射了两个不同请求对应的方法实现
1 package cn.test.ssm.controller;2 3 import cn.test.ssm.po.ProductExtend;4 import cn.test.ssm.service.ProductService;5 import org.springframework.beans.factory.annotation.Autowired;6 import org.springframework.stereotype.Controller;7 import org.springframework.web.bind.annotation.RequestMapping;8 import org.springframework.web.servlet.ModelAndView;9
10 import java.util.List;
11
12 @Controller
13 public class ProductController {
14
15 @Autowired
16 private ProductService productService;
17
18 @RequestMapping("/queryList.do")
19 public ModelAndView queryList() throws Exception{
20 //从service层调用方法
21 List<ProductExtend> productExtendList = productService.findProductListByName(null);
22 //返回ModelandView
23 ModelAndView modelAndView = new ModelAndView();
24 modelAndView.addObject(productExtendList);
25 modelAndView.setViewName("/WEB-INF/items/itemsList.jsp");
26 return modelAndView;
27 }
28
29 @RequestMapping("/queryInfo.do")
30 public ModelAndView queryInfo() throws Exception {
31
32 ProductExtend productExtend = productService.queryProductInfo(1);
33 productExtend.setDesc("这是相机");
34 ModelAndView modelAndView = new ModelAndView();
35 modelAndView.addObject(productExtend);
36 modelAndView.setViewName("/WEB-INF/items/editItem.jsp");
37 return modelAndView;
38 }
39 }复制代码
⑤最后在查询列表中点击查询即可查看详细信息
2、窄化请求映射
a)为了实现不同模块之间的开发,我们可以进行这样的使用:在class上添加@RequestMapping(url)指定通用请求前缀, 限制此类下的所有方法请求url必须以请求前缀开头,通过此方法对url进行分类管理。
b)如下:@RequestMapping放在类名上边,设置请求前缀
@Controller
@RequestMapping("/test")
然后在方法名上边设置请求映射url:
@RequestMapping("/queryItem ")
访问地址为:http://localhost:8080/TestSSM2/test/queryList.do
3、关于http请求方式限定
a)限定POST方法:@RequestMapping(method = RequestMethod.
)
如果通过Get访问则报错:HTTP Status 405 - Request method 'GET' not supported,例如
然后访问http://localhost:8080/TestSSM2/test/queryList.do,就会是下面的错误
b)限定GET方法:@RequestMapping(method = RequestMethod.
)
如果通过Post访问则报错:HTTP Status 405 - Request method 'POST' not supported
c)GET和POST都可以:@RequestMapping(method={RequestMethod.GET,RequestMethod.POST})
三、关于Controller的返回值问题
1、返回ModelAndView
a)我们上面编写Controller都是以这种方式进行的,大概就是定义一个ModelAndView对象,然后填充模型(从数据库中得到的数据)和逻辑视图(指定的jsp等路径),并返回即可
b)例如
2、使用void类型
a)在controller方法形参上可以定义request和response,使用request或response指定响应结果:
①使用request转向页面:request.getRequestDispatcher("页面路径").forward(request, response);
例如:
@RequestMapping("/test_void.do")public void testVoid(HttpServletRequest request, HttpServletResponse response) throws Exception{request.setAttribute("test","返回值为void类型的测试");request.getRequestDispatcher("/WEB-INF/items/hello.jsp").forward(request,response);}复制代码
然后输出结果
②通过response页面重定向:response.sendRedirect("url"),实现方式同上
3、使用String作为返回值
a)Controller中的方法形参为model,然后通过形参将数据返回到请求页面上,最后返回字符串可以指定逻辑视图名(路径信息),通过视图解析器解析为物理视图地址;
1 @RequestMapping("/testString.do")
2 public String testString(Model model) throws Exception {
3 //其他进行的操作
4 //通过形参model将数据返回到请求页面上 类似于返回ModelAndView中的addObject方法
5 model.addAttribute("testString","testString");
6 //然后返回逻辑视图名,经过视图解析器解析为相应的jsp等路径
7 return "test/helloWorld";
8 }复制代码
b)重定向:Contrller方法返回结果重定向到一个url地址,但是由于重定向之后原来的request中的数据不在,所以如果要传参数可以/item/queryItem.action后边加参数:/test/queryTest?test1Key=test1Value&test2Key=test2Value
c)转发:Controller中的方法执行后继续执行另一个controller方法,如下信息modify提交后转向到信息显示页面,修改信息的id参数可以带到修改方法中。//结果转发到update.action,request可以带过去:return"forward:update.action";forward方式相当于“request.getRequestDispatcher().forward(request,response)”,转发后浏览器地址栏还是原来的地址。转发并没有执行新的request和response,而是和转发前的请求共用一个request和response。所以转发前请求的参数在转发后仍然可以读取到。
四、关于SpringMVC的参数绑定问题
1、参数绑定过程
a)参数绑定:注解适配器对RequestMapping标记的方法进行适配,将从浏览器中请求的数据(key/value或者表单信息)在方法中的形参会进行参数绑定,所以在springmvc中的参数绑定是通过Controller的方法形参进行绑定的。
b)参数绑定所支持的默认参数类型,可以直接在Controller方法上面定义下面类型的形参,然后在方法体内直接使用
①HttpServletRequest(通过request对象获取请求信息)
②HttpServletResponse(通过response处理响应信息)
③HTTPSession(通过session对象得到session中存放的对象)
④Model(通过model向页面传递数据,然后页面通过${test.XXXX}获取item对象的属性值。如同上面Controller中方法返回值为String的情况)
2、RequestParam注解使用
a)在没有使用注解的时候,我们在前端提交参数的key名字应该Controller中方法的形参相同,否则在request域中无法进行匹配。当我们需要将Controller方法中的形参设置为不一样的参数名时候,就需要使用这个注解
b)注解简介:@RequestParam用于绑定单个请求参数。
①value:参数名字,即入参的请求参数名字,如value=“test_id”表示请求的参数区中的名字为test_id的参数的值将传入;
②required:是否必须传入参数,默认是true,表示请求中一定要有相应的参数,否则将报HTTP Status 400 - Required Integer parameter 'XXXX' is not present
③defaultValue:默认值,表示如果请求中没有同名参数时的默认值
比如:形参名称为id,但是这里使用value=" test_id"限定请求的参数名为test_id,所以页面传递参数的名必须为test_id。
注意:如果请求参数中没有test_id将抛出异常:HTTP Status 500 - Required Integer parameter 'test_id' is not present
这里通过required=true限定itest_id参数为必需传递,如果不传递则报400错误,可以使用defaultvalue设置默认值,即使required=true也可以不传item_id参数值
c)下面使用例子来进行说明上面的几点内容
①测试注解
测试工程如同上一篇SSM整合中搭建的工程,其中只有一个功能就是查询列表。然后我们在本篇最开始的时候介绍RequestMapping时候添加了查询详细信息的功能,但是其中我们没有接收前端传入的数据,全部都是用的默认值1,下面来将这个方法使用RequestParam进行改写,接收前端传入的参数进行查询。
1 @RequestMapping("/queryInfo.do")2 public ModelAndView queryInfo(@RequestParam(value = "id") Integer testId) throws Exception {3 //在没有使用注解的时候,方法形参中的参数名需要和前端请求的key名称一样,使用之后就可以自定义4 ProductExtend productExtend = productService.queryProductInfo(testId);5 6 productExtend.setDesc("这是相机");7 ModelAndView modelAndView = new ModelAndView();8 modelAndView.addObject(productExtend);9 modelAndView.setViewName("/WEB-INF/items/editItem.jsp");
10 return modelAndView;
11 }复制代码
然后我们再次进行测试,首先访问http://localhost:8080/TestSSM2/test/queryList.do,然后查看id=2的信息
得到下面的结果
在对比id=1的时候
②测试required
在上面的方法中加上
然后进行测试,输入http://localhost:8080/TestSSM2/test/queryInfo.do,不加参数,则报出下面的错误
③测试defaultValue
当required设置为true的时候,如果没有传入key/value,当在Controller中设置defaultValue的时候也不会报出上面的异常,在Controller方法参数中改成下面这样
然后直接输入http://localhost:8080/TestSSM2/test/queryInfo.do不加id参数,还是能够查询到默认的id=1的数据
3、普通POJO类型绑定
a)将pojo对象中的属性名和传递进来的属性名对应,如果传进来的参数名称和对象中的属性名称一致则将参数值设置在pojo对象中 ,然后在Contrller方法定义: 请求的参数名称和pojo的属性名称一致,会自动将请求参数赋值给pojo的属性。
b)我们现在在Controller中新添加一个下面的方法,输出从页面上面提交的数据
c)在页面表单中点击提交数据
然后后台中输出
4、自定义参数绑定
a)定义一个Date类型的参数绑定,首先建议里个转换器的java工具类,用来将String转换为java.util.Date类型
1 package cn.test.ssm.controller.converter;2 3 4 import org.springframework.core.convert.converter.Converter;5 6 import java.text.ParseException;7 import java.text.SimpleDateFormat;8 import java.util.Date;9
10 public class StringToDateConverter implements Converter<String, Date> {
11 @Override
12 public Date convert(String s) {
13
14 try {
15 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
16 return simpleDateFormat.parse(s);
17 } catch (ParseException e) {
18 e.printStackTrace();
19 }
20 return null;
21 }
22 }复制代码
然后在springmvc.xml中配置上上面的转换器
1 <!--配置mvc:annotation代替基于注解方式的处理器映射器和适配器的配置-->2 <mvc:annotation-driven conversion-service="converterService"></mvc:annotation-driven>3 4 <bean id="converterService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">5 <!--配置转换器-->6 <property name="converters">7 <list>8 <bean class="cn.test.ssm.controller.converter.StringToDateConverter"></bean>9 </list>
10 </property>
11 </bean>复制代码
最后可以修改一下上面的查看信息方法,在后台中打印出所有提交的数据,注意下面的方法中形参createtime的类型已经设置为Date类型,在前端页面中也添加上了createtime的输入
1 @RequestMapping("/printInfo.action")
2 public String printInfo(Product product, Date createtime) throws Exception {
3 System.out.println("输出信息"+product);
4 System.out.println(createtime);
5 return "forward:queryList.do";
6 }复制代码
最后在浏览器中进行如下输入测试,输入一个日期类型
最后在后台查看打印的信息
5、自定义包装类型
a)当前天传入的参数比较复杂的时候(比如说涵盖不同数据实体类之间关联的查询或者某个实体类的扩展属性信息),这个时候我们可以在扩展类中加上额外的属性然后将其作为我们自定义的包装类的属性,然后将前台页面传入参数的name设置为包装类的属性名.实体类属性(testExtend.name)
b)看下面的例子,这是一个模糊查询的简单功能实现
①我们首先在实体类Product的扩展类ProductExtend中添加接受模糊查询参数的一个属性
②然后定义一个包装类型,其中将上面的扩展类型设置为一个属性
③然后就在Controller方法中将自定义的包装类型设置为方法形参,用以进行参数绑定,并且调用service的方法进行查询
④在前台中查看查询
⑤在debug模式中查看是否接收到前端传入的参数,发现可以接收到页面传入的参数
并且在调用service方法之后的查询结果也为
最终页面显示结果
转载于:https://juejin.im/post/5ce395b3e51d454d393c7158
SpringMVC之Controller和参数绑定相关推荐
- java元婴期(30)----java进阶(springmvc(4)---参数绑定(下)springmvc校验异常处理)
包装类型pojo参数绑定 需求 商品查询controller方法中实现商品查询条件传入. 实现方法 第一种方法:在形参中 添加HttpServletRequest request参数,通过reques ...
- java元婴期(29)----java进阶(springmvc(3)---springmvc和mybatis整合参数绑定(上))
springmvc和mybatis整合 需求 使用springmvc和mybatis完成商品列表查询. 整合思路 springmvc+mybaits的系统架构: 第一步:整合dao层 mybatis和 ...
- Springmvc的handler method参数绑定常用的注解
转自:http://blog.longjiazuo.com/archives/1149 1. 简介: handler method参数绑定常用的注解,我们根据他们处理的Request的不同内容部分分为 ...
- 【SSM - SpringMVC篇】03 - SpringMVC的参数绑定 - 参数自动绑定 - javabean对象参数绑 - 嵌套bean参数绑定
文章目录 SpringMVC的参数绑定 1 传统方式进行参数传递 2 通过SpringMVC的参数绑定实现[***用这个就行] 2.1 SpringMVC的基本数据类型的参数绑定 2.1.1 方法形式 ...
- SpringMVC源码之参数解析绑定原理
摘要 本文从源码层面简单讲解SpringMVC的参数绑定原理 SpringMVC参数绑定相关组件的初始化过程 在理解初始化之前,先来认识一个接口 HandlerMethodArgumentResolv ...
- springmvc的初始化参数绑定
一.springmvc的初始化参数绑定 此种和我们之前说的类型转换非常相似,可以看作是一种类型转换 在初始化参数绑定时 重要的是参数类型 -------------------单日期的绑定 二. 配 ...
- SpringMVC自动将请求参数和入参对象的属性进行一一绑定;要求请求参数的名字和javaBean入参的对象里面的属性名是一样的||员工的增删改查案例
SpringMVC自动将请求参数和入参对象的属性进行一一绑定:要求请求参数的名字和javaBean入参的对象里面的属性名是一样的 1.SpringMVC中配置HiddenHttpMethodFilte ...
- SpringMvc之参数绑定注解详解
在 SpringMVC 中,提交请求的数据是通过方法形参来接收的.从客户端请求的 key/value 数据,经过参数绑定,将 key/value 数据绑定到 Controller 的形参上,然后在 C ...
- springmvc(三) 参数绑定、
前面两章就介绍了什么是springmvc,springmvc的框架原理,并且会简单的使用springmvc以及ssm的整合,从这一章节来看,就开始讲解springmvc的各种功能实现,慢慢消化 --W ...
最新文章
- 深度学习调用TensorFlow、PyTorch等框架
- [转]Android UI 自动化测试
- 信息系统项目管理师-学习方法、重难点、10大知识领域笔记
- CentOS 初体验十:文件权限查看和修改
- ivew ui 中使用Menu组件时导航菜单 active-name 无法动态激活问题
- 第三十七课.宽度学习
- 西门子plc与ABB510变频器modbus通讯
- Zynga的数据分析
- 生活随记 - 清明时节特想老爸老妈
- 当 Python 遇到数据库,这个模块就变得超级好用
- 从0开始学习 GitHub 系列之「06.团队合作利器 Branch」----转载自stormzhang 原创文章
- C# 7.0 SPANS
- 安装Google三件套
- python package什么意思_Python模块、包(Package)概念与用法分析
- android studio制作.9图片,并且不改变原图大小
- 信号调制与二极管检波电路的multisim仿真
- python收音机_FM收音机入门,以及Python实现FM调制解调
- radmin不能发送Ctrl+Alt+Del的解决办法
- 六种水果健康食用方法
- 办公室的衣着打扮 FORMAL, BUSINESS CASUAL,AND CASUAL
热门文章
- Linux 搭建PHP环境
- maven生成jar包
- 利用Teensy进行EM410x卡模拟以及暴力破解EM410X类门禁系统可行性猜想
- VisualSVN 补丁,你懂的,需要的速度进~ (更新至6.0.1)
- python基础之元组定义进阶操作、字典定义进阶操作
- Druid:数据库连接池实现技术 1
- 06-01 搭建持续集成平台 Jenkins
- 安装centos7步骤_Centos7下源码编译安装mysql5.7 详细步骤 小白也能安装
- 测试 软通动力软件测试机试_5000字长文,计算机保研机试介绍及准备策略!高分过过过!...
- 文件操作(文件指针+顺序/随机读写)