springMVC
- 一个基于MVC设计模式的web框架
- 是属于spring框架的一个模块
基于restful 的web服务的实现
SpringMVC的运行结构
springMVC入门程序
- 导入类库:
非注解方式 (了解)
- 配置前端控制器 web.xml
<!-- 配置前端控制器 -->
<servlet>
<servlet-name>dispatcherServlet</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>dispatcherServlet</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
- 配置springmvc框架的核心配置文件
<!-- 非注解的controller -->
<bean name="/hello.action" class="com.gec.mvc.controller.HelloController"></bean>
<!-- 非注解的处理器映射器 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
<!-- 非注解的处理器适配器 -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
- 控制器类
//非注解的controller
public class HelloController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
//ModelAndView 表示 模型数据加视图
ModelAndView mv = new ModelAndView();
mv.addObject("msg", "hello springmvc!"); //在作用域中保存数据
mv.setViewName("index"); // 渲染的视图的逻辑名 前缀+index+ .jsp
return mv;
}
}
注解方式
- spring最简配置
<!--配置注解的处理器映射器和适配器 -->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 扫描包之下的类中的注解 -->
<context:component-scan base-package="com.gec.mvc.controller"></context:component-scan>
<!-- 视图解析器 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
- 注解的controller
@Controller
public class TestController {
@RequestMapping("/findUserName")
public ModelAndView findUserName() {
List<String> names = new ArrayList<>();
names.add("张三");
names.add("李四");
names.add("王五");
ModelAndView mv = new ModelAndView();
mv.addObject("names", names);
mv.setViewName("list");
return mv;
}
}
handler处理器的方法声明
1.方法的返回类型
- ModelAndView 表示模型数据和视图名
- String 表示返回视图逻辑名
- void 要通过HttpServletResponse输出http响应的内容(少用)
- 任意的自定义对象(pojo, 集合) (最常用 ) 用于json数据交互
- 资源的跳转方式: redirect: forward:
2.方法的参数列表的绑定
- 默认的原生接口 HttpServletRequest HttpServletResponse HttpSession
//默认的常用接口的注入
@RequestMapping("/getParam01")
public String getParam01(HttpServletRequest request,HttpServletResponse response,HttpSession session,Model model) {
session.setAttribute("Mike", "Mike in session scope.");
request.setAttribute("Mike", "Mike in request scope.");
model.addAttribute("Jack", "Jack in request scope.");
return "test";
}
- 简单类型数据(基本数据类型和字符串)
//默认所有的请求方法都可以访问
@RequestMapping(value="/getParam02",method=RequestMethod.POST)
public String getParam02(int id,String username){
System.out.println(id);
System.out.println(username);
return "test";
}
常见错误:
405 表示当前请求不支持指定的类型
参数列表注入失败(类型转换的问题)
@RequestParam注解
//@RequestParam 用于描述提交参数
@RequestMapping(value="/getParam03",method=RequestMethod.GET)
public String getParam03(
@RequestParam(value="pageNum",required=false,defaultValue="1") int pageNum){ //页码: 可以不提供,但是默认是第1页
System.out.println(pageNum);
return "test";
}
- 对象类型数据
jsp页面
<form action="register.action" method="post">
<p>
用户名:<input type="text" name="name"/>
</p>
<p>
密 码:<input type="password" name="password"/>
</p>
<p>
<input type="submit" value="提 交"/>
</p>
</form>
Handler方法
@RequestMapping(value="/register",method=RequestMethod.POST)
public String register(User user) {
System.out.println(user.getName());
System.out.println(user.getPassword());
return "test";
}
- 类型转换
(1) 系统的类型转换器
(2) 自定义类型转换器
实现一个日期类型格式化输出的转换器
public class DateConverter implements Converter<String, Date> {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
@Override
public Date convert(String time) {
try {
return sdf.parse(time);
} catch (ParseException e) {
e.printStackTrace();
}
return null; //不会报错,Date数据直接是null
//throw new IllegalArgumentException(); 报400错误
}
}
在springmvc.xml配置自定义类型转换器
<!-- 视图解析器 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="com.gec.mvc.utils.DateConverter" />
</list>
</property>
</bean>
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
Springmvc的Restful的访问(风格)链接
传统: http://localhost:8080/ssm-2037/items/loadAllItem.action?id=100&&name=Mike
Restful: http://localhost:8080/ssm-2037/items/loadAllItem/100/Mike/…
web.xml
<!-- 配置前端控制器 -->
<servlet>
<servlet-name>dispatcherServlet</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>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
注意:
- ‘/’ 表示不含后缀的路径
- ‘/*’ 表示所有的路径
springMVC拦截器
MVC框架的拦截的目标:主要针对handler(控制器)
作用:降低组件间的耦合度。
实现:
- 实现拦截器类
public class CheckUserInterceptor implements HandlerInterceptor {
//是在执行handler方法之前 运行
//true: 放行, 进入handler的方法 --->执行handler方法的业务逻辑--->postHandle()--->return语句--->afterCompletion()
//false: 不会执行handler方法
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String path = request.getRequestURI();
System.out.println(path);
if (path.indexOf("doLogin") != -1 || path.indexOf("register") != -1) {
return true;
}
HttpSession session = request.getSession();
if (session.getAttribute("user")!=null) { //用户已经登录
return true;
} else {
response.sendRedirect(request.getContextPath() + "/login.jsp");
return false;
}
}
//是在执行完handler方法之后运行(在执行return语句之前执行),渲染视图做拦截
//应用场景:需要修改ModelAndView时。
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse respnose, Object handler, ModelAndView mv)
throws Exception {
}
//是在执行完handler方法之后运行(在执行return语句之后执行)
//应用场景:获取了异常对象后做日志的记录
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
}
- 配置拦截器
<!-- 配置拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="cn.web.auction.interceptor.CheckUserInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
自定义全局异常处理器
- 先定义自定义业务的异常类
/**
* 商品竞价的异常
* @author gec
* */
public class AuctionPriceException extends Exception {
private String message;
public AuctionPriceException(String message) {
super(message);
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
- 实现HandlerExceptionResolver接口
public class CustomHandlerExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse respone, Object obj,
Exception ex) {
ModelAndView mv = new ModelAndView();
if (ex instanceof AuctionPriceException) {
//对应异常的业务操作
AuctionPriceException priceException = (AuctionPriceException) ex;
mv.addObject("errorMsg", priceException.getMessage());
mv.setViewName("error");
} else {
mv.addObject("errorMsg", "未知异常");
mv.setViewName("error");
}
return mv;
}
}
- 在springmvc的全局配置文件作配置
<bean class="com.gec.auction.utils.CustomHandlerExceptionResolver"></bean>