课程安排: 第一天: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、拦截器
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>
三、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; } }
五、在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>
这样在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>
三、配置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>
四、生成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>
五、整合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); } }
六、在spring容器配置service(applicationContext-service.xml)

<beans dtd省略> <!-- 扫描service --> <context:component-scan base-package="cn.itcast.ssm.service" /> </beans>
七、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>
八、整合springmvc,编辑springmvc.xml文件.

<beans dtd省略> <!-- 扫描controller--> <context:component-scan base-package="cn.itcast.ssm.controller" /> <mvc:annotation-driven /> </beans>
九、编写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; } }
十、配置前端控制器并在加载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>
十一、测试:http://localhost:8080/springmvc_mybatis1208/queryItems.action
5、@RequestMapping
定义controller方法对应的url,进行处理器映射使用.
一、窄化请求映射

@Controller
//为了对url进行分类管理 ,能够在这里定义根路径,最终访问url是根路径+子路径
//好比:商品列表:/items/queryItems.action
@RequestMapping("/items")
public class ItemsController {
// 商品查询
@RequestMapping("/queryItems")
...
二、限制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"; }
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 {
须要说明的是:简单类型的参数绑定和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()); }
十一、传递数据时的乱码问题
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>
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; } }
三、错误页面
四、在springmvc.xml配置全局异常处理器
五、在商品修改的controller方法中抛出异常
六、在service接口中抛出异常
ps:若是与业务功能相关的异常,建议在service中抛出异常.与业务功能没有关系的异常,建议在controller中抛出.上边的功能,建议在service中抛出异常.
12、上传图片
一、加入上传图片的jar
二、在页面form中提交enctype="multipart/form-data"的数据时,须要springmvc对multipart类型的数据进行解析.在springmvc.xml中配置multipart类型解析器.
三、建立图片虚拟目录存储图片
图形界面配置: