SpringMvc详解

  • 一Spring mvc是什么
  • 二Spring mvc运行流程架构
  • 三组件说明
    • 1DispatcherServlet前端控制器
    • 2HandlerMapping处理器映射器
    • 3Handler处理器
    • 4HandlAdapter处理器适配器
    • 5ViewResolver视图解析器
  • 四框架搭建流程
    • 1导入相关架包本处不阐述
    • 2配置前端控制器DispatcherServlet在WEB-INFwebxml中配置前端控制器
    • 51 Servlet拦截方式
    • 3配置处理器映射器HandlerMapping和处理器适配器HandlerAdapter注解方式其他本处不再阐述在springMVCxml中配置
    • 4配置试图解析器viewResolver在springMVCxml中配置
    • 5配置主键扫描器
  • 五注解
    • 1Controller
    • 2RequestMappingvalue getlistmethod RequestMethodGET
    • 3RequestParam
  • 六Controller的返回值
    • 1返回ModelAndViewcontroller方法中定义ModelAndView对象并返回对象中可添加model数据指定view
    • 2返回void
    • 3返回字符串controller方法返回字符串可以指定逻辑视图名通过视图解析器解析为物理视图地址
  • 七参数绑定
    • 1默认支持的参数类型
      • HttpServletRequest
      • HttpServletResponse
      • HttpSession
      • Model
    • 2RequestParam
    • 3简单类型
      • 整型
      • 字符串
      • 单精度双精度
      • 布尔型
    • 4自定义参数绑定难点不阐述
    • 5POJO即java类
      • 1简单pojo
      • 将pojo对象中的属性名于传递进来的属性名对应如果传进来的参数名称和对象中的属性名称一致则将参数值设置在pojo对象中
      • Contrller方法定义如下
      • 2包装pojo
      • 包装对象定义如下
      • 页面定义
      • Controller方法定义如下
    • 6集合类
      • 1字符串数组
      • 2List
  • 八乱码问题
    • 1POST乱码
    • 2GET乱码
  • 九上传图片
    • 1导入架包
    • 2配置解析器
    • 3编写controller
    • JSP
  • 十数据回显
  • 十一JSON数据交互
    • 需求要使springMVC支持接收JSON数据和返回JSON数据
    • 1Springmvc默认用MappingJacksonHttpMessageConverter对json数据进行转换需要加入jackson的包如下
    • 2在处理器适配器中注入MappingJacksonHttpMessageConverter
    • 3编写Controller
  • 十二validation效验
  • 十三异常处理器统一异常处理
    • 1定义异常
    • 2编写异常解析器
    • 3配置统一异常处理器
    • 4抛出异常
  • 十四设置静态资源解析
  • 十五SpringMvc拦截器
    • 1定义拦截器实现HandlerInterceptor接口
    • 2在springmvcxml中配置拦截器
      • 1针对某种mapping配置
      • 2针对所有的mapping全局配置
    • 3拦截器应用
      • 1用户身份认证

一、Spring mvc是什么?

Spring mvc和Struts2都属于表现层的框架,它是Spring框架的一部分

二、Spring mvc运行流程(架构)


1、用户发送请求至前端控制器DispatcherServlet
2、DispatcherServlet收到请求调用HandlerMapping处理器映射器。
3、处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
4、DispatcherServlet通过HandlerAdapter处理器适配器调用处理器
5、执行处理器(Controller,也叫后端控制器)。
6、Controller执行完成返回ModelAndView
7、HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
8、DispatcherServlet将ModelAndView传给ViewReslover视图解析器
9、ViewReslover解析后返回具体View
10、DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)。
11、DispatcherServlet响应用户

三、组件说明

1、DispatcherServlet:前端控制器

用户请求到达前端控制器,它就相当于mvc模式中的c,dispatcherServlet是整个流程控制的中心,由它调用其它组件处理用户的请求,dispatcherServlet的存在降低了组件之间的耦合性。

2、HandlerMapping:处理器映射器

HandlerMapping负责根据用户请求找到Handler即处理器,springmvc提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。

3、Handler:处理器

Handler 是继DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下Handler对具体的用户请求进行处理。
由于Handler涉及到具体的用户业务请求,所以一般情况需要程序员根据业务需求开发Handler。

4、HandlAdapter:处理器适配器

通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。

5、ViewResolver:视图解析器

负责将处理结果生成View视图,ViewResolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户。 springmvc框架提供了很多的View视图类型,包括:jstlView、freemarkerView、pdfView等。

四、框架搭建流程

1、导入相关架包,本处不阐述

2、配置前端控制器(DispatcherServlet),在WEB-INF\web.xml中配置前端控制器

<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:config/springmvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>*.action</url-pattern>
</servlet-mapping>

3.5.1 Servlet拦截方式

1、拦截固定后缀的url,比如设置为 .do、.action, 例如:/user/add.action
此方法最简单,不会导致静态资源(jpg,js,css)被拦截。
2、拦截所有,设置为/,例如:/user/add /user/add.action
此方法可以实现REST风格的url,很多互联网类型的应用使用这种方式。
但是此方法会导致静态文件(jpg,js,css)被拦截后不能正常显示。需要特殊处理。

    <!--omcat, Jetty, JBoss, and GlassFish  默认 Servlet的名字 -- "default" 
    Google App Engine 默认 Servlet的名字 -- "_ah_default" 
    Resin 默认 Servlet的名字 -- "resin-file"
    WebLogic 默认 Servlet的名字  -- "FileServlet" 
    WebSphere  默认 Servlet的名字 -- "SimpleFileServlet" -->
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.css</url-pattern>
    </servlet-mapping>

3、拦截所有,设置为/*,此设置方法错误,因为请求到Action,当action转到jsp时再次被拦截,提示不能根据jsp路径mapping成功。

3、配置处理器映射器(HandlerMapping)和处理器适配器(HandlerAdapter)(注解方式,其他本处不再阐述),在springMVC.xml中配置

<!--注解映射器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>

<!--注解适配器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>

springmvc使用自动加载RequestMappingHandlerMapping和RequestMappingHandlerAdapter,可用在springmvc.xml配置文件中使用替代注解处理器和适配器的配置

<!-- handelMapping And handelAdapter -->
<mvc:annotation-driven />

4、配置试图解析器(viewResolver),在springMVC.xml中配置

<!-- ViewResolver -->
<bean id="viewResolver"
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
    <property name="prefix" value="/WEB-INF/jsp/" />
    <property name="suffix" value=".jsp" />
</bean>

5、配置主键扫描器

<!-- 扫描位置 -->
<context:component-scan base-package="com.bl" />

五、注解

1、@Controller

配置此注解的class才能被扫描器扫描为springMVC的Handler

2、@RequestMapping(value = “/getlist”,method = RequestMethod.GET)

此注解用在class上或者method上,表示请求URL和请求方式

3、@RequestParam

value:参数名字,即入参的请求参数名字,如value=“item_id”表示请求的参数区中的名字为item_id的参数的值将传入;
required:是否必须,默认是true

public String editItem(@RequestParam(value="item_id",required=true) String id) {}

六、Controller的返回值

1、返回ModelAndView,controller方法中定义ModelAndView对象并返回,对象中可添加model数据、指定view

// 创建modelAndView准备填充数据、设置视图
ModelAndView modelAndView = new ModelAndView();
// 填充数据
modelAndView.addObject("testlist", testlist);
// 视图
modelAndView.setViewName("testList");

2、返回void

在controller方法形参上可以定义request和response,使用request或response指定响应结果:
使用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串”);

3、返回字符串,controller方法返回字符串可以指定逻辑视图名,通过视图解析器解析为物理视图地址。

//指定逻辑视图名,经过视图解析器解析为jsp物理路径:/WEB-INF/jsp/item/editItem.jsp
return “item/editItem”;
Redirect重定向
return “redirect:queryItem.action”;//如果要传参数可以/item/queryItem.action后边加参数,如:/item/queryItem?name=”张三”&age=24
forward转发
return “forward:editItem.action”;

七、参数绑定

1、默认支持的参数类型

处理器形参中添加如下类型的参数处理适配器会默认识别并进行赋值

HttpServletRequest

通过request对象获取请求信息

HttpServletResponse

通过response处理响应信息

HttpSession

通过session对象得到session中存放的对象

Model

通过model向页面传递数据,如下:

//调用service查询商品信息
Items item = itemService.findItemById(id);
model.addAttribute("item", item);

页面通过${item.XXXX}获取item对象的属性值

2、@RequestParam

@RequestParam用于绑定单个请求参数。

value:参数名字,即入参的请求参数名字,如value=“item_id”表示请求的参数区中的名字为item_id的参数的值将传入;
required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报;
TTP Status 400 - Required Integer parameter ‘XXXX’ is not present

defaultValue:默认值,表示如果请求中没有同名参数时的默认值

定义如下:
public String editItem(@RequestParam(value="item_id",required=true) String id) {
}

3、简单类型

当请求的参数名称和处理器形参名称一致时会将请求参数与形参进行绑定

整型

public String editItem(Model model,Integer id) throws Exception{

字符串

例子略

单精度/双精度

例子略

布尔型

处理器方法:
public String editItem(Model model,Integer id,Boolean status) throws Exception
说明:对于布尔类型的参数,请求的参数值为true或false。

4、自定义参数绑定(难点,不阐述)

5、POJO(即java类)

1、简单pojo

将pojo对象中的属性名于传递进来的属性名对应,如果传进来的参数名称和对象中的属性名称一致则将参数值设置在pojo对象中

页面定义如下;

<input type="text" name="name"/>
<input type="text" name="price"/>

Contrller方法定义如下:

@RequestMapping("/editItemSubmit")
public String editItemSubmit(Items items)throws Exception{
System.out.println(items);

请求的参数名称和pojo的属性名称一致,会自动将请求参数赋值给pojo的属性。

2、包装pojo

包装对象定义如下:

Public class QueryVo {
private Items items;
}

页面定义:

<input type="text" name="items.name" />
<input type="text" name="items.price" />

Controller方法定义如下:

public String useraddsubmit(Model model,QueryVo queryVo)throws Exception{
System.out.println(queryVo.getItems());

6、集合类

1、字符串数组

页面定义如下:
页面选中多个checkbox向controller方法传递

<input type="checkbox" name="item_id" value="001"/>
<input type="checkbox" name="item_id" value="002"/>
<input type="checkbox" name="item_id" value="002"/>

传递到controller方法中的格式是:001,002,003

Controller方法中可以用String[]接收,定义如下:

public String deleteitem(String[] item_id)throws Exception{
    System.out.println(item_id);
}

2、List

List中存放对象,并将定义的List放在包装类中,action使用包装对象接收。

Public class QueryVo {
Private List<Items> itemList;
  //get/set方法..
}

包装类中定义List对象,并添加get/set方法如下:

页面:

<tr>
    <td>
    <input type="text" name=" itemList[0].id" value="${item.id}"/>
    </td>
    <td>
    <input type="text" name=" itemList[0].name" value="${item.name }"/>
    </td>
    <td>
    <input type="text" name=" itemList[0].price" value="${item.price}"/>
    </td>
    </tr>
    <tr>
    <td>
    <input type="text" name=" itemList[1].id" value="${item.id}"/>
    </td>
    <td>
    <input type="text" name=" itemList[1].name" value="${item.name }"/>
    </td>
    <td>
    <input type="text" name=" itemList[1].price" value="${item.price}"/>
    </td>
</tr>

Contrller方法定义如下:

public String useraddsubmit(Model model,QueryVo queryVo)throws Exception{
    System.out.println(queryVo.getItemList());
}

5.5.7.3 Map
在包装类中定义Map对象,并添加get/set方法,action使用包装对象接收。
包装类中定义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());
}

八、乱码问题

1、POST乱码

在web.xml中加入:

<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 = new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")

ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码

九、上传图片

1、导入架包

2、配置解析器

<!-- 文件上传 -->
<bean id="multipartResolver"
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 设置上传文件的最大尺寸为5MB -->
    <property name="maxUploadSize">
        <value>5242880</value>
    </property>
</bean>

3、编写controller

//商品修改提交
@RequestMapping("/editItemSubmit")
public String editItemSubmit(Items items, MultipartFile pictureFile)throws Exception{

    //原始文件名称
    String pictureFile_name =  pictureFile.getOriginalFilename();
    //新文件名称
    String newFileName =  UUID.randomUUID().toString()+pictureFile_name.substring(pictureFile_name.lastIndexOf("."));   
    //上传图片
    File uploadPic = new java.io.File("F:/develop/upload/temp/"+newFileName);

    if(!uploadPic.exists()){
        uploadPic.mkdirs();
    }
    //向磁盘写文件
    pictureFile.transferTo(uploadPic);
}

JSP

<input type="file" name="pictureFile" />

十、数据回显

1、贴上一篇文章的连接:http://blog.csdn.net/u012373815/article/details/47205657

2、@ModelAttribute将方法返回值传到页面
1、controller代码

@ModelAttribute("itemsType")
public Map<String, String> getItem(){
    Map<String, String> map = new HashMap<String, String>();
    map.put("001", "张三");
    map.put("002", "李四");
    return map;
}

2、JSP代码

<c:forEach items="${testlist }" var="item">
<tr>
    <td>${item.id }</td>
    <td>${item.val }</td>
    <td><a href="${pageContext.request.contextPath }/editItem.action?id=${item.id}">修改</a></td>
</tr>
</c:forEach>

十一、JSON数据交互

需求:要使springMVC支持接收JSON数据和返回JSON数据

1、Springmvc默认用MappingJacksonHttpMessageConverter对json数据进行转换,需要加入jackson的包,如下:

这里写图片描述

2、在处理器适配器中注入MappingJacksonHttpMessageConverter

<!--注解适配器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <!-- JSON转换器 -->
    <property name="messageConverters">
        <list>
            <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
        </list>
    </property>
</bean>

3、编写Controller

@RequestMapping(value="testjson")
public void testJson(HttpServletResponse response,@RequestBody Test test){
    System.out.println(test.getVal());
    try {
        PrintWriter out = response.getWriter();
        out.print("xxx");
    } catch (IOException e) {
        e.printStackTrace();
    }
    //return test;
}

JAVA类

@Basic(optional = false)
private Integer id;

@Column(name="VAL")
@Field
private String val;

//属性的Get和Set方法

JSON格式

{
"id": "1",
"val": "123"
}

十二、validation效验

http://haohaoxuexi.iteye.com/blog/1812584

十三、异常处理器(统一异常处理)

1、定义异常

public class CustomException extends Exception {

    //异常信息
    private String message;

    public CustomException(String message){
        super(message);
        this.message = message;

    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

2、编写异常解析器

public class CustomExceptionResolver implements HandlerExceptionResolver  {

    //前端控制器DispatcherServlet在进行HandlerMapping、调用HandlerAdapter执行Handler过程中,如果遇到异常就会执行此方法
    //handler最终要执行的Handler,它的真实身份是HandlerMethod
    //Exception ex就是接收到异常信息
    @Override
    public ModelAndView resolveException(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex) {
        //输出异常
        ex.printStackTrace();

        //统一异常处理代码
        //针对系统自定义的CustomException异常,就可以直接从异常类中获取异常信息,将异常处理在错误页面展示
        //异常信息
        String message = null;
        CustomException customException = null;
        //如果ex是系统 自定义的异常,直接取出异常信息
        if(ex instanceof CustomException){
            customException = (CustomException)ex;
        }else{
            //针对非CustomException异常,对这类重新构造成一个CustomException,异常信息为“未知错误”
            customException = new CustomException("未知错误");
        }

        //错误 信息
        message = customException.getMessage();

        request.setAttribute("message", message);


        try {
            //转向到错误 页面
            request.getRequestDispatcher("/WEB-INF/jsp/error.jsp").forward(request, response);
        } catch (ServletException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return new ModelAndView();
    }
}

3、配置统一异常处理器

<!-- 定义统一异常处理 -->
<bean class="com.xxx.CustomExceptionResolver"/>

4、抛出异常

可以在controller方法、service方法、dao实现类中抛出异常,要求dao、service、controller遇到异常全部向上抛出异常,方法向 上抛出异常throws Exception

if(xxx==null){
    throw new CustomException("XXX不存在")
}

十四、设置静态资源解析

当DispatcherServlet拦截/开头的所有请求,对静态资源的访问就报错404:
需要通过设置对静态资源进行解析

<!--静态资源解析-->
<mvc:resources location="/js/" mapping="/js/**"/>
<mvc:resources location="/img/" mapping="/img/**"/>  

表示访问/js/**的url从工程下/js/下解析和访问img下的url从img下解析

十五、SpringMvc拦截器

使用拦截器实现用户认证(用户登陆后进行身份校验拦截),用户权限拦截。

1、定义拦截器(实现HandlerInterceptor接口)

Public class HandlerInterceptor1 implements HandlerInterceptor{

    /**
     * controller执行前调用此方法
     * 返回true表示继续执行,返回false中止执行
     * 这里可以加入登录校验、权限拦截等
     */
    @Override
    Public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
        // TODO Auto-generated method stub
        Return false;
    }
    /**
     * controller执行后但未返回视图前调用此方法
     * 这里可在返回用户前对模型数据进行加工处理,比如这里加入公用信息以便页面显示
     */
    @Override
    Public void postHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        // TODO Auto-generated method stub

    }
    /**
     * controller执行后且视图返回后调用此方法
     * 这里可得到执行controller时的异常信息
     * 这里可记录操作日志,资源清理等
     */
    @Override
    Public void afterCompletion(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        // TODO Auto-generated method stub

    }
}

2、在springmvc.xml中配置拦截器

1、针对某种mapping配置

<bean
class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
<property name="interceptors">
    <list>
        <ref bean="handlerInterceptor1"/>
        <ref bean="handlerInterceptor2"/>
    </list>
</property>



2、针对所有的mapping全局配置

<!--拦截器 -->
<mvc:interceptors>
    <!--多个拦截器,顺序执行 -->
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="cn.itcast.springmvc.filter.HandlerInterceptor1"></bean>
    </mvc:interceptor>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="cn.itcast.springmvc.filter.HandlerInterceptor2"></bean>
    </mvc:interceptor>
</mvc:interceptors>

3、拦截器应用

1、用户身份认证

Public class LoginInterceptor implements HandlerInterceptor{

    @Override
    Public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {

        //如果是登录页面则放行
        if(request.getRequestURI().indexOf("login.action")>=0){
            return true;
        }
        HttpSession session = request.getSession();
        //如果用户已登录也放行
        if(session.getAttribute("user")!=null){
            return true;
        }
        //用户没有登录挑战到登录页面
        request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);

        return false;
    }
}

你可能感兴趣的:(spring,mvc)