原文链接: 1、SpringMVC——走出新手村 2、SpringMVC——初次见面 3、SpringMVC——走出新手村
SpringMVC是什么
小编之前一直把他搞混,因为MVC就觉得他还能做数据持久层(抱头痛哭状,基础不扎实啊)。其实Spring Web MVC和Struts2都属于表现层的框架,它是Spring框架的一部分,从Spring的整体结构中看得出来,如下图:
接下来老规矩,上代码。
撸代码
导包
SpringMVC运行索要的jar包如下。(改天弄个Maven就不要挑jar这么麻烦了)
创建springmvc.xml
SpringMVC本身就是Spring的子项目,对Spring兼容性很好。(毕竟是亲儿子)专业术语叫“无缝整合”。SpringMVC是表现层所以他控制的就是Controller(以后你接触的表现出基本都会叫这个名字了,忘记action吧!)
导入这些约束spring-aop、spring-beans、spring-context、spring-mvc、spring-tool、spring-tx、spring-util
代码语言:javascript复制<!-- 配置controller扫描包 -->
<context:component-scan
base-package="com.ziyuanshequ.springmvc.controller" />
</beans>
配置前端控制器
配置SpringMVC的前端控制器DispatcherServlet在web.xml中。
代码语言:javascript复制<!-- 配置SpringMVC前端控制器 -->
<servlet>
<servlet-name>ziyuanshequ</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 指定SpringMVC配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ziyuanshequ</servlet-name>
<!-- 设置所有以action结尾的请求进入SpringMVC -->
<url-pattern>*.action</url-pattern>
</servlet-mapping>
加入jsp页面
代码语言:javascript复制<c:forEach items="${itemList }" var="item">
<tr>
<td>${item.name }</td>
<td><fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/></td>
<td>${item.detail }</td>
</tr>
</c:forEach>
entity
代码语言:javascript复制public class Item {
// 商品id
private int id;
// 商品名称
private String name;
// 商品创建时间
private Date createtime;
// 商品描述
private String detail;
set/get...
}
创建ItemController
代码语言:javascript复制@Controller
public class ItemController {
// 请求的url,和用户请求的url进行匹配,.action可不写
@RequestMapping("/itemList.action")
public ModelAndView getItemList() {
// 创建页面需要显示的商品数据
List<Item> list = new ArrayList<>();
list.add(new Item(1, "小米", new Date(), "质量好!"));
list.add(new Item(2, "华为", new Date(), "质量好!"));
list.add(new Item(3, "魅族", new Date(), "质量好!"));
// 创建ModelAndView,用来存放数据和视图
ModelAndView modelAndView = new ModelAndView();
// 设置数据到模型中
modelAndView.addObject("list", list);
// 设置视图jsp,需要设置视图的物理地址
modelAndView.setViewName("/WEB-INF/jsp/itemList.jsp");
return modelAndView;
}
}
Springmvc架构
框架结构
架构流程
1、用户发送请求至前端控制器DispatcherServlet。
2、DispatcherServlet收到请求调用HandlerMapping处理器映射器。
3、处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
4、DispatcherServlet通过HandlerAdapter处理器适配器调用处理器。
5、执行处理器(Controller,也叫后端控制器)。
6、Controller执行完成返回ModelAndView。
7、HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。
8、DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
9、ViewReslover解析后返回具体View。
10、DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)。
11、DispatcherServlet响应用户。
组件说明
DispatcherServlet:前端控制器
用户请求到达前端控制器,它就相当于mvc模式中的c,DispatcherServlet是整个流程控制的中心,由它调用其它组件处理用户的请求,DispatcherServlet的存在降低了组件之间的耦合性。
HandlerMapping:处理器映射器
HandlerMapping负责根据用户请求url找到Handler即处理器,Springmvc提供了不同的映射器实现不同的映射方式。(配置文件方式、实现接口方式、注解方式等)
Handler:处理器
Handler是继DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下Handler对具体的用户请求进行处理。由于Handler涉及到具体的用户业务请求,所以一般情况需要程序员根据业务需求开发Handler。(就是你写的Controller)
HandlAdapter:处理器适配器
通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。
ViewResolver:视图解析器
ViewResolver负责将处理结果生成View视图,ViewResolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户。
View:视图
springmvc框架提供了很多的View视图类型的支持,包括:jstlView、freemarkerView、pdfView等。我们最常用的视图就是jsp。
我们没有做任何配置,就可以使用这些组件是因为框架已经默认加载这些组件了。是不是觉得很贴心呢!(文件在spring-webmvc包下org.springframework.web.servlet中的DispatcherServlet.properties文件,没事可以点进去看看。)这名字真长我排版都不好看了!
下面请认真阅读
注解式处理器映射器
对类中标记了@ResquestMapping的方法进行映射。根据@ResquestMapping定义的url匹配@ResquestMapping标记的方法,匹配成功返回HandlerMethod对象给前端控制器。HandlerMethod对象中封装url对应的方法Method。 但是从spring3.1版本开始,废除了DefaultAnnotationHandlerMapping的使用,推荐使用RequestMappingHandlerMapping完成注解式处理器映射。在springmvc.xml中配置如下:
代码语言:javascript复制<!-- 配置处理器映射器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />
注解式处理器适配器
对标记@ResquestMapping的方法进行适配。从spring3.1版本开始,废除了AnnotationMethodHandlerAdapter的使用,推荐使用RequestMappingHandlerAdapter完成注解式处理器适配。在springmvc.xml中配置如下:
代码语言:javascript复制<!-- 配置处理器适配器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" />
直接配置处理器映射器和处理器适配器比较麻烦,可以使用注解驱动来加载。springmvc.xml配置文件中使用替代注解处理器和适配器的配置。
代码语言:javascript复制<!-- 注解驱动 -->
<mvc:annotation-driven />
视图解析器
视图解析器使用SpringMVC框架默认的InternalResourceViewResolver,这个视图解析器支持JSP视图解析在springmvc.xml配置文件中配置如下:
代码语言:javascript复制<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 配置逻辑视图的前缀 -->
<property name="prefix" value="/WEB-INF/jsp/" />
<!-- 配置逻辑视图的后缀 -->
<property name="suffix" value=".jsp" />
</bean>
现在我们可以修改ItemController中的代码
代码语言:javascript复制// 设置视图jsp,需要设置视图的物理地址
modelAndView.setViewName("/WEB-INF/jsp/itemList.jsp");
就可以改为
代码语言:javascript复制modelAndView.setViewName("itemList");
改了这么多就是为了少敲几个代码,有没有很生气呢!(你又打不到我)但是以后工作上班,搭建好的项目就是这样子的。
参数绑定你要知道的
springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过滤器。 springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过request域传输到页面。(感兴趣的可以看看底层方法,就和你当时学的servlet是一样。)
万年的ID
页面点击修改按钮,发起请求
http://127.0.0.1:8080/springmvc/itemEdit.action?id=1
需要从请求的参数中把请求的id取出来。Id包含在Request对象中。可以从Request对象中取id。想获得Request对象只需要在Controller方法的形参中添加一个参数即可。Springmvc框架会自动把Request对象传递给方法。
代码语言:javascript复制@RequestMapping("/itemEdit")
public ModelAndView queryItemById(HttpServletRequest request) {
String strId = request.getParameter("id");
// 把结果传递给页面
ModelAndView modelAndView = new ModelAndView();
// 把数据放在模型中
modelAndView.addObject("item", service.findById(strId));
// 设置逻辑视图
modelAndView.setViewName("itemEdit");
return modelAndView;
}
END
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
怎么可能那么短。不存在的!打起精神下面才是重头。
Model
除了ModelAndView以外,还可以使用Model来向页面传递数据,Model是一个接口,在参数里直接声明model即可。如果使用Model则可以不使用ModelAndView对象,Model对象可以向页面传递数据,View对象则可以使用String返回值替代。不管是Model还是ModelAndView,其本质都是使用Request对象向jsp传递数据。
代码语言:javascript复制@RequestMapping("/itemEdit")
public String queryItemById(HttpServletRequest request, Model model) {
// 从request中获取请求参数
String strId = request.getParameter("id");
// 把数据放在模型中
model.addAttribute("item", service.findById(strId));
return "itemEdit";
}
ModelMap
ModelMap是Model接口的实现类,也可以通过ModelMap向页面传递数据使用Model和ModelMap的效果一样,如果直接使用Model,springmvc会实例化ModelMap。
代码语言:javascript复制@RequestMapping("/itemEdit")
public String queryItemById(HttpServletRequest request, ModelMap model) {
// 从request中获取请求参数
String strId = request.getParameter("id");
// 把数据放在模型中
model.addAttribute("item", service.findById(strId));
return "itemEdit";
}
绑定简单类型
当请求的参数名称和处理器形参名称一致时会将请求参数与形参进行绑定。这样,从Request取参数的方法就可以进一步简化。
代码语言:javascript复制@RequestMapping("/itemEdit")
public String queryItemById(int id, ModelMap model) {
// 把数据放在模型中
model.addAttribute("item", service.findById(id));
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
使用@RequestParam常用于处理简单类型的绑定。
value:参数名字,即入参的请求参数名字,如value=“itemId”表示请求的参数区中的名字为itemId的参数的值将传入。
required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报错。TTP Status 400 - Required Integer parameter 'XXXX' is not present
defaultValue:默认值,表示如果请求中没有同名参数时的默认值。
代码语言:javascript复制@RequestMapping("/itemEdit")
public String queryItemById(@RequestParam(value = "itemId", required = true,
defaultValue = "1")int id,ModelMap model) {
// 把数据放在模型中
model.addAttribute("item", service.findById(id));
return "itemEdit";
}
绑定pojo类型
实体
代码语言:javascript复制public class Items {
private Integer id;
private String name;
private Float price;
private String pic;
private Date createtime;
private String detail;
get...set....
jsp页面
代码语言:javascript复制<form id="itemForm"action="/addItem.action" method="post">
<input type="hidden" name="id" />
<input type="text" name="name" />
<input type="text" name="pic" />
controller层
代码语言:javascript复制@RequestMapping("/addItem")
public String addItem(Item item) {
service.save(item);
// 返回逻辑视图
return "success";
}
注意:提交的表单中不要有日期类型的数据,否则会报400错误。如果想提交日期类型的数据需要用到后面的自定义参数绑定的内容。
绑定包装pojo
代码语言:javascript复制public class QueryVo {
private Item item;
set/get...
}
jsp页面
代码语言:javascript复制<form id="itemForm"action="/addItem.action" method="post">
<input type="hidden" name="item.id" />
<input type="text" name="item.name" />
<input type="text" name="item.pic" />
controller层
代码语言:javascript复制@RequestMapping("/queryItem")
public String queryItem(QueryVo queryVo) {
System.out.println(queryVo.getItem().getId());
System.out.println(queryVo.getItem().getName());
return "success";
}
推荐阅读目录
⊙ Java学习求职路线(资料、视频、源码、项目实战)
⊙ 程序员用这5种方式学习编程最无效,停止这些可以少走弯路!
⊙大学毕业刚培训完Java,没有经验怎么找工作呢?
⊙请问你知道什么是栈吗?
⊙看看你对队列的了解有多少?
⊙面试题68(加深你对栈的理解_让你知道什么是栈)
⊙来测试一下你对数据结构中的栈和队列的了解有多少?
⊙面试题63(链表,哈希表)
⊙ 请你对Java中树的了解有多少?
⊙ 这个培训机构怎么?
⊙ JavaEE就业学习路线(给初学者以及自学者一个学习方向)?
⊙ Servlet实现一个简单的登录【验证码】功能
⊙二维码生成源码
⊙java学习微信讨论群
⊙Spring学习笔记
⊙Mybatis学习笔记