在完成框架的整合之后,开发商品的修改功能。
第一步:开发mapper
由于mapper是用mybatis的逆向工程创建的,因此而在这里,没有过多的业务逻辑的开发,因此,使用逆向工程生成的mapper即可。
注意一点就是,数据库里的时间类型,jdbcType = “TIMESTAMP” 对应于java.util.Date,日期格式为“yyyy-MM-dd HH:mm:ss”
第二步:开发service
首先在service接口中定义updateItems方法,如下:
//根据id查询商品信息--修改页面需要展示的内容
public ItemsCustom findItemsById(int id) throws Exception;
/**
* 修改商品信息
* @param id 修改商品的id
* @param itemsCustom 修改的商品的信息
* @throws Exception
*/
public void updateItems(Integer id, ItemsCustom itemsCustom) throws Exception;
然后在service的实现类中实现其方法,如下:
@Autowired
private ItemsMapper itemsMapper;
@Override
public ItemsCustom findItemsById(int id) throws Exception {
Items items = itemsMapper.selectByPrimaryKey(id);
//中间对商品信息进行业务处理
//.......
//返回itemsCustom
ItemsCustom itemsCustom = new ItemsCustom();
//将items中的属性值拷贝到itemsCustom
BeanUtils.copyProperties(items, itemsCustom);
return itemsCustom;
}
@Override
public void updateItems(Integer id, ItemsCustom itemsCustom) throws Exception {
//添加业务校验,通常在service接口中对关键参数进行校验
//校验id是否为空,如果为空,抛出异常
//更新商品信息使用updateByPrimaryKeyWithBLOBs,根据id更新items表中的所有字段,包括大文本类型
//updateByPrimaryKeyWithBLOBs要求必须传入id
itemsCustom.setId(id);
itemsMapper.updateByPrimaryKeyWithBLOBs(itemsCustom);
}
第三步:开发controller
@Controller
//为了对url进行分类管理,可以在这里定义这个controller的根路径,最终访问的url为根路径+子路径
//比如:商品的列表:/items/queryItems.action
@RequestMapping("/items")
public class ItermsController {
@Autowired
private ItemsService itemsService;
// 商品查询
@RequestMapping("/queryItems")
public ModelAndView queryItems() throws Exception {
// 调用service查找数据库,查询商品列表,
List<ItemsCustom> itemList = itemsService.findItemsList(null);
// 返回ModelAndView
ModelAndView modelAndView = new ModelAndView();
// 相当于request的setAttribute,在jsp页面中通过itemList获取数据
modelAndView.addObject("itemList", itemList);
// 指定视图
// 下边的路径,如果在视图解析器中配置了jsp路径的前缀和后缀,则可以修改为
// modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
modelAndView.setViewName("/items/itemsList");
// 上面的路径配置,可以不再程序中指定jsp地址的前缀和后缀
return modelAndView;
}
//商品信息修改页面显示
//@RequestMapping("/editItems")
//限制http请求方法,限制为post和get
// @RequestMapping(value="/editItems",method={RequestMethod.POST,RequestMethod.GET})
// public ModelAndView editItems() throws Exception{
//
// //调用service查询商品信息
// ItemsCustom itemsCustom = itemsService.findItemsById(1);
//
// // 返回ModelAndView
// ModelAndView modelAndView = new ModelAndView();
// //将商品信息放到model
// modelAndView.addObject("itemsCustom",itemsCustom);
// modelAndView.setViewName("/items/editItems");
// return modelAndView;
// }
@RequestMapping(value="/editItems",method={RequestMethod.POST,RequestMethod.GET})
//@RequestParam里边指定request传入参数名称和形参进行绑定
//通过required属性指定参数是否必须传入
//通过defaultValue可以设置默认值,如果id参数没有传入,将默认值于形参进行绑定
public String editItems(Model model, @RequestParam(value="id",required=true,defaultValue="1")Integer items_id) throws Exception{
//调用service查询商品信息
ItemsCustom itemsCustom = itemsService.findItemsById(items_id);
//通过形参中的model将model数据传到页面
//相当于modelAndView.addObject方法
model.addAttribute("itemsCustom",itemsCustom);
return "items/editItems";
}
//商品信息修改提交
@RequestMapping("/editItemsSubmit")
public String editItemsSubmit(HttpServletRequest request,Integer id,String name,ItemsCustom itemsCustom) throws Exception{
//调用service更新商品信息,页面需要将商品新传到此方法
itemsService.updateItems(id, itemsCustom);
// 返回ModelAndView
// ModelAndView modelAndView = new ModelAndView();
//将商品信息放到model
// modelAndView.addObject("itemsCustom",itemsCustom);
// modelAndView.setViewName("success");
//重定向到商品的查询列表
return "redirect:queryItems.action";
//forward转发
// return "forward:queryItems.action";
// return "success";
}
注:
1、@RequestMapping的作用:定义controller方法对应的url,进行处理器映射使用
特性:
1、url映射
2、窄化请求映射,即可以在controller类上增加@RequestMapping注解,来限制访问这个controller的路径
3、可以限制http的请求访问方法。出于安全性考虑,对http的链接进行限制
2、Controller方法的返回值
·返回ModelAndView
需要在方法结束时,定义ModelAndView,将model和view分别进行设置
·返回String
·如果controller方法返回String,表示返回逻辑视图名;真正的视图(jsp路径)=视图解析器中的前缀+逻辑视图名+后缀
·redirect重定向
redirect重定向特点:浏览器地址中的url会发生变化,修改提交的request数据无法传到重定向的地址。因为重定向后就重新进行request(即request无法共享)
·forward页面转发,通过forward进行页面转发,浏览器的地址栏不变,request数据共享
·返回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串”);
3、参数绑定
·参数绑定默认支持绑定的类型
直接在controller方法形参上定义下边类型的对象,就可以使用这些对象。在参数绑定过程中,适配器如果遇到以下这些类型,就直接进行绑定。
- HttpServletRequest : 通过request对象获取请求信息
- HttpServletResponse :通过response处理响应信息
- HttpSession :通过session对象得到session中存放的对象
- Model/ModelMap : Model是一个接口,ModelMap是Model接口的实现类,通过Model或ModelMap向页面传递数据。
作用:将model数据填充到request域
例如:
//调用service查询商品信息
ItemsCustom itemsCustom = itemsService.findItemsById(1);
model.addAttribute("itemsCustom",itemsCustom);
页面通过${itemsCustom.XXX}获取itemCustom对象的属性值
使用Model和ModelMap的效果一样,如果直接使用Model,springmvc会实例化ModelMap。
- 简单类型
可以通过@RequestParam对简单类型的参数进行绑定
如果不使用@RequestParam,要求request传入的参数名称和controller方法的形参名称一致,方可绑定成功。
如果使用@RequestParam,则可以不用限制request传入的参数名称和controller方法的形参名称一致
·参数绑定pojo
页面中input的name和controller的pojo形参中的属性名称一致,就可以将页面中的数据绑定到pojo。
·自定义参数绑定实现日期类型的绑定
对于controller形参中pojo对象,如果有日期类型,需要自定义参数绑定
思路:将请求的日期的数据串,转成日期类型。要转换的日期类型要和pojo中日期属性的类型保持一致。
参数绑定需要向处理器适配器中注入自定义的参数绑定组件。
springmvc.xml
<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="com.sky.ssm.controller.converter.CustomDateConverter"/>
</list>
</property>
</bean>
mvc:annotation-driven提供了conversion-service接口,可以将自定义的参数绑定类型添加到里面;自定义的参数绑定类型,实质就是一个bean
com.sky.ssm.controller.converter.CustomDateConverter.java
package com.sky.ssm.controller.converter;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.core.convert.converter.Converter;
/**
* 自定义日期转换器
* @author sk
*
*/
public class CustomDateConverter implements Converter<String, Date>{
@Override
public Date convert(String source) {
// 实现将日期串转成日期类型(格式:yyyy-MM-dd HH:mm:ss)
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
//转换成功,直接返回
return simpleDateFormat.parse(source);
} catch (Exception e) {
// TODO: handle exception
}
//如果参数绑定失败,就返回null
return null;
}
}
定义的Converter<源类型,目标类型>接口实现类,比如:
Converter<String,Date>表示:将请求的日期数据串转成java中的日期类型。注意:要转换的目标类型一定和接收的pojo中的属性类型一致。将定义的Converter实现类注入到处理器适配器中。
第二种自定义参数绑定的方法:
自定义参数绑定方式二:
<!---注解适配器-->
<bean class=”org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter” >
<property name=”webBindingInitializer” rel=”customBinder”/>
</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="com.sky.ssm.controller.converter.CustomDateConverter"/>
</list>
</property>
</bean>
适配器提供了一个对外的webBindingInitializer属性,通过设置其值,可以实现自定义的参数绑定
项目目录: