1.1 商品修改
1.1.1 需求
功能描述:商品信息修改
操作流程:
1、 在商品列表页面点击修改连接
2、打开商品修改页面,显示了当前商品的信息
根据商品id查询商品信息
3、修改商品信息,点击提交。
更新商品信息
1.1.2 mapper
使用mybatis逆向工程生成代码:
ItemsMapper.java
ItemsMapper.xml
itemsMapper.java里面有两个方法:
1: 根据商品id查询商品信息
2:更新商品信息
1.1.3 service
public interface ItemsService {
//商品查询列表
public List<ItemsCustom> findItemsList(ItemsQueryVo itemsQueryVo)
throws Exception;
//根据商品id查询商品信息
public ItemsCustom findItemsById(int id) throwsException;
//更新商品信息
public void updateItems(Integer id,ItemsCustom itemsCustom) throws Exception;
}
1.2 @requestMapping讲解
1.2.1 设置方法对应的url(完成url映射)
在controller类中的一个方法对应一个请求的url
@RequestMapping("/queryItems")
public ModelAndView queryItems(HttpServletRequest request) throws Exception {
}
1.2.2 窄化请求映射
在controller类上定义根路径,这样有助于系统的模块化开发
@Controller
//定义url的根路径,访问时根路径+方法的url
@RequestMapping("/items")
public class ItemsController {
}
1.2.3 限制http请求的方法
通过requestMapping限制url请求的http方法,
如果限制请求必须是post,如果get请求就抛出异常:
商品修改方法,限制为http的get:
@RequestMapping(value="/editItems",method={RequestMethod.GET})
public String editItems(Model model,Integerid)throws Exception{
}
1.3 controller方法返回值
1.3.1 返回ModelAndView
@RequestMapping("/queryItems")
public ModelAndView queryItems(HttpServletRequestrequest) throws Exception {
System.out.println(request.getParameter("id"));
//调用service查询商品列表
List<ItemsCustom> itemsList = itemsService.findItemsList(null);
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("itemsList", itemsList);
// 指定逻辑视图名
modelAndView.setViewName("itemsList");
return modelAndView;
}
1.3.1 返回字符串
如果controller方法返回jsp页面,可以简单将方法返回值类型定义为字符串,最终返回逻辑视图名。
//方法返回 字符串,字符串就是逻辑视图名,Model作用是将数据填充到request域,在页面展示
@RequestMapping(value="/editItems",method={RequestMethod.GET})
public String editItems(Model model,Integer id)throws Exception{
//调用 service查询商品信息
ItemsCustom itemsCustom = itemsService.findItemsById(id);
model.addAttribute("item", itemsCustom);
return"editItem";
}
1.3.2 返回void
//方法返回void
@RequestMapping(value="/editItems",method={RequestMethod.GET})
public void editItems(
HttpServletRequest request,
HttpServletResponse response,
Integer id
)
throwsException {
//调用 service查询商品信息
ItemsCustom itemsCustom = itemsService.findItemsById(id);
request.setAttribute("item", itemsCustom);
//注意如果使用request转向页面,这里指定页面的完整路径
request.getRequestDispatcher("/WEB-INF/jsp/editItem.jsp").forward(request, response);
}
使用此方法,容易输出json、xml格式的数据:
通过response指定响应结果,例如响应json数据如下:
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write("json串");
1.3.3 redirect重定向和forward转发
如果方法重定向到另一个url,方法返回值为“redirect:url路径”,如果方法转发则方法返回值为“forward:url路径”
//商品修改提交
//itemsQueryVo是包装类型的pojo
@RequestMapping("/editItemSubmit")
public String editItemSubmit(Integer id,ItemsCustomitemsCustom)throws Exception{
//调用service接口更新商品信息
itemsService.updateItems(id, itemsCustom);
//请求重定向
return "redirect:queryItems.action";
//转发
// return"forward:queryItems.action";
}
使用redirect进行重定向,request数据无法共享,url地址栏会发生变化的, 使用forward进行请求转发,request数据可以共享,url地址栏不会。
1.4 参数绑定
1.4.1 默认支持的参数类型
处理器形参中添加如下类型的参数处理适配器会默认识别并进行赋值。
1.4.1.1 HttpServletRequest
通过request对象获取请求信息
1.4.1.2 HttpServletResponse
通过response处理响应信息
1.4.1.3 HttpSession
通过session对象得到session中存放的对象
1.4.2 Model
通过model向页面传递数据,如下:
//调用service查询商品信息
Items item =itemService.findItemById(id);
model.addAttribute("item",item);
页面通过${item.XXXX}获取item对象的属性值。
1.4.3 @RequestParam注解
如果request请求的参数名和controller方法的形参数名称一致,适配器自动进行参数绑定。如果不一致可以通过
@RequestParam 指定request请求的参数名绑定到哪个方法形参上。
//方法返回void
@RequestMapping(value="/editItems",method={RequestMethod.GET})
public void editItems(
HttpServletRequest request,
HttpServletResponse response,
@RequestParam(value = "id", required = false, defaultValue = "1")
Integer item_id//这里前端传过来的是参数名是id这里controller方法接收则用item_id如果这里没加@RequestParam这个注解则接收不到这个参数
)
throwsException {
}
对于必须要传的参数,通过@RequestParam中属性required设置为true,如果不传此参数则报错。
对于有些参数如果不传入,还需要设置默认值,使用@RequestParam中属性defaultvalue设置默认值。
1.4.4 可以绑定简单类型
可以绑定整型、字符串、单精/双精度、日期、布尔型。
1.4.5 可以绑定简单pojo类型
简单pojo类型只包括简单类型的属性。
绑定过程:
request请求的参数名称和pojo的属性名一致,就可以绑定成功。
简单pojo类型存在的问题:
如果controller方法形参中有多个pojo且pojo中有重复的属性,使用简单pojo绑定无法有针对性的绑定,
比如:方法形参有items和User,pojo同时存在name属性,从http请求过程的name无法有针对性的绑定到items或user。
1.4.6 可以绑定包装的pojo
包装的pojo里边包括了其他的pojo。
页面参数定义:
修改商品信息:
<table width="100%"border=1>
<tr>
<td>商品名称</td>
<td><input type="text"name="itemsCustom.name"value="${item.name}"/></td>
</tr>
<tr>
<td>商品价格</td>
<td><input type="text"name="itemsCustom.price"value="${item.price}"/></td>
</tr>
</table>
包装类型的属性也是itemsCustom:
public class ItemsQueryVo {
//商品信息
private ItemsCustom itemsCustom;
public ItemsCustom getItemsCustom() {
return itemsCustom;
}
public voidsetItemsCustom(ItemsCustom itemsCustom) {
this.itemsCustom= itemsCustom;
}
}
按照上边的规则进行包装类型的绑定。
1.4.7 参数绑定集合类型
集合类型的参数绑定和包装类POJO类似,需要在包装类POJO中定义
List的简单POJO如:
public class ItemsQueryVo {
//商品信息
privateItemsCustom itemsCustom;
//商品信息列表
privateList<ItemsCustom> itemsList;
}
JSP页面如下:
<c:forEach items="${itemsList }" var="item" varStatus="s">
<tr>
<td><input type="text"name="itemsList[${s.index}].name"value="${item.name }"/></td>
<td><input type="text"name="itemsList[${s.index}].price"value="${item.price }"/></td>
</tr>
</c:forEach>
controller里面的方法通过包装类POJO ItemsQueryVo就能和JSP传过来的参数进行绑定:
@RequestMapping(value="/editItems")
public StringeditItems(ItemsQueryVo itemsQueryVo)throwsException{
//调用 service批量修改商品信息的方法
return"success";
}
注意:
request请求的参数名和controller方法的形参数名称一致,适配器自动进行参数绑定,不然需要通过@RequestParam注解进行说明即:JSP页面中的itemsList要和包装类中的ItemsQueryVo属性 List<ItemCustom> itemsList名称一致
1.4.8 使用WebBindingInitializer进行自定义参数绑定
使用WebBindingInitializer让多个controller共用 属性编辑器(不适用)或者是属性转换器。
然后将自定义WebBindingInitializer,注入到处理器适配器中。
1.4.8.1 实现Converter接口:
定义日期类型转换器
package cn.itcast.ssm.controller.converter;
import java.text.SimpleDateFormat;
import java.util.Date;
importorg.springframework.core.convert.converter.Converter;
/**
* 自定义日期转换器
*
*@author xia
*
*/
public class CustomDateConverter implementsConverter<String, Date> {
publicDate convert(String source) {
try{
//进行日期转换
returnnew SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(source);
}catch (Exception e) {
e.printStackTrace();
}
returnnull;
}
}
自定义字符串去除前后空格转换器
packagecn.itcast.ssm.controller.converter;
importorg.springframework.core.convert.converter.Converter;
/**
* 自定义空格转换器
* @authorxia
*
*/
public classStringTrimConverter implements Converter<String, String> {
publicString convert(String source) {
try{
//去掉字符串两边空格,如果去除后为空设置为null
if(source!=null){
source= source.trim();
if(source.equals("")){
returnnull;
}
}
}catch (Exception e) {
e.printStackTrace();
}
returnsource;
}
}
1.4.8.2 配置转换器(springmvc.xml)
方式一:( 不使用<mvc:annotation-drivenconversion-service="conversionService">
</mvc:annotation-driven>的方式配置):
<!-- 使用spring组件扫描 -->
<context:component-scanbase-package="cn.itcast.ssm.controller"/>
<!-- 通过annotation-driven可以替代下边的处理器映射器和适配器-->
<!-- <mvc:annotation-drivenconversion-service="conversionService">
</mvc:annotation-driven> -->
<!-- 注解处理器映射器 -->
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
</bean>
<!-- 注解适配器 -->
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<!--在webBindingInitializer中注入自定义转换器 -->
<property name="webBindingInitializer"ref="customBinder"></property>
</bean>
<!-- 配置视图解析器要求将jstl的包加到classpath -->
<!--ViewResolver -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix"value="/WEB-INF/jsp/"/>
<property name="suffix"value=".jsp"/>
</bean>
<!-- 自定义webBindingInitializer-->
<bean id="customBinder"
class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
<!--使用converter进行参数转 -->
<property name="conversionService"ref="conversionService"/>
</bean>
<!-- 转换器 -->
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="cn.itcast.ssm.controller.converter.CustomDateConverter"/>
<bean class="cn.itcast.ssm.controller.converter.StringTrimConverter"/>
</list>
</property>
</bean>
</beans>
方式二(使用<mvc:annotation-drivenconversion-service="conversionService">
</mvc:annotation-driven>的方式配置):
<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>