Spring MVC 入门

1、发起请求到前端控制器(DispacherServlet)

2、前端控制器请求HandlerMapping查找Handler

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

3、处理器映射器HandlerMapping向前端控制器返回Handler

4、前端控制器调用处理器适配器执行Handler

5、处理器适配器执行Handler

6、Hanler执行完向适配器返回ModelAndView

7、处理器适配器向前端控制器返回ModelAndView

8、前端控制器请求视图解析器进行视图解析

9、视图解析器向前端控制器返回View

10、前端控制器进行视图渲染

11、前端控制器向用户响应结果

二、SpringMVC环境搭建

1、建立如下目录

2、导入和spring相关的jar包

3、在web.xml文件中配置SpringMVC前端控制器

<!-- 配置前端控制器DispatcherServlet -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 初始化参数配置
        contextConfigLocation配置springmvc加载的配置文件(配置HandlerMapping、HandlerAdapter)
         如果不配置contextConfigLocation,默认加载的是/WEB-INF/servlet名称-servlet.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解析,对于静态文件需要配置不让其解析
        第三种:/*,struts习惯使用,springmvc不管用,使用这种配置,最终要转发到一个jsp页面时,
                仍然由DispatcherServlet解析jsp地址,不能根据jsp地址转到Handler,会报错
        -->
        <url-pattern>*.action</url-pattern>
    </servlet-mapping>

 4、在创建的springmvc.xml中配置HandlerMapping(C)、HandlerAdapter(M)、ViewResolver(V)

    <!-- 配置Handler -->
    <bean name="/itemController.action" class="cn.itcast.ssm.controller.ItemController"></bean>
    
    <!-- 简单控制器处理器适配器 (HandlerAdapter)
        所有的适配器都实现HandlerAdapter接口
    -->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>

    <!-- 配置处理器映射器 (HandlerMapping)
        将Handler(Controller)的Bean的name作为url进行查找,需要在配置Handler时指定name
        public class org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter 
                                implements org.springframework.web.servlet.HandlerAdapter 
        {
             public boolean supports(java.lang.Object handler);
        }
    -->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
    
    <!-- 配置视图解析器(ViewResover),这里解析默认用jstl标签,所以注意:classpath下面是否导入jstl相关包-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"></bean>

5、编写名叫ItemController的Handler

package cn.itcast.ssm.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class ItemController implements Controller {

    @Override
    public ModelAndView handleRequest(HttpServletRequest arg0,
            HttpServletResponse arg1) throws Exception {

List list = new ArrayList();

          ModelAndView modelAndView = new ModelAndView();
          modelAndView.addObject("itemList",list);
          modelAndView.setViewName("/WEB-INF/jsp/jsp1/index.jsp");

          return modelAndView;

    }
}

三、使用非注解的HandlerAdapter和HandlerMapping

1、HandlerMapping

<!-- ================非注解的HandlerMapping ================= -->
    <!-- 
    第一种:<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
    第二种:<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"></bean>
--> <bean id="itemController" name="/itemController.action" class="cn.itcast.ssm.controller.ItemController"></bean> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mapping"> <props> <!--<prop key="/***.action">controller的bean的Id</prop>--> <prop key="/itemController1.action">itemController</prop> <prop key=""></prop> </props> </property> </bean>
多个映射器可以并存,例如:/itemController.action,/itemController1.action指向同一个Bean,但此时两个地址都可以正常访问。

2、HandlerAdapter

<!-- ================非注解的HandlerAdapter ================= -->
    <!-- 
    第一种:<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>
      要求Handler/Controller的Bean实现Controller接口 第二种:<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"></bean> 要求Handler/Controller实现org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter接口 --> <bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"></bean> <bean id="itemController2" class="cn.itcast.ssm.controller.ItemController2"></bean> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mapping"> <props> <!--<prop key="/***.action">controller的bean的Id</prop>--> <prop key="/itemController1.action">itemController</prop> <prop key="/itemController2.action">itemController2</prop> </props> </property> </bean>

ItemController.java源文件,如图

以上Handler中有一个弊端,就是一个Handler(Controller)中只有一个方法。

 四、注解的HandlerAdapter和HandlerMapping

在spring3.1之后才使用下面的注解

添加注解驱动配置

    <!-- ================注解的HandlerAdapter ================= -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.class"></bean>
    <!-- ================注解的HandlerMapping ================= -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.class"></bean>

这里的代码在程序开发时,通常会用下面的代码替换
  <!-- springmvc 注解驱动,配置下面这行代码,上面两行代码不再需要配置 -->
    <mvc:annotation-driven />

创建Controller名叫ItemController3.java

package cn.itcast.ssm.controller;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class ItemController3 {
    
    //这里的url可以为"/queryItems","/queryItems.action"
    @RequestMapping("/queryItems")
    public ModelAndView queryItems(){
        List list = new ArrayList();
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("itemList", list);
        return modelAndView;
    }
}

添加组件扫描Controller的配置文件

<!-- 这里使用组件扫描controller包,以后还可以扫描Service....等 -->
    <context:component-scan base-package="cn.itcast.ssm.controller" />

 五、视图解析器

为了简化  modelAndView.setViewName("/WEB-INF/jsp/jsp1/index.jsp"); 地址,采用前缀和后缀

用下面代码替换前面的视图解析器的配置

<!-- 配置视图解析器(ViewResover) -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/jsp/jsp1/"/>
    <property name="suffix" value=".jsp"/>
</bean>

 六、SpringMVC整合MyBatis

面试题:在SpringMVC中spring的作用是什么?

  Spring将SpringMVC的各层进行整合

  1、spring对持久层的Mapper接口进行管理

  2、spring对业务层的Service进行管理,可以调用Mapper接口

  3、spring对表现层的Handler进行管理,可以调用Service

  4、Spring在业务层进行事务处理。

具体步骤如下:

1、整合DAO层

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

使用Mapper扫描器自动扫描包

2、整合Service层

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

3、整合Springmvc,由于它是Spirng的模块,所以不需要整合。

sringmvc.xml配置文件部分如下:

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"  
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"  
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task"  
    xmlns:aop="http://www.springframework.org/schema/aop"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans    
                        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd    
                        http://www.springframework.org/schema/context    
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd  
                        http://www.springframework.org/schema/mvc    
                        http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd  
                        http://www.springframework.org/schema/tx  
                        http://www.springframework.org/schema/tx/spring-tx-3.1.xsd  
                        http://www.springframework.org/schema/task  
                        http://www.springframework.org/schema/task/spring-task-3.1.xsd  
                        http://www.springframework.org/schema/aop  
                        http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">  
  
    <context:annotation-config />  
  
    <context:component-scan base-package="cn.com"  />  
  
    <tx:annotation-driven transaction-manager="transactionManager" />  
  
    <mvc:annotation-driven />  
  
    <aop:aspectj-autoproxy proxy-target-class="true" />  
  
    <!-- annotation的方法映射适配器 -->  
    <bean id="handlerAdapter"  
        class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />  
    <!-- annotation默认的方法映射适配器 -->  
<!--     <bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> -->  
<!--     <property name="order" value="1" /> -->  
<!--     </bean> -->  
  
    <!-- 静态文件 -->  
    <mvc:resources location="/assets/" mapping="/assets/**"></mvc:resources>  
  
    <!-- 跳转文件的前后缀 -->  
    <bean  
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
        <property name="prefix" value="/WEB-INF/view/"></property>  
        <property name="suffix" value=".jsp"></property>  
    </bean>  
  
    <!-- ================mvc ================= -->  
  
  
    <!-- ==================spring context=============== -->  
    <!-- 引入配置文件 -->  
    <bean id="propertyConfigurer"  
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
        <property name="locations">  
            <list>  
                <value>WEB-INF/conf/jdbc.properties</value>  
                <!-- <value>WEB-INF/conf/conf.properties</value> -->  
            </list>  
        </property>  
    </bean>  
  
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"  
        destroy-method="close">  
        <property name="driverClassName" value="${driver}" />  
        <property name="url" value="${url}" />  
        <property name="username" value="${username}" />  
        <property name="password" value="${password}" />  
        <!-- 初始化连接大小 -->  
        <property name="initialSize" value="${initialSize}"></property>  
        <!-- 连接池最大数量 -->  
        <property name="maxActive" value="${maxActive}"></property>  
        <!-- 连接池最大空闲 -->  
        <property name="maxIdle" value="${maxIdle}"></property>  
        <!-- 连接池最小空闲 -->  
        <property name="minIdle" value="${minIdle}"></property>  
        <!-- 获取连接最大等待时间 -->  
        <property name="maxWait" value="${maxWait}"></property>  
    </bean>  
  
    <!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->  
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
        <property name="dataSource" ref="dataSource" />  
        <!-- 自动扫描mapping.xml文件 -->  
        <property name="mapperLocations" value="classpath:mapper/*.xml"></property>  
    </bean>  
  
    <bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">  
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>  
        <property name="basePackage" value="cn.com.**.dao" />  
        <property name="properties">  
            <value>mappers=cn.com.common.ssm.engine.mapper.BaseDao</value>  
        </property>  
    </bean>  
  
  
<!--     (事务管理)transaction manager, use JtaTransactionManager for global tx -->  
    <bean id="transactionManager"  
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
        <property name="dataSource" ref="dataSource" />  
    </bean>  

      <!-- 通知,限定业务层Service的方法名必须以下面的开头,并通知给事务管理器 -->
     <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:attributes>
     </tx:advice>

    <!-- aop配置,因为AOP要调用通知
     execution(* cn.itcast.ssm.service.impl.*.*(..)),表示 
    按照cn.itcast.ssm.service.impl所有的类名所有的方法名,(..)表示不管什么参数
    -->
   <aop:config>
      <aop:advisor advice-ref="txAdvice" pointcut="execution(* cn.itcast.ssm.service.impl.*.*(..))"/>
   </aop:config>

  
    <!-- shiro -->  
  
    <bean id="myRealm" class="cn.com.security.shiro.CustomRealm" />  
  
    <!-- 安全管理器 -->  
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
        <property name="realm" ref="myRealm" />  
    </bean>  
  
    <!-- Shiro过滤器 -->  
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
        <!-- Shiro的核心安全接口,这个属性是必须的 -->  
        <property name="securityManager" ref="securityManager" />  
        <!-- 身份认证失败,则跳转到登录页面的配置 -->  
        <property name="loginUrl" value="login.do" />  
        <!-- 权限认证失败,则跳转到指定页面 -->  
        <property name="unauthorizedUrl" value="/unauthor.jsp" />  
        <!-- Shiro连接约束配置,即过滤链的定义 -->  
        <property name="filterChainDefinitions">  
            <value>  
                /login.do=anon  
                /**/*.do=authc  
            </value>  
        </property>  
    </bean>  
  
    <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->  
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />  
  
    <!-- 开启Shiro注解 -->  
<!--     <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor" /> -->  
<!--     <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> -->  
<!--         <property name="securityManager" ref="securityManager" /> -->  
<!--     </bean> -->  
  
</beans>  

在web.xml中配置前端控制器和加载Spring容器

<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">
    
    <!-- 前端控制器 -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 初始化参数配置
        contextConfigLocation配置springmvc加载的配置文件(配置HandlerMapping、HandlerAdapter)
         如果不配置contextConfigLocation,默认加载的是/WEB-INF/servlet名称-servlet.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解析,对于静态文件需要配置不让其解析
        第三种:/*,struts习惯使用,springmvc不管用,使用这种配置,最终要转发到一个jsp页面时,
                仍然由DispatcherServlet解析jsp地址,不能根据jsp地址转到Handler,会报错
        -->
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
    
    <!-- 加载Spring容器 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/Classes/spring/application-*.xml</param-value>
    </context-param>
    
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
</web-app>

 七、注解列举、参数绑定

1、@RequestMapping(),请求映射

特性:url映射,限制请求方式

@RequestMapping("/editItems")
@RequestMapping(value="/editItems",method = RequestMethod.GET)
@RequestMapping(value="/editItems",method = {RequestMethod.GET,RequestMethod.POST})

2、Controller方法的返回值

第一种:ModelAndView , model和View需要分别设置

ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("itemCustom",itemCustom);
modelAndView.setViewName("/WEB-INF/jsp/jsp1/editItem.jsp");

第二种:string,表示返回的是逻辑视图名,真正的视图名:jsp路径 + 前缀+视图名+后缀

@RequestMapping(value="/editItems",method={RequestMethod.GET,RequestMethod.POST})
    public String editItems(Model model) throws Exception{
        //通过方法的形参表示ModelAndView中的Model
        ItemCustom itemCustom = itemService.findItemById(1);
        model.addAttribute("itemCustom",itemCustom);
        return "/WEB-INF/jsp/jsp1/editItem.jsp";
    }

  页面重定向redirect

  特定:url地址发生改变、request不可以共享

@RequestMapping("/editItemSubmit")
    public String editItemSubmit(){
        //重定向,因为在同一controller中不需要添加绝对路径
        return "redirect:success.action";
    }

  页面转发forward

  特点:url地址不改变、request可以共享

@RequestMapping("/editItemSubmit")
    public String editItemSubmit(){
        //重定向,因为在同一controller中不需要添加绝对路径
        return "forward:success.action";
    }
 

第三种:void

在Controller方法的形参上定义request和response,使用它们指定相应结果:

@RequestMapping("/editItemSubmit")
    public String editItemSubmit(HttpServletRequest request, HttpServletResponse response){
        
        //request实现转发
        request.getRequestDispathcer("页面路径").forward(request,response);
        
        //request重定向
        request.sendRedirect("页面路径");
        
        //Response相应结果,例如:json
        response.setCharacterEncoding("utf-8");
        response.SetContentType("application/json;charset=utf-8");
        response.getWriter().write("json串");
        
    }

 3、参数绑定和参数绑定的组件Converter(转换器)

  • 默认支持的参数类型转换包含:

    1、HttpServletRequest

    2、HttpServletResponse

    3、HttpSession

    4、Model(接口)/  ModelMap(Model的实现类) :作用:将model数据填充到Request域

  • 自定义参数绑定,实现日期格式的绑定

    要求:自定义参数绑定要和pojo中的成员变量属性的类型保持一致

    步骤:1、在web.xml的注解驱动中添加如下代码       

<mvc:annotation-driven conversion-service="conversionService"/>

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

      2、创建自定义的Controller转换器并且实现org.springframework.core.convert.converter.Converter接口,例如:CustomDateConverter

package cn.itcast.ssm.controller;

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 arg0) {
        
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:sss");
        try {
            return simpleDateFormat.parse(arg0);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
}

4、简单类型

 @RequestParam,接收请求参数

public String editItemSubmit(@RequestParam("id") Integer item_id)

public String editItemSubmit(@RequestParam(value="id",required=true,defaultValue="1") Integer item_id)

5、pojo绑定,要求表单的name属性值必须和pojo的成员变量属性名保持一致。

6、@ModelAttribute

·· 1、做数据回显,如下:

//@ModelAttribute可以指定pojo回显到页面中的request的key,
    //这样页面显示调用方法:item.name,此时requst域中的key值不再必须是和pojo的类型(首字符小写)保持一致
    public String saveEmployeeAction(
            @ModelAttribute("item")
            @Validated(value={ValidationGroup1.class}) Item item,
            BindingResult bindingResult, Model model) {}

  2、将方法的返回值返回到页面

  

八、校验器的配置

  • 不同Controller中同一方法校验

  1、在Springmvc.xml文件中添加校验器的相关配置

  <mvc:annotation-driven validator="validator" />

    <!-- 校验器配置 
        在注解驱动中添加 validator="validator"
    -->
    <bean id="validator"
        class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
        <property name="providerClass" value="org.hibernate.validator.HibernateValidator" />
        <!--不设置则默认为classpath下的ValidationMessages.properties -->
        <property name="validationMessageSource" ref="validatemessageSource" />
    </bean>
<!--错误信息的配置文件--> <bean id="validatemessageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basename"> <list> <value>classpath:validatemessages</value> </list> </property> <property name="fileEncodings" value="utf-8" />
      <!--文件缓存时间--> <property name="cacheSeconds" value="120" /> </bean>

  2、创建错误信息文件validatemessages.properties添加错误信息 

#错误校验信息
item.name.length.error=请输入1-30的字符长度
item.name.isNull.error=不能为空

  3、在实体类的属性前面添加如下校验

  //验证字符长度
    @Size(min=1,max=30,message="{item.name.length.error}")
    //非空校验
    @NotNull(message="{item.name.isNull.error}")
    private String itemName;
Bean Validation 中内置的 constraint         
 2 @Null   被注释的元素必须为 null    
 3 @NotNull    被注释的元素必须不为 null    
 4 @AssertTrue     被注释的元素必须为 true    
 5 @AssertFalse    被注释的元素必须为 false    
 6 @Min(value)     被注释的元素必须是一个数字,其值必须大于等于指定的最小值    
 7 @Max(value)     被注释的元素必须是一个数字,其值必须小于等于指定的最大值    
 8 @DecimalMin(value)  被注释的元素必须是一个数字,其值必须大于等于指定的最小值    
 9 @DecimalMax(value)  被注释的元素必须是一个数字,其值必须小于等于指定的最大值    
10 @Size(max=, min=)   被注释的元素的大小必须在指定的范围内    
11 @Digits (integer, fraction)     被注释的元素必须是一个数字,其值必须在可接受的范围内    
12 @Past   被注释的元素必须是一个过去的日期    
13 @Future     被注释的元素必须是一个将来的日期    
14 @Pattern(regex=,flag=)  被注释的元素必须符合指定的正则表达式    
15     
16 Hibernate Validator 附加的 constraint    
17 @NotBlank(message =)   验证字符串非null,且长度必须大于0    
18 @Email  被注释的元素必须是电子邮箱地址    
19 @Length(min=,max=)  被注释的字符串的大小必须在指定的范围内    
20 @NotEmpty   被注释的字符串的必须非空    
21 @Range(min=,max=,message=)  被注释的元素必须在合适的范围内 

  4、在Controller中添加校验

@RequestMapping(value = "save", method = RequestMethod.POST)
    //在需要校验的pojo前添加@Validated注解,在后面添加BindingResult接收校验参数
    //@Validated和BindingResult是配对出现的并且位置是固定的,不能修改,多个参数需要校验,必须按照这样的位置处理
    public String saveEmployeeAction(@Validated Item item,
            BindingResult bindingResult, Model model) {
        
        //获取校验信息
        if (bindingResult.hasErrors()) {
            List<ObjectError> allErrors = bindingResult.getAllErrors();
            for(ObjectError objectError : allErrors){
                System.out.println(objectError.getDefaultMessage());
            }
            return "empSave";
        }
        model.addAttribute("allError", allErrors);
        return "empSaveSuccess";
    }

  5、jsp页面上进行遍历输出即可。

  • 分组校验,不同Controller采用不同方法校验

  1、新建接口文件

    目录结构如下:

  2、在javaBean修改为如下代码

//验证字符长度
    //groups表示校验属于哪个分组
    @Size(min=1,max=30,message="{item.name.length.error}",groups={ValidationGroup1.class})

  3、在Controller中指定使用哪个分组

public String saveEmployeeAction(@Validated(value={ValidationGroup1.class}) Item item,
            BindingResult bindingResult, Model model) {

 九、异常处理

1、自定义异常处理类CustomException

2、编写自定义异常解析器CustomExceptionResolver

package cn.itcast.ssm.exception;

import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

public class CustomExceptionResolver implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest request,
            HttpServletResponse response, Object arg2, Exception ex) {
        // TODO Auto-generated method stub
        //判断异常是否是自定义的异常
        CustomException customException = null;
        
        if(ex instanceof CustomException){
            
            ex = (CustomException)ex;
        }else{
            customException = new CustomException("未知错误");
        }
        String message = customException.getMessage();
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("message", message);
        modelAndView.setViewName("error");
        return null;
    }

}

3、配置全局异常处理器

<!-- 配置全局异常处理器 -->
    <bean class="cn.itcast.ssm.exception.CustomExceptionResolver"></bean>

 十、文件上传

  1、导入jar包

  2、在SpringMVC.xml文件中添加文件解析器的配置

<!-- 配置文件解析器,用于文件上传 -->
    <bean id="commonsMultipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 这里指定为5M -->
        <property name="maxUploadSize">
            <value>5242880</value>
        </property>
    </bean>

  3、在Controller中添加上传代码

//MultipartFile item_pic 绑定图片,用于上传图片
    public String saveEmployeeAction(
            @ModelAttribute("item")
            @Validated(value={ValidationGroup1.class}) Item item,
            BindingResult bindingResult, Model model
            ,MultipartFile item_pic) throws Exception, IOException {
        
        //获取校验信息
        if (bindingResult.hasErrors()) {
            List<ObjectError> allErrors = bindingResult.getAllErrors();
            for(ObjectError objectError : allErrors){
                System.out.println(objectError.getDefaultMessage());
            }
            return "empSave";
        }
        
        //获取文件名
        String originalFilename = item_pic.getOriginalFilename();
        //生成新的文件名
        String newFileName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf("."));
        
        //指定文件上传路径
        String filePath = "";
        
        File file = new File(filePath + newFileName);
        
        //上传文件,将内存数据写入到磁盘
        item_pic.transferTo(file);
        
        //修改数据库文件的路径,通过设置POJO类的属性完成
        //......
        
        model.addAttribute("emp", item);
        return "empSaveSuccess";
    }

十一、json解析

  1、导jar包       

  2、在SpringMVC.xml配置json转换器,如果用了mvc注解驱动,则可以不再配置一下的json转换器

<bean  
    class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"  
    p:ignoreDefaultModelOnRedirect="true">  
    <property name="messageConverters">  
        <list>  
            <bean  
                class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>  
        </list>  
    </property>  
</bean>  

  3、在形参起前面添加@RequestBody,在方法的返回类型前面添加@ResponseBody

十二、RestFul前端控制器配置

  • 对静态资源访问

十三、拦截器

  1、preHandle、postHandle、afterCompleted方法

  2、拦截器的配置

   3、拦截器的执行结果

    1、拦截器1、2都放行

2、拦截1放行、2不放行

    3、两个都不放行

 十四、乱码的解决方案

1、post乱码

  在web.xm中添加filter过滤器

<!-- 解决post乱码,添加过滤器 -->
    <filter>
        <filter-name>Encoding</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter.class</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>Encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

SpringMVC和Strus2的区别

  1、Springmvc 面向方法开发的,Struts2面向类开发的

  2、Springmvc是单例的,Struts2是多例开发的

  

 

posted @ 2018-01-12 17:41  无敌多么,无敌寂寞  阅读(175)  评论(0编辑  收藏  举报