springmvc教程系列

springmvc史上最好教程(2)

springmvc史上最好教程(1)

一、 注解开发-基础

1.1 需求

使用springmvc+mybatis架构实现商品信息维护。

1.2 商品修改

1.2.1 dao

使用逆向工程自动生成的代码:

ItemsMapper.java

ItemsMapper.xml

1.2.2 service

//根据id查询商品信息public Items findItemById(int id) throws Exception;//修改商品信息public void saveItem(Items items)throws Exception;

1.2.3 controller

修改商品信息显示页面:

@RequestMapping(value="/editItem")public String editItem(Model model, Integer id) throws Exception{//调用service查询商品信息Items item = itemService.findItemById(id);model.addAttribute("item", item);return "item/editItem";}

修改商品信息提交:

//商品修改提交@RequestMapping("/editItemSubmit")public String editItemSubmit(Items items)throws Exception{System.out.println(items);itemService.saveItem(items);return "success";}

1.2.4 页面

/WEB-INF/jsp/item/itemsList.jsp

/WEB-INF/jsp/item/editItem.jsp

1.3 @RequestMapping

通过RequestMapping注解可以定义不同的处理器映射规则。

1.3.1 URL路径映射

@RequestMapping(value="/item")或@RequestMapping("/item)

value的值是数组,可以将多个url映射到同一个方法

1.3.2 窄化请求映射

在class上添加@RequestMapping(url)指定通用请求前缀, 限制此类下的所有方法请求url必须以请求前缀开头,通过此方法对url进行分类管理。

如下:

@RequestMapping放在类名上边,设置请求前缀

@Controller

@RequestMapping("/item")

方法名上边设置请求映射url:

@RequestMapping放在方法名上边,如下:

@RequestMapping("/queryItem ")

访问地址为:/item/queryItem

1.3.3 请求方法限定

1、限定GET方法

@RequestMapping(method = RequestMethod.GET)

如果通过Post访问则报错:

HTTP Status 405 - Request method 'POST' not supported

例如:

@RequestMapping(value="/editItem",method=RequestMethod.GET)

2、 限定POST方法

@RequestMapping(method = RequestMethod.POST)

如果通过Post访问则报错:

HTTP Status 405 - Request method 'GET' not supported

3、GET和POST都可以

@RequestMapping(method={RequestMethod.GET,RequestMethod.POST})

1.4 controller方法返回值

1.4.1 返回ModelAndView

controller方法中定义ModelAndView对象并返回,对象中可添加model数据、指定view。

1.4.2 返回void

在controller方法形参上可以定义request和response,使用request或response指定响应结果:

使用request转向页面,如下:

request.getRequestDispatcher("页面路径").forward(request, response);

通过response页面重定向:

response.sendRedirect("url")

通过response指定响应结果,例如响应json数据如下:

response.setCharacterEncoding("utf-8");

response.setContentType("application/json;charset=utf-8");

response.getWriter().write("json串");

1.4.3 返回字符串

1.4.3.1 逻辑视图名

controller方法返回字符串可以指定逻辑视图名,通过视图解析器解析为物理视图地址。

//指定逻辑视图名,经过视图解析器解析为jsp物理路径:/WEB-INF/jsp/item/editItem.jspreturn "item/editItem";

1.4.3.2 Redirect重定向

Contrller方法返回结果重定向到一个url地址,如下商品修改提交后重定向到商品查询方法,参数无法带到商品查询方法中。

//重定向到queryItem.action地址,request无法带过去
return "redirect:queryItem.action";

redirect方式相当于“response.sendRedirect()”,转发后浏览器的地址栏变为转发后的地址,因为转发即执行了一个新的request和response。

由于新发起一个request原来的参数在转发时就不能传递到下一个url,如果要传参数可以/item/queryItem.action后边加参数,如下:

/item/queryItem?...&…..

1.4.3.3 forward转发

controller方法执行后继续执行另一个controller方法,如下商品修改提交后转向到商品修改页面,修改商品的id参数可以带到商品修改方法中。

//结果转发到editItem.action,request可以带过去return "forward:editItem.action";

forward方式相当于“request.getRequestDispatcher().forward(request,response)”,转发后浏览器地址栏还是原来的地址。转发并没有执行新的request和response,而是和转发前的请求共用一个request和response。所以转发前请求的参数在转发后仍然可以读取到。

1.5 参数绑定

1.5.1 默认支持的参数类型

处理器形参中添加如下类型的参数处理适配器会默认识别并进行赋值。

1.5.1.1 HttpServletRequest

通过request对象获取请求信息

1.5.1.2 HttpServletResponse

通过response处理响应信息

1.5.1.3 HttpSession

通过session对象得到session中存放的对象

1.5.1.4 Model

通过model向页面传递数据,如下:

//调用service查询商品信息
Items item = itemService.findItemById(id);
model.addAttribute("item", item);

页面通过${item.XXXX}获取item对象的属性值。

1.5.2 参数绑定介绍

注解适配器对RequestMapping标记的方法进行适配,对方法中的形参会进行参数绑定,早期springmvc采用PropertyEditor(属性编辑器)进行参数绑定将request请求的参数绑定到方法形参上,3.X之后springmvc就开始使用Converter进行参数绑定。

1.5.3 @RequestParam

@RequestParam用于绑定单个请求参数。

value:参数名字,即入参的请求参数名字,如value=“item_id”表示请求的参数区中的名字为item_id的参数的值将传入;

required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报;

TTP Status 400 - Required Integer parameter 'XXXX' is not present

defaultValue:默认值,表示如果请求中没有同名参数时的默认值

定义如下:

public String editItem(@RequestParam(value="item_id",required=true) String id) {}

形参名称为id,但是这里使用value=" item_id"限定请求的参数名为item_id,所以页面传递参数的名必须为item_id。

注意:如果请求参数中没有item_id将跑出异常:

HTTP Status 500 - Required Integer parameter 'item_id' is not present

这里通过required=true限定item_id参数为必需传递,如果不传递则报400错误,可以使用defaultvalue设置默认值,即使required=true也可以不传item_id参数值

1.5.4 简单类型

当请求的参数名称和处理器形参名称一致时会将请求参数与形参进行绑定。

1.5.4.1 整型

public String editItem(Model model,Integer id) throws Exception{

1.5.4.2 字符串

例子略

1.5.4.3 单精度/双精度

例子略

1.5.4.4 布尔型

处理器方法:

public String editItem(Model model,Integer id,Boolean status) throws Exception

请求url:

http://localhost:8080/springmvc_mybatis/item/editItem.action?id=2&status=false

说明:对于布尔类型的参数,请求的参数值为true或false。

1.5.5 自定义参数绑定

1.5.5.1 需求

根据业务需求自定义日期格式进行参数绑定。

1.5.5.2 propertyEditor

1.5.5.2.1 使用WebDataBinder 

在controller方法中通过@InitBinder标识方法为参数绑定方法,通过WebDataBinder注册属性编辑器,问题是此方法只能在单个controller类中注册。

/*** 注册属性编辑器(字符串转换为日期)*/@InitBinderpublic void initBinder(WebDataBinder binder) throws Exception {binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true));}

1.5.5.2.2 使用WebDataBinder 

在controller方法中通过@InitBinder标识方法为参数绑定方法,通过WebDataBinder注册属性编辑器,问题是此方法只能在单个controller类中注册。

如下:

编写CustomPropertyEditor:

public class CustomPropertyEditor implements PropertyEditorRegistrar {@Overridepublic void registerCustomEditors(PropertyEditorRegistry registry) {registry.registerCustomEditor(Date.class, new CustomDateEditor(newSimpleDateFormat("yyyy-MM-dd HH-mm-ss"),true));}}

配置如下:

<!-- 注册属性编辑器 --><bean id="customPropertyEditor" class="com.sihai.ssm.propertyeditor.CustomPropertyEditor"></bean> <!-- 自定义webBinder --><bean id="customBinder"class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer"><property name="propertyEditorRegistrars"><list><ref bean="customPropertyEditor"/></list></property></bean><!--注解适配器 --><beanclass="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"><property name="webBindingInitializer" ref="customBinder"></property> </bean>

1.5.5.3 Converter

1.5.5.3.1 自定义Converter

public class CustomDateConverter implements Converter<String, Date> {@Overridepublic Date convert(String source) {try {SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");return simpleDateFormat.parse(source);} catch (Exception e) {e.printStackTrace();}return null;}}

1.5.5.3.2 配置方式1

<!--注解适配器 --><beanclass="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"><property name="webBindingInitializer" ref="customBinder"></property> </bean><!-- 自定义webBinder --><bean id="customBinder"class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer"><property name="conversionService" ref="conversionService" /></bean><!-- conversionService --><bean id="conversionService"class="org.springframework.format.support.FormattingConversionServiceFactoryBean"><!-- 转换器 --><property name="converters"><list><bean class="cn.itcast.ssm.controller.converter.CustomDateConverter"/></list></property></bean>

1.5.5.3.3 配置方式2

<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven><!-- conversionService --><bean id="conversionService"class="org.springframework.format.support.FormattingConversionServiceFactoryBean"><!-- 转换器 --><property name="converters"><list><bean class="cn.itcast.ssm.controller.converter.CustomDateConverter"/></list></property></bean>

1.5.6 pojo

1.5.6.1 简单pojo

将pojo对象中的属性名于传递进来的属性名对应,如果传进来的参数名称和对象中的属性名称一致则将参数值设置在pojo对象中

页面定义如下;

<input type="text" name="name"/>

<input type="text" name="price"/>

Contrller方法定义如下:

@RequestMapping("/editItemSubmit")public String editItemSubmit(Items items)throws Exception{System.out.println(items);

请求的参数名称和pojo的属性名称一致,会自动将请求参数赋值给pojo的属性。

1.5.6.2 包装pojo

如果采用类似struts中对象.属性的方式命名,需要将pojo对象作为一个包装对象的属性,action中以该包装对象作为形参。

包装对象定义如下:

Public class QueryVo {private Items items;}

页面定义:

<input type="text" name="items.name" />

<input type="text" name="items.price" />

Controller方法定义如下:

public String useraddsubmit(Model model,QueryVo queryVo)throws Exception{System.out.println(queryVo.getItems());

1.5.6.3 ModelAttribute

@ModelAttribute作用如下:

1、绑定请求参数到pojo并且暴露为模型数据传到视图页面

此方法可实现数据回显效果。

 // 商品修改提交@RequestMapping("/editItemSubmit")public String editItemSubmit(@ModelAttribute("item") Items items,Model model)

页面:

<tr><td>商品名称</td><td><input type="text" name="name" value="${item.name }"/></td></tr><tr><td>商品价格</td><td><input type="text" name="price" value="${item.price }"/></td></tr>

如果不用@ModelAttribute可以使用model.addAttribute("item", items)完成数据回显。

2、将方法返回值暴露为模型数据传到视图页面

//商品分类@ModelAttribute("itemtypes")public Map<String, String> getItemTypes(){Map<String, String> itemTypes = new HashMap<String,String>();itemTypes.put("101", "数码");itemTypes.put("102", "母婴");return itemTypes;}

页面:

商品类型:

<select name="itemtype"><c:forEach items="${itemtypes }" var="itemtype"><option value="${itemtype.key }">${itemtype.value }</option></c:forEach></select>

1.5.7 集合类

1.5.7.1 字符串数组

页面定义如下:

页面选中多个checkbox向controller方法传递

<input type="checkbox" name="item_id" value="001"/><input type="checkbox" name="item_id" value="002"/><input type="checkbox" name="item_id" value="002"/>

传递到controller方法中的格式是:001,002,003

Controller方法中可以用String[]接收,定义如下:

public String deleteitem(String[] item_id)throws Exception{System.out.println(item_id);}

1.5.7.2 List

List中存放对象,并将定义的List放在包装类中,action使用包装对象接收。

List中对象:

成绩对象

Public class QueryVo {Private List<Items> itemList;//订单明细//get/set方法..}

包装类中定义List对象,并添加get/set方法如下:

页面:

 <tr><td><input type="text" name=" itemList[0].id" value="${item.id}"/></td><td><input type="text" name=" itemList[0].name" value="${item.name }"/></td><td><input type="text" name=" itemList[0].price" value="${item.price}"/></td></tr><tr><td><input type="text" name=" itemList[1].id" value="${item.id}"/></td><td><input type="text" name=" itemList[1].name" value="${item.name }"/></td><td><input type="text" name=" itemList[1].price" value="${item.price}"/></td></tr>

Contrller方法定义如下:

public String useraddsubmit(Model model,QueryVo queryVo)throws Exception{System.out.println(queryVo.getItemList());}

1.5.7.3 Map

在包装类中定义Map对象,并添加get/set方法,action使用包装对象接收。

包装类中定义Map对象如下:

Public class QueryVo {private Map<String, Object> itemInfo = new HashMap<String, Object>();//get/set方法..}

页面定义如下:

<tr><td>学生信息:</td><td>姓名:<inputtype="text"name="itemInfo['name']"/>年龄:<inputtype="text"name="itemInfo['price']"/>.. .. ..</td></tr>

Contrller方法定义如下:

public String useraddsubmit(Model model,QueryVo queryVo)throws Exception{System.out.println(queryVo.getStudentinfo());}

1.6 问题总结

1.6.1 404

页面找不到,视图找不到。

HandlerMapping根据url没有找到Handler。

1.6.2 Post时中文乱码

在web.xml中加入:

<filter><filter-name>CharacterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>utf-8</param-value></init-param></filter><filter-mapping><filter-name>CharacterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>

以上可以解决post请求乱码问题。

对于get请求中文参数出现乱码解决方法有两个:

修改tomcat配置文件添加编码与工程编码一致,如下:

<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

另外一种方法对参数进行重新编码:

String userName newString(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")

ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码

1.7 与struts2不同

1、 springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过虑器。

2、 springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。

3、 Struts采用值栈存储请求和响应的数据,通过OGNL存取数据,springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过reques域传输到页面。Jsp视图解析器默认使用jstl。

springmvc教程--注解开发基础详解相关推荐

  1. SpringMVC 基于注解的Controller详解

    本文出处 http://blog.csdn.net/lufeng20/article/details/7598801 概述 继 Spring 2.0 对 Spring MVC 进行重大升级后,Spri ...

  2. java图形界面详解_JAVA 图形界面开发基础详解

    与C的win32一样,JAVA也有自己的图形界面开发,将在此篇博客中对基础部分进行讲解. 1.Java提供的图形界面类有哪些? Java提供了两套图形界面 (1)AWT组建(基础) AWT组件是jdk ...

  3. labview 串口通信开发基础详解

    串口通信的基本概念 串口通信的基本概念 1,什么是串口? 2,什么是RS-232? 3,什么是RS-422? 4,什么是RS-485? 5,什么是握手? 1,什么是串口? 串口是计算机上一种非常通用设 ...

  4. java注解式开发_JAVA语言之Spring MVC注解式开发使用详解[Java代码]

    本文主要向大家介绍了JAVA语言的Spring MVC注解式开发使用详解,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助. MVC注解式开发即处理器基于注解的类开发, 对于每一个定义的处 ...

  5. 《Java和Android开发实战详解》——1.2节Java基础知识

    本节书摘来自异步社区<Java和Android开发实战详解>一书中的第1章,第1.2节Java基础知识,作者 陈会安,更多章节内容可以访问云栖社区"异步社区"公众号查看 ...

  6. get方法报空指针_C++基础教程之指针拷贝详解

    C++基础教程之指针拷贝详解 指针是编程人员的梦魇,对C语言的开发者是如此,对C++的开发者也是如此.特别是在C++中,如果不注意处理类中的指针,非常容易出问题.如果朋友们不相信可以看看下面的代码: ...

  7. 《Unity 3D 游戏开发技术详解与典型案例》——1.1节Unity 3D基础知识概览

    本节书摘来自异步社区<Unity 3D 游戏开发技术详解与典型案例>一书中的第1章,第1.1节Unity 3D基础知识概览,作者 吴亚峰 , 于复兴,更多章节内容可以访问云栖社区" ...

  8. 《Android Studio应用开发实战详解》——第1章,第1.2节Android系统基础

    本节书摘来自异步社区<Android Studio应用开发实战详解>一书中的第1章,第1.2节Android系统基础,作者 王翠萍,更多章节内容可以访问云栖社区"异步社区&quo ...

  9. Python视频剪辑基础教程:MoviePy VideoClip详解

    Python视频剪辑基础教程:MoviePy VideoClip详解 随着数字化媒体的快速发展,视频成为了现代社会最为流行的媒介之一.在如此多样化的数字化媒体中,视频编辑技术被誉为其中最为关键的技能之 ...

最新文章

  1. java 环境配置 mac_Java:配置环境(Mac)——JDK
  2. 跨链(2)跨链技术“侧链(Sidechains)”
  3. 2020年度“CCF-百度松果基金”评审结果公示
  4. Android 应用开发(32)--工程相关解析(各种文件,资源访问)
  5. 《SOA In the real world》第一章译稿(含下载)
  6. socket编程-阻塞和非阻塞
  7. socket接口多线程数据传输
  8. 操作系统课程设计报告
  9. 发动机冒黑烟_发动机总冒黑烟 用这招解决最快!
  10. php 人民币格式化,用PHP解析时格式化货币
  11. 二级c语言不写编程,计算机二级C语言 到底是不是考原题
  12. STM32F103C8T6系统板
  13. 十进制转换的三种方法,共同进步~
  14. 《深度学习之美》第3章
  15. 自学web前端怎么学?web前端学习路线css属性
  16. 主题和母版页(母版页)
  17. 未连接到互联网错误的解决方案
  18. android,手机 遥控,
  19. 0对任何数取余_大数取余
  20. java数字时钟_Java实现动态数字时钟

热门文章

  1. BLE-NRF51822教程13-连接时触发配对
  2. C++ Primer 5th笔记(chap 17 标准库特殊设施)bernoulli_distribution 类
  3. 智能合约重构社会契约(9)Fabric
  4. 区块链BaaS云服务概念简述
  5. [FF-A]-01-Introduction
  6. [ARM异常]-图解armv7/armv8的异常向量表和基地址
  7. 详解虚函数的实现过程之初探虚表(1)
  8. CreateDirectory GetCurrentDirectory 和SetCurrentDirectory
  9. Intel VT学习笔记(五)—— 调试技巧
  10. Windows驱动开发学习笔记(七)—— 多核同步内核重载