springMVC基础

2019年11月17日 阅读数:69
这篇文章主要向大家介绍springMVC基础,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

课程安排: 第一天:springmvc的基础知识 什么是springmvc? springmvc框架原理(掌握) 前端控制器、处理器映射器、处理器适配器、视图解析器 springmvc入门程序 目的:对前端控制器、处理器映射器、处理器适配器、视图解析器学习 非注解的处理器映射器、处理器适配器 注解的处理器映射器、处理器适配器(掌握) springmvc和mybatis整合(掌握) springmvc注解开发:(掌握) 经常使用的注解学习 参数绑定(简单类型、pojo、集合类型(明天讲)) 自定义参数绑定(掌握) springmvc和struts2区别 次日:springmvc的高级应用 参数绑定(集合类型) 数据回显 上传图片 json数据交互 RESTful支持 拦截器php

1、什么是springmvc
2、入门程序--商品列表查询(采用注解,xml方式略)
3、源码分析 略,结合struts2原理和以前的画图不难分析.
4、mybatis、springMVC整合
5、@RequestMapping
6、controller方法的返回值
7、参数绑定
8、springmvc和struts2的区别
9、springmvc校验
10、数据回显
11、异常处理
12、上传图片
十3、json数据交互
十4、RESTful支持
十5、拦截器
View Code

1、什么是springmvc

一、springmvc是spring框架的一个模块,springmvc和spring无需经过中间整合层进行整合(无缝链接),一个基于mvc的web框架.css

二、springmvc执行过程前端

执行步骤:vue

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

第二步:前端控制器请求HandlerMapping查找 Handler(能够根据xml配置、注解进行查找)mysql

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

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

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

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

第七步:处理器适配器向前端控制器返回ModelAndView,ModelAndView是springmvc框架的一个底层对象,包括 Model和view

第八步:前端控制器请求视图解析器去进行视图解析, 根据逻辑视图名解析成真正的视图(jsp)

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

第十步:前端控制器进行视图渲染,视图渲染将模型数据(在ModelAndView对象中)填充到request域

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

组件:

一、前端控制器DispatcherServlet(不须要程序员开发),做用接收请求,响应结果,至关于转发器,中央处理器.有了DispatcherServlet减小了其它组件之间的耦合度.

二、处理器映射器HandlerMapping(不须要程序员开发),做用:根据请求的url查找Handler.

三、处理器适配器HandlerAdapter(不须要程序员开发),做用:按照特定规则(HandlerAdapter要求的规则)去执行Handler.

四、处理器Handler(须要程序员开发),注意:编写Handler时按照HandlerAdapter的要求去作,这样适配器才能够去正确执行Handler.

五、视图解析器View resolver(不须要程序员开发),做用:进行视图解析,根据逻辑视图名解析成真正的视图(view).

六、视图View(须要程序员开发jsp),View是一个接口,实现类支持不一样的View类型(jsp、freemarker、pdf...).

2、入门程序--商品列表查询(采用注解,xml方式略)

一、导入spring相应jar包,必定包括spring-webmvc-3.2.0.RELEASE.jar.

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

<?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
      第三种:/*,这样配置不对,会报错.-->
      <url-pattern>*.action</url-pattern>
  </servlet-mapping>
</web-app>
View Code

三、xml方式在springmvc.xml中配置处理器、适配器过程略,基本不会使用,使用默认配置便可,注解方式加以下一行便可:

<mvc:annotation-driven /> 

四、开发注解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>();     
        Items items_1 = new Items();
        items_1.setName("联想笔记本");
        items_1.setPrice(6000f);
        items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
        itemsList.add(items_1);
        
       //返回ModelAndView
        ModelAndView modelAndView =  new ModelAndView();
       //至关 于request的setAttribut,在jsp页面中经过itemsList取数据
        modelAndView.addObject("itemsList", itemsList);
       //指定视图
        modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
      return modelAndView;
    }
}
View Code

五、在spring容器中加载Handler,采用以下方式,不要单个设置

<context:component-scan base-package="cn.itcast.ssm.controller" />

六、访问:http://localhost:8080/springmvcfirst1208/queryItems.action便可.

ps:一个小细节能够在springmvc.xml中配置视图解析器配置前缀和后缀:

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <!-- 配置jsp路径的前缀 -->
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <!-- 配置jsp路径的后缀 -->
    <property name="suffix" value=".jsp"/>
</bean>
View Code

这样在Handler中指定视图时能够简化为以下:

modelAndView.setViewName("items/itemsList");

3、源码分析 略,结合struts2原理和以前的画图不难分析.

4、mybatis、springMVC整合

一、导入所须要的jar包:数据库驱动包:mysql驱动包、mybatis包、mybatis和spring整合包、log4j包、dbcp数据库链接池包、spring全部jar包、jstl包.

二、整合dao,配置sqlMapConfig.xml:

<?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配置,根据须要添加 -->
    <!-- 数据源和mapper映射交由spring配置 -->
    <!-- 配置别名 -->
    <typeAliases>
        <!-- 针对单个别名定义不推荐  -->
        <!-- 批量别名定义  mybatis自动扫描包中的po类,别名就是类名(首字母大写或小写均可以)-->
        <package name="cn.itcast.mybatis.po"/>
    </typeAliases>
</configuration>
View Code

三、配置spring dao层配置文件applicationContext-dao.xml,配置以下内容:数据源、SqlSessionFactory、mapper扫描器:

<beans dtd省略>
    <!-- 加载db.properties文件中的内容-->
    <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="30" />
        <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.itcast.ssm.mapper"></property>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
    </bean>  
</beans>
View Code

四、生成po类、mapper.java及mapper.xml(同一目录下).

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

<?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.itcast.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.itcast.ssm.po.ItemsQueryVo"
           resultType="itemsCustom">
          SELECT items.* FROM items  
          <where>
              <include refid="query_items_where"></include>
          </where>
      </select>
</mapper>
View Code

五、整合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);
    }
}
View Code

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

<beans dtd省略>
    <!-- 扫描service -->
    <context:component-scan base-package="cn.itcast.ssm.service" />
</beans>
View Code

七、service层事务控制(applicationContext-transaction.xml)

<beans dtd省略>
    <!-- 事务管理器对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="insert*" propagation="REQUIRED" />
            <tx:method name="update*" propagation="REQUIRED" />
            <tx:method name="find*" propagation="SUPPORTS" read-only="true" />
            <tx:method name="get*" propagation="SUPPORTS" read-only="true" />
            <tx:method name="select*" propagation="SUPPORTS" read-only="true" />
        </tx:attributes>
    </tx:advice>
    
    <!-- aop -->
    <aop:config>
        <aop:advisor advice-ref="txAdvice"
            pointcut="execution(* cn.itcast.ssm.service.impl.*.*(..))" />
    </aop:config>
</beans>
View Code

八、整合springmvc,编辑springmvc.xml文件.

<beans dtd省略>
    <!-- 扫描controller-->
    <context:component-scan base-package="cn.itcast.ssm.controller" />
    <mvc:annotation-driven />
</beans>
View Code

九、编写Controller

public class ItemsController {

    @Autowired
    private ItemsService itemsService;

    // 商品查询
    @RequestMapping("/queryItems")
    public ModelAndView queryItems(HttpServletRequest request) throws Exception {
        // 调用service查找 数据库,查询商品列表
        List<ItemsCustom> itemsList = itemsService.findItemsList(null);
        
        // 返回ModelAndView
        ModelAndView modelAndView = new ModelAndView();
        // 至关 于request的setAttribut,在jsp页面中经过itemsList取数据
        modelAndView.addObject("itemsList", itemsList);

        // 指定视图
        // 下边的路径,若是在视图解析器中配置jsp路径的前缀和jsp路径的后缀,修改成
        // modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
        // 上边的路径配置能够不在程序中指定jsp路径的前缀和jsp路径的后缀
        modelAndView.setViewName("items/itemsList");
        
        return modelAndView;
    }
}
View Code

十、配置前端控制器并在加载web应用时,加载spring配置文件.

<?xml version="1.0" encoding="UTF-8"?>
<beans dtd省略>
    <display-name>springmvc_mybatis1208</display-name>

    <!-- 加载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>

    <!-- springmvc前端控制器 -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/springmvc.xml</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>*.action</url-pattern>
    </servlet-mapping>
</web-app>
View Code

十一、测试:http://localhost:8080/springmvc_mybatis1208/queryItems.action

5、@RequestMapping

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

一、窄化请求映射

@Controller
//为了对url进行分类管理 ,能够在这里定义根路径,最终访问url是根路径+子路径
//好比:商品列表:/items/queryItems.action
@RequestMapping("/items")
public class ItemsController {
    // 商品查询
    @RequestMapping("/queryItems")
...
View Code

二、限制http请求方法

出于安全性考虑,对http的连接进行方法限制.若是限制请求为post方法,进行get请求,报错.

@RequestMapping("/queryItems" method={RequestMethod.POST})

6、controller方法的返回值

一、返回ModelAndView

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

二、返回string

1>表示返回逻辑视图名.真正视图(jsp路径)=前缀+逻辑视图名+后缀

@RequestMapping(value="/editItems",method={RequestMethod.POST})
public String editItems(Model model)throws Exception {
    
    //调用service根据商品id查询商品信息
    ItemsCustom itemsCustom = itemsService.findItemsById(1);
    
    //经过形参中的model将model数据传到页面
    //至关于modelAndView.addObject方法
    model.addAttribute("itemsCustom", itemsCustom);
    
    return "items/editItems";
}
View Code

2>redirect重定向

return "redirect:queryItems.action";

3>forward页面转发

return "forward:queryItems.action";

三、返回void

在controller方法形参上能够定义request和response,使用request或response指定响应结果(感受就是和servlet同样):

1>使用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串");

7、参数绑定

一、从客户端请求key/value数据,通过参数绑定,将key/value数据绑定到controller方法的形参上.springmvc中,接收页面提交的数据是经过方法形参来接收.而不是在controller类定义成员变动接收,与struts巨大区别!!!!

二、处理器适配器调用springmvc提供参数绑定组件将key/value数据转成controller方法的形参,参数绑定组件:converter(进行任意类型的传换),spirngmvc提供了不少converter(转换器),在特殊状况下须要自定义converter,如对日期绑定.

三、默认支持的类型,直接在controller方法形参上定义下边类型的对象,就可使用这些对象.

1>HttpServletRequest,经过request对象获取请求信息.
2>HttpServletResponse,经过response处理响应信息.
3>HttpSession,经过session对象获得session中存放的对象.
4>Model,将model数据填充到request域.

四、简单类型绑定(@RequestParam)

1>若是不使用@RequestParam,要求request传入参数名称和controller方法的形参名称一致,方可绑定成功.若是使用@RequestParam,不用限制request传入参数名称和controller方法的形参名称一致.

2>经过required属性指定参数是否必需要传入,若是设置为true,没有传入参数,报错.

3>经过defaultValue能够设置默认值,若是id参数没有传入,将默认值和形参绑定.

@RequestMapping(value="/editItems",method={RequestMethod.POST,RequestMethod.GET})
public String editItems(Model model,@RequestParam(value="id",required=true,defaultValue=1) Integer items_id){

ps:能够传入多个,写法同样,逗号分隔便可.

五、pojo绑定

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

//pojo类
public class Items {
    private Integer id;
    private String name;
    private Float price;
    ...
}

<%--jsp--%>
<input type="hidden" name="id" value="${itemsCustom.id }"/>
<tr>
    <td>商品名称</td>
    <td><input type="text" name="name" value="${itemsCustom.name }"/></td>
</tr>
<tr>
    <td>商品价格</td>
    <td><input type="text" name="price" value="${itemsCustom.price }"/></td>
</tr>

//商品信息修改提交
@RequestMapping("/editItemsSubmit")
public String editItemsSubmit(HttpServletRequest request,Integer id,Items items)throws Exception {
View Code

须要说明的是:简单类型的参数绑定和pojo参数绑定互不影响,也就是上面editItemsSubmit中的形参id和items都会被赋值,不冲突.

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

对于controller形参中pojo对象,若是属性中有日期类型,须要自定义参数绑定.因此自定义参数绑定将日期串转成java.util.Date类型.须要向处理器适配器中注入自定义的参数绑定组件:

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();
        }
        return null;
    }
}

View Code

<!--springmvc.xml -->
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>

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

View Code

七、包装类型参数绑定,也就是pojo中有pojo,经过"."便可绑定.

八、数组绑定

九、list绑定

十、map绑定

Public class QueryVo {
private Map<String, Object> itemInfo = new HashMap<String, Object>();
  //get/set方法..
}

<tr>
<td>学生信息:</td>
<td>
姓名:<inputtype="text"name="itemInfo['name']"/>
年龄:<inputtype="text"name="itemInfo['price']"/>
.. .. ..
</td>
</tr>

public String useraddsubmit(Model model,QueryVo queryVo)throws Exception{
  System.out.println(queryVo.getStudentinfo());
}
View Code

十一、传递数据时的乱码问题

1>post乱码在web.xml添加post乱码filter:

<!-- post乱码过虑器 -->
<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>
View Code

2>对于get请求中乱码解决方法有两个:

一、修改tomcat中间件配置文件添加编码与工程编码一致,以下:

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

二、另一种方法对参数进行从新编码:

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

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

8、springmvc和struts2的区别

一、springmvc基于方法开发的,struts2基于类开发的.springmvc将url和controller方法映射.映射成功后springmvc生成一个Handler对象,对象中只包括了一个method.方法执行结束,形参数据销毁.

二、springmvc能够进行单例开发,而且建议使用单例开发,struts2经过类的成员变量接收参数,没法使用单例,只能使用多例.(缘由是spring中是没有成员变量的只有方法,struts2中有成员变量,springmvc线程之间互不冲突).

三、通过实际测试,struts2速度慢,在于使用struts标签,若是使用struts建议使用jstl.

四、springmvc安全性高于strtus2,struts2常常报出各类高危漏洞.

五、struts2感受比springMVC乱不少,由于使用成员变量来接受参数,方法不少时,彻底不清楚哪一个方法用了哪些成员变量,而springMVC采用形参接受的话很是清晰.

9、springmvc校验

一、项目中,一般使用较可能是前端的校验,好比页面中js校验.对于安全要求较高点建议在服务端进行校验.

二、服务端校验:

1>控制层conroller:校验页面请求的参数的合法性.在服务端控制层conroller校验,不区分客户端类型(浏览器、手机客户端、远程调用)

2>业务层service(使用较多):主要校验关键业务参数,仅限于service接口中使用的参数.

3>持久层dao:通常是不校验的.

三、应用:页面提交请求的参数,请求到controller方法中,使用validation进行校验.若是校验出错,将错误信息展现到页面.

1>采用的可是hibernate的校验框架,导包

2>springmvc.xml中配置校验器

3>校验器注入处处理器适配器中

4>在pojo中添加校验规则

5>在CustomValidationMessages.properties配置校验错误信息:

6>捕获校验错误信息

//在须要校验的pojo前边添加@Validated,在须要校验的pojo后边添加BindingResult bindingResult接收校验出错信息

//注意:@Validated和BindingResult bindingResult是配对出现,而且形参顺序是固定的(一前一后).

7>在页面显示校验错误信息

8>分组校验

需求:在pojo中定义校验规则,而pojo是被多个 controller所共用,当不一样的controller方法对同一个pojo进行校验,可是每一个controller方法须要不一样的校验.

解决方法:定义多个校验分组(实际上是一个java接口),分组中定义有哪些规则,每一个controller方法使用不一样的校验分组.

 

10、数据回显

提交后,若是出现错误,将刚才提交的数据回显到刚才的提交页面.

一、springmvc默认对pojo数据进行回显.

pojo数据传入controller方法后,springmvc自动将pojo数据放到request域,key等于pojo类型(首字母小写),使用@ModelAttribute指定pojo回显到页面在request中的key.

二、@ModelAttribute还能够将方法的返回值传到页面

三、使用最简单方法使用model,简单类型回显采用这种,能够不用@ModelAttribute.

11、异常处理

一、系统中异常包括两类:预期异常和运行时异常RuntimeException,前者经过捕获异常从而获取异常信息,后者主要经过规范代码开发、测试经过手段减小运行时异常的发生.

二、系统的dao、service、controller出现都经过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理.

三、springmvc提供全局异常处理器(一个系统只有一个异常处理器)进行统一异常处理.

四、步骤:

1>自定义异常类

2>全局异常处理器,springmvc提供一个HandlerExceptionResolver接口

全局异常处理器处理思路:一、解析出异常类型二、若是该异常类型是系统 自定义的异常,直接取出异常信息,在错误页面展现.三、若是该异常类型不是系统自定义的异常,构造一个自定义的异常类型(信息为"未知错误").

public class CustomExceptionResolver implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex) {
        //handler就是处理器适配器要执行Handler对象(只有method)
        CustomException customException = null;
        if(ex instanceof CustomException){
            customException = (CustomException)ex;
        }else{
            customException = new CustomException("未知错误");
        }
        //错误信息
        String message = customException.getMessage();
        ModelAndView modelAndView = new ModelAndView();
        //将错误信息传到页面
        modelAndView.addObject("message", message);
        //指向错误页面
        modelAndView.setViewName("error");
        return modelAndView;
    }
}
View Code

三、错误页面

四、在springmvc.xml配置全局异常处理器

五、在商品修改的controller方法中抛出异常

六、在service接口中抛出异常

ps:若是与业务功能相关的异常,建议在service中抛出异常.与业务功能没有关系的异常,建议在controller中抛出.上边的功能,建议在service中抛出异常.

12、上传图片

一、加入上传图片的jar

二、在页面form中提交enctype="multipart/form-data"的数据时,须要springmvc对multipart类型的数据进行解析.在springmvc.xml中配置multipart类型解析器.

三、建立图片虚拟目录存储图片

图形界面配置: