SpringMVC第一阶段

springMVC

什么是springMVC

springMVC是spring公司出品的一个表现层框架

springMVC作用

  • 从请求中接受数据
  • 将处理好的数据返回给页面

入门程序

  1. 建项目,引jar包

  2. 创建包结构,控制层用controller

  • 处理流程

3.在web.xml中配置dispacherServlet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<servlet>
<servlet-name>springMvc</servlet-name>
<servlet-class></servlet-class>
<!-- tomcat一启动就加载 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMvc</servlet-name>
<!--
/* 拦截所有路劲,都会进入dispatherServlet中但不放行,所以不能使用
*.action 拦截url路劲以.action结尾的,这样的路劲才能进入dispatherServlet
/ 拦截所有路劲,但是不包括j.sp,但是 js,css,png,jpg 等都会被拦截而不放行
-->
<url-pattern>*.action</url-pattern>
</servlet-mapping>
  • 如果没有配置springMvc的核心配置文件的位置,那么会默认去找 上面Servlet-name的值-servlet.xml 这个名称的配置文件。
    • 当然也可以手动配置
      1
      2
      3
      4
      5
      //在上面的`<servlet-class>`下面加
      <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:SpringMvc.xml</param-value>
      </init-param>

4.这里采用注解的方式

  • 现在配置文件中开启包的扫描<context:component-scan base-package="cn.itcast.controller"/>
  • 然后再在controller中的类ItemsController上加上@Controller
  • 在list方法上加@RequestMapping("/list")
    • 表示标记url到请求方法的映射,其实就是通过url找到需要的controller方法
    • 相当于一个map
    • @RequestMapping(value="/list")也是对的,@RequestMapping(name="/list")自己测的是对的,但是网上说不对。。。
  • 配置注解驱动:下面会详细讲<mvc:annotation-driven conversion-service="conversionService"/>

5.跳转:

  • ModelAndView modelView = new ModelAndView();
    • 模型和视图:模型放了返回给页面的数据,视图指定了页面的地址
    • 在SpringMvc中model底层中其实是将数据放入了request中,并且对request域进行了扩展
  • modelView.addObject("itemList",itemList);
    • 将返回的页面的数据放入model中其实就相当于放入了request域中
  • modelView.setViewName("/WEB-INF/jsp/itemList.jsp");

    • 指定页面的位置
    • 这里面的路劲叫做逻辑路径,就是页面地址的字符串
    • 可以配置视图解析器,配置路劲前面跟后面的东西
      1
      2
      3
      4
      5
      //前面是/WEB-INF/jsp/,后面是.jsp
      <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
      <property name="prefix" value="/WEB-INF/jsp/"></property>
      <property name="suffix" value=".jsp"></property>
      </bean>
  • 最后返回return modelView;

逻辑路径:就是页面地址的字符串
物理路径:是根据逻辑路径中的地址来加载页面成view对象


然后再通过访问:.../list.action 就可以访问到ItemsController里面的list方法,并执行完毕之后跳转到/WEB-INF/jsp/itemList.jsp

springMvc的三大组件:

  • 处理器映射器:
  • 处理器适配器
  • 视图解析器

  • 如果没有手动配置处理器映射器跟处理器适配器可以正常运行,但每个请求都会去找springmvc默认的文件DispatcherServlet.properties,去里面找合适的处理器映射器跟处理器适配器,这样会降低系统的访问效率

  • 所以我们需要手动配置处理器映射器跟处理器适配器,就不用去默认的配置文件中找了,加快效率

    • 老版本:在DispatcherServlet.properties中呢,
    • 新版本:在包下面的类中,
  • 在公司中都不用,用这个<mvc:annotation-driven />

    • 注解驱动:自动配置最新版本的处理器映射器跟处理器适配器
    • 只是为了方便
  • 面试题:注解驱动和注解扫描是否都是需要配置的?为什么?区别是什么?

    • 注解驱动:是为我们自动配置最新版的注解形式的处理器映射器和处理器适配器
    • 注解扫描:扫描指定包下有@controller注解的类
    • 两个东西不是一回事, 不要混淆视听

  • 视图解析器:作用是将前缀和后缀分开在我们的controller中写页面地址的时候方便使用
  • 配置好前缀跟后缀后:页面的路劲=前缀+controller中的地址+后缀
1
2
3
4
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value=""></property>
<property name="suffix" value=""></property>
</bean>

架构流程

  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负责根据用户请求找到Handler即处理器,springmvc提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。
  • Handler:处理器
    • Handler 是继DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下Handler对具体的用户请求进行处理。
    • 由于Handler涉及到具体的用户业务请求,所以一般情况需要程序员根据业务需求开发Handler。
  • HandlAdapter:处理器适配器
    • 通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。
  • View Resolver:视图解析器
    • View Resolver负责将处理结果生成View视图,View Resolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户.
  • View:视图
    • springmvc框架提供了很多的View视图类型的支持,包括:jstlView、freemarkerView、pdfView等。我们最常用的视图就是jsp。
    • 一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面。

  • 说明:在springmvc的各个组件中,处理器映射器、处理器适配器、视图解析器称为springmvc的三大组件。
    需要用户开放的组件有handler、view

Mybatis跟SpringMvc跟Spring架构整合

  • model.addAttribute("item",items);其实就是将数据放入了request域中并做了扩展
  • SpringMvc规定只有controller方法返回一个普通的字符串,就认为是页面的名称,会走视图解析器拼接完整的页面路径

架构整合思路

dao层:
映射文件,接口文件,pojo使用逆向工程自动生成
sqlMapConfig.xml mybatis核心配置文件中可以为空的但是必须有
ApplicationContext-dao.xml数据源,连接池,会话工厂,mapper包扫面

service层:
ApplicationContext-service.xml 配置@Service注解扫面
ApplicationContext-trans.xml 注解事务

controller层:
SpringMvc.xml注解扫描,注解驱动,视图解析器

具体实现

  1. 导入jar包,配置配置文件,创建包结构
  2. 通过mybatis的逆向工程生成dao跟pojo
  3. 创建一些列的配置文件

参数绑定

  • 从页面中接受参数:
    • 默认支持的类型(需要哪个加哪个):HttpServletRequest,HttpServletResponse,HttpSession,model(可以理解为Request域)
    • 简单类型:String,double,integer,long,boolean等
    • pojo类型
    • pojo包装类QueryVo
    • 自定义转换器converter
  1. 默认支持的类型的意思就是可以在方法的参数上直接加参数,就会就收到
1
2
3
4
5
6
7
8
9
10
//演示SpringMvc默认支持的参数
@RequestMapping("/toEdit")
public String toEdit(HttpServletRequest request,Model model){
String id=request.getParameter("id");
Item items=itemsService.findItemById(Integer.parseInt(id));
//将数据放入model中,其实就是将数据放入了request域中并做了扩展
model.addAttribute("items",items);
//SpringMvc规定只有controller方法返回一个普通的字符串,就认为是页面的名称,会走视图解析器拼接完整的页面路径
return "editItems";
}

2.简单类型:接收的变量名称必须等于页面上的input框的name值,SpringMvc自动进行类型转化

1
2
3
public String update(Integer id,String name){
}

3.pojo类型:接收pojo中的属性值必须等于页面上的input框的name值

1
2
3
public String update(Items items){
}

4.QueryVo:如果传入的是QueryVo,那么页面上框的name值是属性.属性.属性。。。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class QueryVo{
private Items items;
private String ids;
}
<form action="${pageContext.request.contextPath }/search.action" mothod="post">
<input type="input" name="items.name" />
<input type="input" name="items.price" />
</form>
@RequestMapping("/search")
public String search(QueryVo vo) throws Exception{
System.out.println(vo);
return "success";
}

自定义转换

SpringMvc可以进行简单类型的自动类型的转换,但是无法转化日期类型,所以需要自定义转化器来转换

  • 可以在建一个CustomerGlobalStrToDateConverter类实现Converter接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class CustomerGlobalStrToDateConverter implements Converter<String, Date> {
@Override
public Date convert(String source) {
try {
//具体转换内容
Date date = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(source);
return date;
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
  • 在SpringMvc.xml配置文件中配置一下
1
2
3
4
5
6
7
8
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<!-- 自定义全局字符串转日期转换器 -->
<bean class="CustomerGlobalStrToDateConverter全路劲"/>
</set>
</property>
</bean>

传入参数的注解

1
2
3
4
@RequestMapping(value="/list")
public ModelAndView list(){
}
  • 在括号中添加参数@RequestParam(defaultValue = "1") Long id
    • 表述默认传入的参数是1
    • 如果传入一个新的id就是那个新的
  • 添加@RequestParam(required = boolean) Long id
    • false:传与不传没区别
    • true:不传参数就会报400错误
  • 添加@RequestParam("id") Long id
    • 不传就会报400

编码问题

因为SpringMvc不像Struts2一样能自动解决乱码问题,所以需要手动解决
如果是post提交可以,配置一个过滤器:

get提交可以手动编解码或配置tomcat

SpringMvc跟Struts2的区别

  • struts2:
    • struts2的核心控制器是filter
    • 接收参数:模型驱动(也就是全局类型的对象,但是他是不安全的所以他的核心控制器需要配置成多例)
    • 返回参数:struts2使用值栈
  • springMvc:
    • SpringMvc核心控制器是servlet
    • 接受参数:springMvc采用方法级别的局部变量来接受参数,局部变量用完就销毁,所以线程是安全的
    • 返回数据:springMvc使用request域
张冲 wechat
欢迎扫一扫上面的微信关注我,一起交流!
坚持原创技术分享,您的支持将鼓励我继续创,点击打赏!