什么是springmvc?
Spring web mvc和Struts2都属于表现层的框架,它是Spring框架的一部分
流程图
怎么构建基础springmvc工程
1 创建web工程
2 导入jar包
3 在web.xml中配置前端控制器(指定上下文路径 classpath:springmvc.xml)
拦截规则 1 /*拦截所有 2 / 拦截除jsp以外的所有 3 *.action/*.do
4 springmvc.xml配置扫描@Controller注解
5 Action Controller Handler处理器 程序员书写 类上@Controller注解
方法上@RequestMapping(value = 请求的路径) .action可省略 建议不要省 方便维护
@Controller
public xx class{
@RequestMapping(/item.action)
public ModelAndView xx(){
new ModelAndView
设置数据
返回视图(物理视图或逻辑视图)
}
}
架构分析 一个中心 三个基本点
前端控制器 处理器映射器 处理器适配器 视图解析器 由springmvc提供Handler处理器 jsp视图 由程序员书写
默认的三大组件 废弃了
推荐使用RequestMappingHandlerMapping
直接在springmvc.xml中配置注解 <mvc:anonation-driver/>
整合Mybatis
整合思想1 SqlMapConfig.xml 核心配置文件 (配置个别名就可以 ,其余交给spring完成)
2 applicationContext.xml 数据源 druid(阿里的) 读取 db.properties Mybatis工厂
Mybatis Mapper动态代理开发扫描方式 指定基本包
3 创建db.properties文件
4 事务 Spring+Mybatis
5 创建springmvc.xml 三大组件 扫描基本包
6 配置web.xml 配置监听器读取applicationContext.xml
配置前端控制器读取 springmvc.xml
配置POST提交乱码 Fittler过滤器
@RequestMapping注解
三个注意点1 当只指定一个路径,没有指定其它时 (value="xx")的value可以不写 . 如果指定多个url , 或限定了方法,必须加value
2 加在类上时, 限制此类下的所有方法请求 url 必须以请求前缀开头
3 请求方法的限定 @RequestMapping(method = RequestMethod.GET)
@RequestMapping(method = {RequestMethod.GET,RequestMethod.POST})
Controller方法返回值
1 ModelAndView 全能 带数据, 返回视图路径 不建议使用2 String 返回视图路径 方法形参(model.addAttribute("xx",xx))带数据 解耦 数据 视图分离 建议使用
3 void ajax请求合适 json格式数据(respongse) 参数(model,request,response) 异步请求使用
/**
* 返回void测试
*
* @param request
* @param response
* @throws Exception
*/
@RequestMapping("queryItem")
public void queryItem(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 1 使用request进行转发
// request.getRequestDispatcher("/WEB-INF/jsp/success.jsp").forward(request,
// response);
// 2 使用response进行重定向到编辑页面
// response.sendRedirect("/springmvc-web2/itemEdit.action");
// 3 使用response直接显示
response.getWriter().print("{\"abc\":123}");
String
//提交修改页面 入参 为 Items对象
@RequestMapping(value = "/updateitem.action")
// public ModelAndView updateitem(Items items){
public String updateitem(QueryVo vo,MultipartFile pictureFile) throws Exception{
//保存图片到
String name = UUID.randomUUID().toString().replaceAll("-", "");
//jpg
String ext = FilenameUtils.getExtension(pictureFile.getOriginalFilename());
pictureFile.transferTo(new File("D:\\upload\\" + name + "." + ext));
vo.getItems().setPic(name + "." + ext);
//修改
itemService.updateItemsById(vo.getItems());
// ModelAndView mav = new ModelAndView();
// mav.setViewName("success");
return "redirect:/itemEdit.action?id=" + vo.getItems().getId();
// return "forward:/item/itemlist.action";
}
参数绑定
默认支持的参数类型HttpServletRequest HttpServletResponse HttpSession
ModelAndView Model/ModelMap
绑定简单类型
当请求的参数名称和处理器形参名称一致时会将请求参数与形参进行绑定。
这样,从Request取参数的方法就可以进一步简化。
/**
* 根据id查询商品,绑定简单数据类型
*
* @param id
* @param model
* @return
*/
@RequestMapping("/itemEdit")
public String queryItemById(int id, ModelMap model) {
// 根据id查询商品数据
Item item = this.itemService.queryItemById(id);
// 把商品数据放在模型中
model.addAttribute("item", item);
return "itemEdit";
}
支持的数据类型
参数类型推荐使用包装数据类型,因为基础数据类型不可以为null
整形:Integer、int
字符串:String
单精度:Float、float
双精度:Double、double
布尔型:Boolean、boolean
说明:对于布尔类型的参数,请求的参数值为true或false。或者1或0
请求url:
http://localhost:8080/xxx.action?id=2&status=false
处理器方法:
public String editItem(Model model,Integer id,Boolean status)
@RequestParam常用于处理简单类型的绑定。
value:参数名字,即入参的请求参数名字,如value=“itemId”表示请求的参数 区中的名字为itemId的参数的值将传入
required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报错
TTP Status 400 - Required Integer parameter 'XXXX' is not present
defaultValue:默认值,表示如果请求中没有同名参数时的默认值
@RequestMapping("/itemEdit")
public String queryItemById(@RequestParam(value = "itemId", required = true, defaultValue = "1") Integer id,
ModelMap modelMap) {
// 根据id查询商品数据
Item item = this.itemService.queryItemById(id);
// 把商品数据放在模型中
modelMap.addAttribute("item", item);
return "itemEdit";
}
绑定pojo类型
要求:pojo对象中的属性名和表单中input的name属性一致。
/**
* 更新商品,绑定pojo类型
*
* @param item
* @param model
* @return
*/
@RequestMapping("/updateItem")
public String updateItem(Item item) {
// 调用服务更新商品
this.itemService.updateItemById(item);
// 返回逻辑视图
return "success";
}
绑定包装pojo
要求 表单中name属性名为 item.属性名 与pojo包装类(pojo为item)的pojo的属性名一致
// 绑定包装数据类型
@RequestMapping("/queryItem")
public String queryItem(QueryVo queryVo) {
System.out.println(queryVo.getItem().getId());
System.out.println(queryVo.getItem().getName());
return "success";
}
自定义参数绑定
如遇到日期格式或spring没办法把字符串转为其它类型时 使用
先在springmvc.xml中配置,
一般使用<mvc:annotation-driven/>注解驱动加载处理器适配器
<!-- 配置注解驱动 -->
<mvc:annotation-driven conversion-service="conversionService" />
<!-- 转换器配置 -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="cn.itcast.springmvc.converter.DateConverter" />
</set>
</property>
</bean>
自定义Converter
//Converter<S, T>
//S:source,需要转换的源的类型
//T:target,需要转换的目标类型
public class DateConverter implements Converter<String, Date> {
@Override
public Date convert(String source) {
try {
// 把字符串转换为日期类型
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy-MM-dd HH:mm:ss");
Date date = simpleDateFormat.parse(source);
return date;
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 如果转换异常则返回空
return null;
}
}
将表单的数据绑定到List
要求: name属性必须是list属性名+下标+元素属性。
<c:forEach items="${itemList }" var="item" varStatus="s">
<tr>
<td><input type="checkbox" name="ids" value="${item.id}"/></td>
<td>
<input type="hidden" name="itemList[${s.index}].id" value="${item.id }"/>
<input type="text" name="itemList[${s.index}].name" value="${item.name }"/>
</td>
</tr>
</c:forEach>
注意:接收List类型的数据必须是pojo的属性,如果方法的形参为ArrayList类型无法正确接收到数据。
json数据交互
//json数据交互
@RequestMapping(value = "/json.action") //这里的json.action与ajax中的url对应
public @ResponseBody
Items json(@RequestBody Items items){
System.out.println(items);
return items;
}
jsp页面
$(function(){
var params = '{"id": 1,"name": "测试商品","price": 99.9,"detail": "测试商品描述","pic": "123456.jpg"}';
$.ajax({
url : "${pageContext.request.contextPath }/json.action",
data : params,
contentType : "application/json;charset=UTF-8",//发送数据的格式
type : "post",
dataType : "json",//回调
success : function(data){
alert(data.name);
}
});
});
@ResponseBody是发出去的 作用是把对象变为json格式的字符串 如:'{"id":1,"name":xx}'
@RequestBody是接收的 作用是json格式的字符串变为对象
因为传过来是字符串json格式 所以用该注解转为对象格式 第二个@RequestBody
返回给ios,安卓不认识你的对象 所以要转为字符串json格式 这就是第一个@ResponseBody
开启 <mvc:annotation-driven />
- 添加
jackson
依赖<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.8.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.8.1</version> </dependency>
- 推荐阅读 SpringMVC @ResponseBody和@RequestBody使用
-
拦截器 后面补充
至此 springmvc算是进门了