zoukankan      html  css  js  c++  java
  • 20160531-20160607springmvc入门

    springmvc的基础知识

    什么是springmvc?

    springmvc框架原理(掌握)

             前端控制器、处理器映射器、处理器适配器、视图解析器

    springmvc入门程序

             目的:对前端控制器、处理器映射器、处理器适配器、视图解析器学习

             非注解的处理器映射器、处理器适配器

             注解的处理器映射器、处理器适配器(掌握)

    springmvc和mybatis整合(掌握)

    springmvc注解开发:(掌握)

             常用的注解学习

             参数绑定(简单类型、pojo、集合类型(明天讲))

             自定义参数绑定(掌握)

    springmvc和struts2区别

    1       springmvc框架

    1.1       什么是springmvc

    springmvc是spring框架的一个模块,springmvc和spring无需通过中间整合层进行整合。(struts2与Spring整合的时候需要借助单独的jar包)

    springmvc是一个基于mvc的web框架。

    1.2       mvc在b/s系统 下的应用

    mvc是一个设计模式,mvc在b/s系统 下的应用:

    1.3       springmvc框架

    第一步:发起请求到前端控制器(DispatcherServlet)

    第二步:前端控制器请求HandlerMapping查找 Handler

             可以根据xml配置、注解进行查找

    第三步:处理器映射器HandlerMapping向前端控制器返回Handler

    第四步:前端控制器调用处理器适配器去执行Handler

    第五步:处理器适配器去执行Handler

    第六步:Handler执行完成给适配器返回ModelAndView

    第七步:处理器适配器向前端控制器返回ModelAndView

             ModelAndView是springmvc框架的一个底层对象,包括 Model和view

    第八步:前端控制器请求视图解析器去进行视图解析

             根据逻辑视图名解析成真正的视图(jsp)

    第九步:视图解析器向前端控制器返回View

    第十步:前端控制器进行视图渲染

             视图渲染将模型数据(在ModelAndView对象中)填充到request域

    第十一步:前端控制器向用户响应结果

    组件:

    1、前端控制器DispatcherServlet(不需要程序员开发)

    作用接收请求,响应结果,相当于转发器,中央处理器。

    有了DispatcherServlet减少了其它组件之间的耦合度。

    2、处理器映射器HandlerMapping(不需要程序员开发)

    作用:根据请求的url查找Handler

    3、处理器适配器HandlerAdapter

    作用:按照特定规则(HandlerAdapter要求的规则)去执行Handler

    4、处理器Handler(需要程序员开发)

    注意:编写Handler时按照HandlerAdapter的要求去做,这样适配器才可以去正确执行Handler

    5、视图解析器View resolver(不需要程序员开发)

    作用:进行视图解析,根据逻辑视图名解析成真正的视图(view)

    6、视图View(需要程序员开发jsp)

    View是一个接口,实现类支持不同的View类型(jsp、freemarker、pdf...)

    2      入门程序

    2.1       需求

    以案例作为驱动。

    springmvc和mybaits使用一个案例(商品订单管理)。

    功能需求:商品列表查询

    2.2       环境准备

    数据库环境:mysql5.1

    java环境:

    jdk1.7.0_72

    eclipse luna

    springmvc版本:spring3.2

    需要spring3.2所有jar(一定包括spring-webmvc-3.2.0.RELEASE.jar)

    2.3      配置前端控制器

    在web.xml中配置前端控制器。

    <!-- springmvc前端控制器 -->
      <servlet>
          <servlet-name>springmvc</servlet-name>
          <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
          <!-- contextConfigLocation配置springmvc加载的配置文件(配置处理器映射器、适配器等等)
          如果不配置contextConfigLocation,默认加载的是/WEB-INF/servlet名称-serlvet.xml(springmvc-servlet.xml)
           -->
          <init-param>
              <param-name>contextConfigLocation</param-name>
              <param-value>classpath:springmvc.xml</param-value>
          </init-param>
      </servlet>
      
      <servlet-mapping>
          <servlet-name>springmvc</servlet-name>
          <!-- 
          第一种:*.action,访问以.action结尾 由DispatcherServlet进行解析
          第二种:/,所以访问的地址都由DispatcherServlet进行解析,对于静态文件的解析需要配置不让DispatcherServlet进行解析
          使用此种方式可以实现 RESTful风格的url
          第三种:/*,这样配置不对,使用这种配置,最终要转发到一个jsp页面时,
          仍然会由DispatcherServlet解析jsp地址,不能根据jsp页面找到handler,会报错。
          
           -->
          <url-pattern>*.action</url-pattern>
      </servlet-mapping>
      

    2.4     配置处理器适配器

    在classpath下的springmvc.xml中配置处理器适配器

    <!-- 处理器适配器
        所有的处理器适配器都实现HandlerAdapter接口
         -->
        
        <bean
            class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
        <!-- 视图解析器 -->

    通过查看原代码:

    此适配器能执行实现 Controller接口的Handler。

    2.5      开发Handler

    需要实现 controller接口,才能由org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter适配器执行。

    package cn.dzq.ssm.controller;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.web.servlet.ModelAndView;
    import org.springframework.web.servlet.mvc.Controller;
    
    import cn.dzq.ssm.po.Items;
    
    public class ItemsController1 implements Controller {
    
        @Override
        public ModelAndView handleRequest(HttpServletRequest request,
                HttpServletResponse response) throws Exception {
            // 调用service查询数据库,查询商品列表,这里使用静态数据模拟
            List<Items> itemsList = new ArrayList<Items>();
            // 向list中填充静态数据
    
            Items items_1 = new Items();
            items_1.setName("联想笔记本");
            items_1.setPrice(6000f);
            items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
    
            Items items_2 = new Items();
            items_2.setName("苹果手机");
            items_2.setPrice(5000f);
            items_2.setDetail("iphone6苹果手机!");
            
            itemsList.add(items_1);
            itemsList.add(items_2);
           
            //返回model and view
            ModelAndView modelAndView=new ModelAndView();
            //相当于request.setAttribute()方法,在jsp页面通过itemsList取数据
            modelAndView.addObject("itemsList", itemsList);
            //指定视图
            modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
            return modelAndView;
        }
    
    }

    2.6      视图编写

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"  prefix="fmt"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>查询商品列表</title>
    </head>
    <body> 
    <form action="${pageContext.request.contextPath }/item/queryItem.action" method="post">
    查询条件:
    <table width="100%" border=1>
    <tr>
    <td><input type="submit" value="查询"/></td>
    </tr>
    </table>
    商品列表:
    <table width="100%" border=1>
    <tr>
        <td>商品名称</td>
        <td>商品价格</td>
        <td>生产日期</td>
        <td>商品描述</td>
        <td>操作</td>
    </tr>
    <c:forEach items="${itemsList }" var="item">
    <tr>
        <td>${item.name }</td>
        <td>${item.price }</td>
        <td><fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/></td>
        <td>${item.detail }</td>
        
        <td><a href="${pageContext.request.contextPath }/item/editItem.action?id=${item.id}">修改</a></td>
    
    </tr>
    </c:forEach>
    
    </table>
    </form>
    </body>
    
    </html>

    2.7       配置Handler

    将编写Handler在spring容器加载。

     <!-- 配置Handler -->
        <bean id="itemsController1" name="/queryItems_test.action" class="cn.itcast.ssm.controller.ItemsController1" />

    2.8      配置处理器映射器

    在classpath下的springmvc.xml中配置处理器映射器

    <!-- 处理器映射器 -->
        <!-- 处理器映射器 将bean的name作为url进行查找 ,需要在配置Handler时指定beanname(就是url) 
        所有的映射器都实现 HandlerMapping接口。
        -->
        <bean
            class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
            

    2.9       配置视图解析器

    需要配置解析jsp的视图解析器。

    <!-- 视图解析器
        解析jsp解析,默认使用jstl标签,classpath下的得有jstl的包
         -->
        <bean
            class="org.springframework.web.servlet.view.InternalResourceViewResolver"/>

    2.10       部署调试

    访问地址:http://localhost:8080/20160601-springmvc/queryItem.action

     正确访问

    处理器映射器根据url找不到Handler,报下边的错误。说明url错误。

    处理器映射器根据url找到了Handler,转发的jsp页面找到,报下边的错误,说明jsp页面地址错误了。

    3      非注解的处理器映射器和适配器

    3.1       非注解的处理器映射器

    处理器映射器:

    org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping

    另一个映射器:

    org.springframework.web.servlet.handler.SimpleUrlHandlerMapping

    <!--简单url映射  -->
        <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
            <property name="mappings">
                <props>
                    <!-- 对itemsController1进行url映射,url是/queryItems1.action -->
                    <prop key="/queryItems1.action">itemsController1</prop>
                    <prop key="/queryItems2.action">itemsController1</prop>
                
                </props>
            </property>
        </bean>

    多个映射器可以并存,前端控制器判断url能让哪些映射器映射,就让正确的映射器处理。

    3.2     非注解的处理器适配器

    org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter

    要求编写的Handler实现 Controller接口。

    <!-- 处理器适配器 所有的处理器适配器都实现HandlerAdapter接口 -->
    
        <bean
            class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />

    org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter

    要求编写的Handler实现 HttpRequestHandler接口。

    <!-- 另一个非注解的适配器 -->
        <bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>
    public class ItemsController2 implements HttpRequestHandler {
    
        @Override
        public void handleRequest(HttpServletRequest request,
                HttpServletResponse response) throws ServletException, IOException {
            // 调用service查询数据库,查询商品列表,这里使用静态数据模拟
                    List<Items> itemsList = new ArrayList<Items>();
                    // 向list中填充静态数据
    
                    Items items_1 = new Items();
                    items_1.setName("联想笔记本");
                    items_1.setPrice(6000f);
                    items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
    
                    Items items_2 = new Items();
                    items_2.setName("苹果手机");
                    items_2.setPrice(5000f);
                    items_2.setDetail("iphone6苹果手机!");
                    
                    itemsList.add(items_1);
                    itemsList.add(items_2);
                    //设置模型数据
                   request.setAttribute("itemsList", itemsList);
                   //设置转发的视图
                   request.getRequestDispatcher("/WEB-INF/jsp/items/itemsList.jsp").forward(request, response);
                      
    
    //使用此方法可以通过修改response,设置响应的数据格式,比如响应json数据
    
     
    
    /*
    
          response.setCharacterEncoding("utf-8");
    
          response.setContentType("application/json;charset=utf-8");
    
          response.getWriter().write("json串");*/
    
     
    
    
            
        }

    4       DispatcherSerlvet.properties

     

    前端控制器从上边的文件中加载处理映射器、适配器、视图解析器等组件,如果不在springmvc.xml中配置,使用默认加载的。

    5      注解的处理器映射器和适配器

    在spring3.1之前使用org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping注解映射器。

    在spring3.1之后使用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping注解映射器。

    在spring3.1之前使用org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter注解适配器。

    在spring3.1之后使用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter注解适配器。

    5.1       配置注解映射器和适配器。

    <!--注解映射器 -->
        <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
        <!--注解适配器 -->
        <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
    <!--  使用 mvc:annotation-driven 可以代替上边两个注解映射器和注解适配器
        mvc:annotation-driven:默认加载很多的参数绑定方法,比如json的转换解析器,就默认加载了如果使用mvc:annotation-driven就不用配置注解映射器和注解适配器
        实际开发中使用mvc:annotation-driven
        -->
    <!--     <mvc:annotation-driven></mvc:annotation-driven> -->
        <!-- 处理器适配器 所有的处理器适配器都实现HandlerAdapter接口 -->

    5.2      开发注解Handler

    使用注解的映射器和注解的适配器。(注解的映射器和注解的适配器必须配对使用)

    /使用Controller表示该类是一个控制器
    @Controller
    public class ItemsController3  {
        
        
        //商品查询列表
        //@RequestMapping实现对queryItems和url的映射,一个方法对应一个url
        //一般建议url和方法名写成一样
        @RequestMapping("/queryItems")
        public ModelAndView queryItems()throws Exception{
            
            // 调用service查询数据库,查询商品列表,这里使用静态数据模拟
                    List<Items> itemsList = new ArrayList<Items>();
                    // 向list中填充静态数据
    
                    Items items_1 = new Items();
                    items_1.setName("联想笔记本");
                    items_1.setPrice(6000f);
                    items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
    
                    Items items_2 = new Items();
                    items_2.setName("苹果手机");
                    items_2.setPrice(5000f);
                    items_2.setDetail("iphone6苹果手机!");
                    
                    itemsList.add(items_1);
                    itemsList.add(items_2);
                    //返回model and view
                    ModelAndView modelAndView=new ModelAndView();
                    //相当于request.setAttribute()方法,在jsp页面通过itemsList取数据
                    modelAndView.addObject("itemsList", itemsList);
                    //指定视图
                    modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
                    return modelAndView;
        }

    5.3      在spring容器中加载Handler

    <!-- 对于注解的Handler可以单个配置
        实际开发中建议使用组件扫描
         -->
        <!-- <bean class="cn.itcast.ssm.controller.ItemsController3" /> -->
        <!-- 可以扫描controller、service、...
        这里让扫描controller,指定controller的包
         -->
        <context:component-scanbase-package="cn.itcast.ssm.controller"></context:component-scan>

    5.4     部署调试

    http://localhost:8081/20160601-springmvc/queryItems.action

    6      源码分析(重点)

    通过前端控制器源码分析springmvc的执行过程。

    第一步:前端控制器接收请求

    调用doDiapatch

    第二步:前端控制器调用处理器映射器查找 Handler

    第三步:调用处理器适配器执行Handler,得到执行结果ModelAndView

    第四步:视图渲染,将model数据填充到request域。

    视图解析,得到view:

    调用view的渲染方法,将model数据填充到request域

    渲染方法:

    7      入门程序小结

    通过入门程序理解springmvc前端控制器、处理器映射器、处理器适配器、视图解析器用法。

    前端控制器配置:

    第一种:*.action,访问以.action结尾 由DispatcherServlet进行解析

     

    第二种:/,所以访问的地址都由DispatcherServlet进行解析,对于静态文件的解析需要配置不让DispatcherServlet进行解析

       使用此种方式可以实现 RESTful风格的url

    处理器映射器:

    非注解处理器映射器(了解)

    注解的处理器映射器(掌握)

             对标记@Controller类中标识有@RequestMapping的方法进行映射。在@RequestMapping里边定义映射的url。使用注解的映射器不用在xml中配置url和Handler的映射关系。

     

    处理器适配器:

    非注解处理器适配器(了解)

    注解的处理器适配器(掌握)

             注解处理器适配器和注解的处理器映射器是配对使用。理解为不能使用非注解映射器进行映射。

    <mvc:annotation-driven></mvc:annotation-driven>可以代替下边的配置:

    <!--注解映射器 -->
        <beanclass="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
        <!--注解适配器 -->
        <beanclass="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>

    实际开发使用:mvc:annotation-driven

    视图解析器配置前缀和后缀:

    <!-- 视图解析器 解析jsp解析,默认使用jstl标签,classpath下的得有jstl的包 -->
        <bean
            class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <!-- 配置jsp路径的前缀 -->
            <property name="prefix" value="/WEB-INF/jsp/" />
            <!-- 配置jsp路径的后缀 -->
            <property name="suffix" value=".jsp" />
        </bean>

    程序中不用指定前缀和后缀:     

    8      springmvc和mybatis整合

    8.1       需求

    使用springmvc和mybatis完成商品列表查询。

    1.2       整合思路

    springmvc+mybaits的系统架构:

     

    第一步:整合dao层

             mybatis和spring整合,通过spring管理mapper接口。

             使用mapper的扫描器自动扫描mapper接口在spring中进行注册。

    第二步:整合service层

             通过spring管理 service接口。

             使用配置方式将service接口配置在spring配置文件中。

             实现事务控制。

    第三步:整合springmvc

             由于springmvc是spring的模块,不需要整合。

    8.3     准备环境

    数据库环境:mysql5.1

    java环境:

    jdk1.7.

    eclipse luna

    springmvc版本:spring3.2

    所需要的jar包:

    数据库驱动包:mysql5.1

    mybatis的jar包

    mybatis和spring整合包

    log4j包

    dbcp数据库连接池包

    spring3.2所有jar包

    jstl包

    工程结构:

    8.4      整合dao

    mybatis和spring进行整合。

    8.4.1     sqlMapConfig.xml

    mybatis自己的配置文件。

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <!--全局setting配置,根据需要添加  -->
        <!--  配置别名-->
        <typeAliases>
            <!--  批量扫描别名-->
            <package name="cn.dzq.ssm.po"/>
        </typeAliases>
        <!-- 配置mapper -->
        <!-- 由于使用spring和mybatis的整合包进行mapper的扫描,所以这里不需配置
        必须遵循mapper.xml和mapper.java文件同名,且在一个目录
         -->
       <!--  <mappers></mappers> -->
    </configuration>

    8.4.2  applicationContext-dao.xml

    配置:

    数据源

    SqlSessionFactory

    mapper扫描器

    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.2.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
            http://www.springframework.org/schema/tx
            http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">
            <!-- 加载db.properties配置文件 ,key命名要有一定的特殊规则-->
        <context:property-placeholder location="classpath:db.properties" />
            <!--  配置数据源dbcp连接池-->
            <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
            destroy-method="close">
            <property name="driverClassName" value="${jdbc.driver}" />
            <property name="url" value="${jdbc.url}" />
            <property name="username" value="${jdbc.username}" />
            <property name="password" value="${jdbc.password}" />
            <property name="maxActive" value="10" />
            <property name="maxIdle" value="5" />
        </bean>
        <!-- sqlSessionFactory -->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <!-- 数据库连接池 -->
            <property name="dataSource" ref="dataSource" />
            <!-- 加载mybatis的全局配置文件 -->
            <property name="configLocation" value="classpath:mybatis/sqlMapConfig.xml" />
        </bean>
        <!-- mapper扫描器 -->
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <!-- 扫描包路径,如果需要扫描多个包,中间使用半角逗号隔开 -->
            <property name="basePackage" value="cn.dzq.ssm.mapper"></property>
            <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
        </bean>
        
        
    </beans>

    8.4.3    逆向工程生成po类及mapper(单表增删改查)

     

    将生成的文件拷贝至工程 中。

    8.4.4    手动定义商品查询mapper

    针对综合查询mapper,一般情况会有关联查询,建议自定义mapper

    8.4.4.1              ItemsMapperCustom.xml

    sql语句:

             SELECT * FROM items  WHERE items.name LIKE '%笔记本%'

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
    <mapper namespace="cn.dzq.ssm.mapper.ItemsMapperCustom" >
    
       <!-- 定义商品查询的sql片段,就是商品查询条件 -->
       <sql id="query_items_where">
           <!-- 使用动态sql,通过if判断,满足条件进行sql拼接 -->
           <!-- 商品查询条件通过ItemsQueryVo包装对象 中itemsCustom属性传递 -->
               <if test="itemsCustom!=null">
                   <if test="itemsCustom.name!=null and itemsCustom.name!=''">
                       items.name LIKE '%${itemsCustom.name}%'
                   </if>
               </if>
        
       </sql>
          
          <!-- 商品列表查询 -->
          <!-- parameterType传入包装对象(包装了查询条件)
              resultType建议使用扩展对象
           -->
          <select id="findItemsList" parameterType="cn.dzq.ssm.po.ItemsQueryVo"
               resultType="cn.dzq.ssm.po.ItemsCustom">
              SELECT items.* FROM items  
              <where>
                  <include refid="query_items_where"></include>
              </where>
          </select>
          
    </mapper>

    8.4.4.2        ItemsMapperCustom.java

    public interface ItemsMapperCustom {
        //商品查询列表
        public List<ItemsCustom> findItemsList(ItemsQueryVo itemsQueryVo)throws Exception;
    }

    8.5      整合service

    让spring管理service接口。

    8.5.1     定义service接口

    public interface ItemsService {
        // 商品查询列表
        public List<ItemsCustom> findItemsList(ItemsQueryVo itemsQueryVo)
                throws Exception;
    }
    public class ItemsServiceImpl implements ItemsService {
    
        @Autowired 
        private ItemsMapperCustom itemsMapperCustom;
        @Override
        public List<ItemsCustom> findItemsList(ItemsQueryVo itemsQueryVo)
                throws Exception {
            
            //通过ItemsMapperCustom查询数据库
            return itemsMapperCustom.findItemsList(itemsQueryVo);
        }
    
    }

    8.5.2     在spring容器配置service(applicationContext-service.xml)

    创建applicationContext-service.xml,文件中配置service。

    <bean id="itemsService" class="cn.dzq.ssm.service.impl.ItemsServiceImpl"/>

    8.5.3     事务控制(applicationContext-transaction.xml)

    在applicationContext-transaction.xml中使用spring声明式事务控制方法。

    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.2.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
            http://www.springframework.org/schema/tx
            http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">
        <!-- 事务管理器 对mybatis的事务控制,spring使用jdbc的事务控制类 -->
        <bean id="TransactionManager"
            class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <!-- 数据源 dataSource:在applicationContext-dao.xml中配置了 -->
            <property name="dataSource" ref="dataSource" />
        </bean>
        <!-- 通知 -->
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                <!-- 传播行为 -->
                <tx:method name="save*" propagation="REQUIRED" />
                <tx:method name="delete*" propagation="REQUIRED" />
                <tx:method name="update*" propagation="REQUIRED" />
                <tx:method name="insert*" propagation="REQUIRED" />
                <tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
                <tx:method name="select*" propagation="SUPPORTS" read-only="true"/>
                <tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
            </tx:attributes>
        </tx:advice>
        <!-- aop -->
        <aop:config>
            <aop:advisor advice-ref="txAdvice" pointcut="excution(* cn.dzq.ssm.service.impl.*.*(..))"/>
        </aop:config>
    </beans>

    8.6     整合springmvc

    8.6.1    springmvc.xml

    创建springmvc.xml文件,配置处理器映射器、适配器、视图解析器。

    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.2.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
            http://www.springframework.org/schema/tx
            http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">
    
        
    
        <!-- 对于注解的Handler可以单个配置 实际开发中建议使用组件扫描 -->
        <!-- <bean class="cn.itcast.ssm.controller.ItemsController3" /> -->
        <!-- 可以扫描controller、service、... 这里让扫描controller,指定controller的包 -->
        <context:component-scan base-package="cn.dzq.ssm.controller"></context:component-scan>
    
    
        
        <!--注解映射器 -->
        <!-- <bean
            class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" /> -->
        <!--注解适配器 -->
        <!-- <bean
            class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" /> -->
    
        <!-- 使用 mvc:annotation-driven 可以代替上边两个注解映射器和注解适配器 mvc:annotation-driven:默认加载很多的参数绑定方法,比如json的转换解析器,就默认加载了如果使用mvc:annotation-driven就不用配置注解映射器和注解适配器 
            实际开发中使用mvc:annotation-driven -->
         <mvc:annotation-driven>
             
         </mvc:annotation-driven> 
         
        <!-- 视图解析器 解析jsp解析,默认使用jstl标签,classpath下的得有jstl的包 -->
        <bean
            class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <!-- 配置jsp路径的前缀 -->
            <property name="prefix" value="/WEB-INF/jsp/" />
            <!-- 配置jsp路径的后缀 -->
            <property name="suffix" value=".jsp" />
        </bean>
    
    </beans>

    8.6.2     配置前端控制器

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
      <display-name>springmvcfirst1208</display-name>
      
      <!-- springmvc前端控制器 -->
      <servlet>
          <servlet-name>springmvc</servlet-name>
          <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
          <!-- contextConfigLocation配置springmvc加载的配置文件(配置处理器映射器、适配器等等)
          如果不配置contextConfigLocation,默认加载的是/WEB-INF/servlet名称-serlvet.xml(springmvc-servlet.xml)
           -->
          <init-param>
              <param-name>contextConfigLocation</param-name>
              <param-value>classpath:springmvc.xml</param-value>
          </init-param>
      </servlet>
      
      <servlet-mapping>
          <servlet-name>springmvc</servlet-name>
          <!-- 
          第一种:*.action,访问以.action结尾 由DispatcherServlet进行解析
          第二种:/,所以访问的地址都由DispatcherServlet进行解析,对于静态文件的解析需要配置不让DispatcherServlet进行解析
          使用此种方式可以实现 RESTful风格的url
          第三种:/*,这样配置不对,使用这种配置,最终要转发到一个jsp页面时,
          仍然会由DispatcherServlet解析jsp地址,不能根据jsp页面找到handler,会报错。
          
           -->
          <url-pattern>*.action</url-pattern>
      </servlet-mapping>
      
      
      <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
      </welcome-file-list>
    </web-app>

    8.6.3    编写Controller(就是Handler)

    public class ItemsController {
        @Autowired 
        private ItemsService itemService;
        // 商品查询
        // 商品查询列表
        // @RequestMapping实现对queryItems和url的映射,一个方法对应一个url
        // 一般建议url和方法名写成一样
        @RequestMapping("/queryItems")
        public ModelAndView queryItems() throws Exception {
    
            // 调用service查询数据库,查询商品列表,这里使用静态数据模拟
            List<ItemsCustom> itemsList = itemService.findItemsList(null);
    
            // 返回model and view
            ModelAndView modelAndView = new ModelAndView();
            // 相当于request.setAttribute()方法,在jsp页面通过itemsList取数据
            modelAndView.addObject("itemsList", itemsList);
            // 指定视图
            // 下边的路径如果在视图解析器中配置了jsp路径的前缀和后缀,修改为:
            // modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
            // 上边的路径配置就可以不在程序中指定jsp路径的前缀和后缀
            modelAndView.setViewName("items/itemsList");
            return modelAndView;
        }
        // 商品修改
    }

    8.6.4    编写jsp

    8.7     加载spring容器

    将mapper、service、controller加载到spring容器中。

    建议使用通配符加载上边的配置文件。

    在web.xml中,添加spring容器监听器,加载spring容器。

    <!-- 加载spring容器 -->
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/classes/spring/applicationContext-*.xml</param-value>
        </context-param>
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>

    9      商品修改功能开发

    9.1       需求

    操作流程:

    1、进入商品查询列表页面

    2、点击修改,进入商品修改页面,页面中显示了要修改的商品(从数据库查询)

             要修改的商品从数据库查询,根据商品id(主键)查询商品信息

    3、在商品修改页面,修改商品信息,修改后,点击提交

    9.2       开发mapper

    mapper:

             根据id查询商品信息

             根据id更新Items表的数据

    不用开发了,使用逆向工程生成的代码。

    9.3       开发service

    接口功能:

             根据id查询商品信息

             修改商品信息

    //根据id查询商品信息
        public ItemsCustom findItemById(Integer id) throws Exception;
        //修改商品信息
        /**
         * 修改商品信息
         * @param id 修改的商品的id
         * @param itemsCustom 修改的商品信息
         * @throws Exception
         */
        public void updateItems (Integer id,ItemsCustom itemsCustom)throws Exception;

    实现:

    public class ItemsServiceImpl implements ItemsService {
    
        @Autowired 
        private ItemsMapperCustom itemsMapperCustom;
        @Autowired
        private ItemsMapper itemsMapper;
        @Override
        public List<ItemsCustom> findItemsList(ItemsQueryVo itemsQueryVo)
                throws Exception {
            
            //通过ItemsMapperCustom查询数据库
            return itemsMapperCustom.findItemsList(itemsQueryVo);
        }
        @Override
        public ItemsCustom findItemById(Integer id) throws Exception {
            Items items=itemsMapper.selectByPrimaryKey(id);
            //中间进行业务处理
            //...
            //最终返回ItemsCustom
            return (ItemsCustom) itemsMapper.selectByPrimaryKey(id);
        }
        @Override
        public void updateItems(Integer id, ItemsCustom itemsCustom) throws Exception {
            //添加业务校验,在service接口中对关键的参数进行校验
            
            //校验id是否为空,如果为空就抛出异常
            
            //更新商品信息使用updateByPrimaryKeyWithBLOBs 根据id更新字段,包括大文本类型
            itemsCustom.setId(id);
            itemsMapper.updateByPrimaryKeyWithBLOBs(itemsCustom);
        }

    9.4     开发controller

    方法:

             商品信息修改页面显示

             商品信息修改提交

    10      @RequestMapping       

     url映射

    定义controller方法对应的url,进行处理器映射使用。

     窄化请求映射

       限制http请求方法

    出于安全性考虑,对http的链接进行方法限制。

    如果限制请求为post方法,进行get请求,报错:

    11      controller方法的返回值

             返回ModelAndView

    需要方法结束时,定义ModelAndView,将model和view分别进行设置。

             返回string

    如果controller方法返回string,

    @RequestMapping(value="/editItems",method={RequestMethod.POST,RequestMethod.GET})
        public String editItems(Model model)throws Exception{
            //调用service根据商品id查询商品信息
            ItemsCustom itemsCustom=itemService.findItemById(1);
            //通过形参中的model将数据传到页面
            //相当于modelAndView.addObject("itemsCustom",itemsCustom);
            model.addAttribute("itemsCustom",itemsCustom);
            return "items/editItems";
        }

    1、表示返回逻辑视图名。

    真正视图(jsp路径)=前缀+逻辑视图名+后缀

    2、redirect重定向

    商品修改提交后,重定向到商品查询列表。

    redirect重定向特点:浏览器地址栏中的url会变化。修改提交的request数据无法传到重定向的地址。因为重定向后重新进行request(request无法共享)

    3、forward页面转发

    通过forward进行页面转发,浏览器地址栏url不变,request可以共享。

     返回void

    在controller方法形参上可以定义request和response,使用request或response指定响应结果:

    1、使用request转向页面,如下:

    request.getRequestDispatcher("页面路径").forward(request, response);

    2、也可以通过response页面重定向:

    response.sendRedirect("url")

    3、也可以通过response指定响应结果,例如响应json数据如下:

    response.setCharacterEncoding("utf-8");

    response.setContentType("application/json;charset=utf-8");

    response.getWriter().write("json串");

    12       参数绑定

    12.1       spring参数绑定过程

    从客户端请求key/value数据,经过参数绑定,将key/value数据绑定到controller方法的形参上。

    springmvc中,接收页面提交的数据是通过方法形参来接收。而不是在controller类定义成员变更接收!!!!

    12.2      默认支持的类型

    直接在controller方法形参上定义下边类型的对象,就可以使用这些对象。在参数绑定过程中,如果遇到下边类型直接进行绑定。

     HttpServletRequest

    通过request对象获取请求信息

     HttpServletResponse

    通过response处理响应信息

     HttpSession

    通过session对象得到session中存放的对象

     Model/ModelMap

    model是一个接口,modelMap是一个接口实现 。

    作用:将model数据填充到request域。

    12.3      简单类型

    通过@RequestParam对简单类型的参数进行绑定。

    如果不使用@RequestParam,要求request传入参数名称和controller方法的形参名称一致,方可绑定成功。

    如果使用@RequestParam,不用限制request传入参数名称和controller方法的形参名称一致。

     

    通过required属性指定参数是否必须要传入,如果设置为true,没有传入参数,报下边错误:

     

    12.4      pojo绑定

    页面中input的name和controller的pojo形参中的属性名称一致,将页面中数据绑定到pojo对应的属性。

    页面定义:

    controller的pojo形参的定义:

    需要说明的是:简单类型的参数绑定和pojo参数绑定互不影响。

    12.5      自定义参数绑定实现日期类型绑定

    对于controller形参中pojo对象,如果属性中有日期类型,需要自定义参数绑定。

    将请求日期数据串传成 日期类型,要转换的日期类型和pojo中日期属性的类型保持一致。

    所以自定义参数绑定将日期串转成java.util.Date类型。

    需要向处理器适配器中注入自定义的参数绑定组件。

    12.5.1     自定义日期类型绑定

    package cn.dzq.ssm.controller.converter;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import org.springframework.core.convert.converter.Converter;
    
    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 (ParseException e) {
                e.printStackTrace();
            }
            //如果参数绑定失败,返回null
            return null;
        }
    
    }

    12.5.2     配置方式

    <!-- 自定义参数绑定 -->
    <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <!--转换器  -->
        <property name="converters">
            <list>
                <!-- 日期类型的转换 -->
                <bean class="cn.dzq.ssm.controller.converter.CustomDateConverter"/>
                
            </list>
        </property>
    </bean>

    13       springmvc和struts2的区别

    1、springmvc基于方法开发的,struts2基于类开发的。

    springmvc将url和controller方法映射。映射成功后springmvc生成一个Handler对象,对象中只包括了一个method。

    方法执行结束,形参数据销毁。

    springmvc的controller开发类似service开发。

    2、springmvc可以进行单例开发,并且建议使用单例开发,struts2通过类的成员变量接收参数,无法使用单例,只能使用多例。(原因就是第一句)

    3、经过实际测试,struts2速度慢,在于使用struts标签,如果使用struts建议使用jstl。

    14       问题

    14.1       post乱码

    在web.xml添加post乱码filter

    在web.xml中加入:

    <filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
    <param-name>encoding</param-name>
    <param-value>utf-8</param-value>
    </init-param>
    </filter>
    <filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>

    以上可以解决post请求乱码问题。

    对于get请求中文参数出现乱码解决方法有两个:

    修改tomcat配置文件添加编码与工程编码一致,如下:

    <Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

    另外一种方法对参数进行重新编码:

    String userName new 
    String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")

    ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码

  • 相关阅读:
    LeetCode 88. Merge Sorted Array
    LeetCode 75. Sort Colors
    LeetCode 581. Shortest Unsorted Continuous Subarray
    LeetCode 20. Valid Parentheses
    LeetCode 53. Maximum Subarray
    LeetCode 461. Hamming Distance
    LeetCode 448. Find All Numbers Disappeared in an Array
    LeetCode 976. Largest Perimeter Triangle
    LeetCode 1295. Find Numbers with Even Number of Digits
    如何自学并且系统学习计算机网络?(知乎问答)
  • 原文地址:https://www.cnblogs.com/xiaoduc-org/p/5547616.html
Copyright © 2011-2022 走看看