SpringMVC是什么?
是一个MVC框架,用来简化基于MVC架构的web应用开发。
五大组件
DispatcherServlet(前端控制器)
接受请求,依据HandlerMapping的配置调用相应的模型来处理。
HandlerMapping
包含了请求路径与模型的对应关系。
Controller
负责处理业务逻辑。
ModelAndView
封装了处理结果。
注:处理结果除了数据之外,还可能有视图名。
ViewResolver(视图解析器)
DispatcherServlet依据ViewResolver的解析,调用真正的视图对象来生成相应的页面。
注:五大组件的关系。
a、DispatcherServlet收到请求之后,依据HandlerMapping的配置,调用相应的Controller来处理。
b、Controller将处理结果封装成ModelAndView对象,然后返回给DispatcherServlet。
c、DispatcherServlet依据ViewResolver的解析,调用相应的视图对象(比如某个JSP)来生成相应的页面。
使用xml配置来开发基于springMVC的web应用
编程步骤
step1、导包。
step2、添加spring的配置文件。
step3、在web.xml中配置DispatcherServlet。
<?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" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<!--
DispatcherServlet在初始化方法里面,会读取该初始化参数的值来
获取spring配置文件的位置,然后启动spring容器。
-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
setp4、写Controller(处理器)。
public class HelloController implements Controller
{
public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception
{
System.out.println("HandleRequest()");
/**
* ModelAndView有两个构造器:
* (1)ModelAndView(String viewName),
* viewName是视图名。
* (2)ModelAndView(String viewName,Map data),
* Map用于封装处理结果数据。
*/
return new ModelAndView("hello");
}
}
step5、写jsp。
step6、在spring配置文件中,添加以下配置:
- HandlerMapping
- Controller
- ViewResolver
<!-- 配置HandlerMapping -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/hello.do">helloController</prop>
</props>
</property>
</bean>
<!-- 配置处理器 -->
<bean id="helloController" class="controller.HelloController"/>
<!-- 配置视图解析器ViewResolver组件 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/"/>
<property name="suffix" value=".jsp"/>
</bean>
使用注解来开发基于springMVC的web应用
编程步骤
step1、导包。
step2、添加spring的配置文件。
step3、配置DispatcherServlet。
step4、写Controller。
/**
* 如何写一个处理器:
* 1、不用实现Controller接口。
* 2、可以在处理类当中,添加多个方法,每个方法处理对应一种类型的请求。
* 3、方法名不做要求,返回类型可以是ModelAndView,也可以是String。
* 4、 使用@Controller,将该处理器纳入容器进行管理。(也就是说,spring配置文件不用配置该处理器了)。
* 5、使用@RequestMapping,告诉前端控制器(DispatcherServlet),请求路径与处理器的方法的对应关系,(spring配置文件不用配置HandlerMapping了)。
*
*/
@Controller
public class HelloControlller
{
@RequestMapping("/hello.do")
public String hello()
{
System.out.println("hello()");
return "hello";
}
}
step5、写jsp。
step6、在Spring配置文件中,添加如下配置:
- 组件扫描。
- MVC注解扫描。
- 视图解析器。
<!-- 配置组件扫描 -->
<context:component-scan base-package="controller"/>
<!-- 配置MVC注解扫描 -->
<mvc:annotation-driven/>
<!-- 配置视图解析器ViewResolver组件 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/"/>
<property name="suffix" value=".jsp"/>
</bean>
读取请求参数值
通过request对象
注:将request对象作为方法的入参即可。
@RequestMapping("/login.do")
//读取请求参数值得第一种方式:
//通过request对象。
public String login1(HttpServletRequest request)
{
System.out.println("login1()");
String adminCode = request.getParameter("admincode");
String pwd = request.getParameter("pwd");
System.out.println("adminCode:"+adminCode+"pwd:"+pwd);
return "index";
}
使用@RequestsParam注解
注:将该注解添加到方法的形参前面。
@RequestMapping("/login2.do")
//读取请求参数值得第二种方式:
//使用@RequestsParam注解。
public String login2(@RequestParam("admincode")String adminCode,@RequestParam("pwd")String pwd)
{
System.out.println("login2()");
System.out.println("adminCode:"+adminCode+"pwd:"+pwd);
return "index";
}
使用javabean封装请求参数值
step1、写一个Java类,要求属性名与请求参数名一致,并且提供相应的get,set方法。
step2、将该javabean作为方法的形参。
@RequestMapping("/login3.do")
//读取请求参数值得第三种方式:
//使用javabean封装请求参数。
public String login3(AdminParam ap)
{
System.out.println("login3()");
System.out.println("adminCode:"+ap.getAdmincode()+"pwd:"+ap.getPwd());
return "index";
}
向页面传值
使用request
将数据绑定到request,然后转发到某个jsp。
注:springMVC默认使用转发。
@RequestMapping("/login4.do")
//向页面传值的第一种方式:
//使用request。
public String login4(AdminParam ap,HttpServletRequest request)
{
System.out.println("login4()");
String adminCode = ap.getAdmincode();
System.out.println("adminCode:"+adminCode);
//将数据绑定到request
request.setAttribute("adminCode", adminCode);
//springmvc默认使用转发
return "index";
}
使用ModelAndView
将数据先封装到ModelAndView对象里面,然后将该对象作为方法的返回值。
@RequestMapping("/login5.do")
//向页面传值的第二种方式:
//使用ModelAndView。
public ModelAndView login5(AdminParam ap)
{
System.out.println("login5()");
String adminCode = ap.getAdmincode();
System.out.println("adminCode:"+adminCode);
Map<String,Object> data = new HashMap<String,Object>();
//相当于request.setAttribute("adminCode", adminCode);
data.put("adminCode", adminCode);
//构造ModelAndView对象
ModelAndView mav = new ModelAndView("index",data);
return mav;
}
使用ModelMap
将该对象作为方法的参数,然后将数据绑定到该对象。
@RequestMapping("/login6.do")
//向页面传值的第三种方式:
//使用ModelMap。
public String login6(AdminParam ap,ModelMap mm)
{
System.out.println("login6()");
String adminCode = ap.getAdmincode();
System.out.println("adminCode:"+adminCode);
//相当于request.setAttribute("adminCode", adminCode);
mm.addAttribute("adminCode",adminCode);
return "index";
}
使用session
@RequestMapping("/login7.do")
//向页面传值的第四种方式:
//使用session。
public String login7(AdminParam ap,HttpSession session)
{
System.out.println("login7()");
String adminCode = ap.getAdmincode();
System.out.println("adminCode:"+adminCode);
session.setAttribute("adminCode", adminCode);
return "index";
}
重定向
如果方法的返回值是String
在重定向地址前添加“redirect:”。
@RequestMapping("/login8.do")
//
public String login8()
{
System.out.println("login8()");
return "redirect:toIndex.do";
}
如果方法的返回值是ModelAndView
@RequestMapping("/login9.do")
//
public ModelAndView login9()
{
System.out.println("login9()");
RedirectView rv = new RedirectView("toIndex.do");
return new ModelAndView(rv);
}
编码问题
为什么会有乱码
表单提交时,浏览器会对中文进行编码(会使用打开表单所在页面是的字符集来编码,比如使用utf-8来编码),而服务器端默认使用iso-8859-1来解码,所以会产生乱码。
如何解决?
springMVC提供了一个过滤器(CharacterEncodingFilter)
注意:
a.表单提交要采用post方式提交。
b.客户端的编码与过滤器的编码要一样。
request.setCharaterEncoding(“utf-8”);
<filter>
<filter-name>encodingFilter</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>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
拦截器
什么是拦截器
spring提供的一个特殊组件,当DispatcherServlet收到请求之后,如果有拦截器,会先调用拦截器,然后调用相应的处理器(Controller)。
注:过滤器属于servlet规范,而拦截器属于spring框架。
如何写一个拦截器
step1.写一个Java类,实现HandlerIntercepter接口。
step2.实现具体的拦截处理逻辑,比如,session验证。
package com.match.netctoss.interceptors;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
/**
* 用于session验证的拦截器
* @author Match
*
*/
public class SessionInterceptor implements HandlerInterceptor
{
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception
{
}
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception
{
}
public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object arg2) throws Exception
{
System.out.println("preHandle()");
HttpSession session = req.getSession();
Object obj = session.getAttribute("admin");
if(obj == null)
{
//没有登录,重定向到登录页面
res.sendRedirect("toLogin.do");
return false;
}
//已经登录过,则允许访问
return true;
}
}
step3、配置拦截器。
异常处理
可以将异常抛给spring,由spring来处理这些异常。具体有两种方式:
使用简单异常处理器
step1、配置简单异常处理器。
<!-- 配置简单异常处理器 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="java.lang.NumberFormatException">error1</prop>
<prop key="java.lang.StringIndexOutOfBoundsException">error2</prop>
</props>
</property>
</bean>
step2、添加异常处理页面。
使用@ExceptionHandler注解
step1、在处理器类中,添加一个异常处理方法,该方法必须使用@ExceptionHandler修饰。
注:在该方法里面,依据异常类型,分别进行不同的处理。
step2、添加异常处理页面。
@ExceptionHandler
//异常处理方法
//ex:是其他方法所抛出的异常
public String exHandle(Exception ex,HttpServletRequest request)
{
System.out.println("exHandle()");
//依据异常类型的不同,分别进行相应处理。
if(ex instanceof NumberFormatException)
{
request.setAttribute("errorMsg","亲,请输入正确的数字。");
return "error";
}
else if(ex instanceof StringIndexOutOfBoundsException)
{
request.setAttribute("errorMsg","下标越界。");
return "error";
}
else
{
//其他异常
return "system_error";
}
}