接下来开始写程序:
部署调试:
非注解的处理器映射器和处理器适配器
修改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 ">
<bean id="itemsController1" name="/queryItems.action" class="cn.itcast.ssm.controller.ItemsController1" />
<bean id="itemsController2" class="cn.itcast.ssm.controller.ItemsController2" />
<bean
class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
<bean
class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/queryItems1.action">itemsController1prop>
<prop key="/queryItems2.action">itemsController1prop>
props>
property>
bean>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
bean>
beans>
测试:
由此可见:多个映射器可以并存,前端控制器判断url能让哪些映射器映射,就让正确的映射器处理
package cn.itcast.ssm.controller;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.HttpRequestHandler;
import org.springframework.web.servlet.ModelAndView;
import cn.itcast.ssm.po.Items;
public class ItemsController2 implements HttpRequestHandler {
@Override
public void handleRequest(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
//调用service查找 数据库,查询商品列表,这里使用静态数据模拟
List itemsList = new ArrayList();
//向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串");*/
}
}
注解的处理器映射器和处理器适配器
在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注解适配器。
开发注解Handler
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;
import cn.itcast.ssm.po.Items;
//使用Controller标识 它是一个控制器
@Controller
public class ItemsController3 {
//注解开发Handler
//商品查询列表
//@RequestMapping实现 对queryItems方法和url进行映射,一个方法对应一个url
//一般建议将url和方法写成一样
@RequestMapping("/queryItems")
public ModelAndView queryItems()throws Exception{
//调用service查找 数据库,查询商品列表,这里使用静态数据模拟
List itemsList = new ArrayList();
//向list中填充静态数据
Items items_1 = new Items();
items_1.setName("联想笔记本3");
items_1.setPrice(6000f);
items_1.setDetail("ThinkPad T430 联想笔记本电脑!3");
Items items_2 = new Items();
items_2.setName("苹果手机3");
items_2.setPrice(5000f);
items_2.setDetail("iphone6苹果手机!3");
itemsList.add(items_1);
itemsList.add(items_2);
//返回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;
}
//定义其它的方法
//商品添加
//商品修改
}
<context:component-scan base-package="cn.itcast.ssm.controller">context:component-scan>
前端控制器配置:
处理器映射器:
入门程序源代码下载 密码: msiy
开发环境
之后我会上传源码。
controller方法的返回值
返回void
在controller方法形参上可以定义request和response,使用request或response指定响应结果:
使用request转向页面,如下:
也可以通过response页面重定向:
也可以通过response指定响应结果,例如响应json数据如下:
参数绑定(简单类型,pojo)
自定义参数绑定实现日期类型绑定(掌握)
包装类中定义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>
Contrller方法定义如下:
public String useraddsubmit(Model model,QueryVo queryVo)throws Exception{
System.out.println(queryVo.getStudentinfo());
}
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
//handler就是处理器适配器要执行Handler对象(只有method)
// 解析出异常类型
// 如果该 异常类型是系统 自定义的异常,直接取出异常信息,在错误页面展示
// String message = null;
// if(ex instanceof CustomException){
// message = ((CustomException)ex).getMessage();
// }else{
//// 如果该 异常类型不是系统 自定义的异常,构造一个自定义的异常类型(信息为“未知错误”)
// message="未知错误";
// }
//上边代码变为
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、dao中任意一处需要手动抛出异常。
如果是程序中手动抛出的异常,在错误页面中显示自定义的异常信息,如果不是手动抛出异常说明是一个运行时异常,在错误页面只显示“未知错误”。
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">bean>
list>
property>
bean>
什么是RESTful
RESTful(即Representational State Transfer的缩写)其实是一个开发理念,是对http的很好的诠释。
2、http的方法规范
3、对http的contentType规范
定义配置
拦截定义
public class HandlerInterceptor1 implements HandlerInterceptor {
//进入 Handler方法之前执行
//用于身份认证、身份授权
//比如身份认证,如果认证通过表示当前用户没有登陆,需要此方法拦截不再向下执行
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
//return false表示拦截,不向下执行
//return true表示放行
return false;
}
//进入Handler方法之后,返回modelAndView之前执行
//应用场景从modelAndView出发:将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一指定视图
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
//执行Handler完成执行此方法
//应用场景:统一异常处理,统一日志处理
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
}
拦截配置
针对HandlerMapping配置:
springmvc拦截器针对HandlerMapping进行拦截设置,如果在某个HandlerMapping中配置拦截,经过该 HandlerMapping映射成功的handler最终使用该 拦截器。
class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="handlerInterceptor1"/>
<ref bean="handlerInterceptor2"/>
list>
property>
id="handlerInterceptor1" class="springmvc.intercapter.HandlerInterceptor1"/>
id="handlerInterceptor2" class="springmvc.intercapter.HandlerInterceptor2"/>
一般不推荐使用。
类似全局的拦截器
springmvc配置类似全局的拦截器,springmvc框架将配置的类似全局的拦截器注入到每个HandlerMapping中。
多拦截器测试
编写两个拦截器
两个拦截器都放行
HandlerInterceptor1…preHandle
HandlerInterceptor2…preHandle
HandlerInterceptor2…postHandle
HandlerInterceptor1…postHandle
HandlerInterceptor2…afterCompletion
HandlerInterceptor1…afterCompletion
总结:
preHandle方法按顺序执行,
postHandle和afterCompletion按拦截器配置的逆向顺序执行。
拦截器1放行,拦截器2不放行
HandlerInterceptor1…preHandle
HandlerInterceptor2…preHandle
HandlerInterceptor1…afterCompletion
总结:
拦截器1放行,拦截器2 preHandle才会执行。
拦截器2 preHandle不放行,拦截器2 postHandle和afterCompletion不会执行。
只要有一个拦截器不放行,postHandle不会执行。
拦截器1不放行,拦截器2不放行
HandlerInterceptor1…preHandle
拦截器1 preHandle不放行,postHandle和afterCompletion不会执行。
拦截器1 preHandle不放行,拦截器2不执行。
小结
根据测试结果,对拦截器应用。
比如:统一日志处理拦截器,需要该 拦截器preHandle一定要放行,且将它放在拦截器链接中第一个位置。
比如:登陆认证拦截器,放在拦截器链接中第一个位置。权限校验拦截器,放在登陆认证拦截器之后。(因为登陆通过后才校验权限)
捕获校验错误信息
在需要校验的pojo前边添加@Validated,在需要校验的pojo后边添加BindingResult bindingResult接收校验出错信息
注意:@Validated和BindingResult bindingResult是配对出现,并且形参顺序是固定的(一前一后)。