SpringMVC_第1张图片

SpringMVC_第2张图片

SpringMVC

01.SpringMVC架构

SpringMVC_第3张图片

关于DispatcherServlet源码实现原理我参考了:http://blog.csdn.net/congcong68/article/details/40451233

02.spring入门程序

程序执行步骤:

Tomcat启动-->加载web.xml-->加载web.xml中的servlet-->加载SpringMvc.xml配置文件-->

SpringMvc.xml(名称不固定)里面有:

<context:component-scan base-package="com.my.controller">context:component-scan>

-->就会扫描这个包里面的所有类,然后就会加载含有@Controller注解的类,并将其加载到内存中变成对象

代码

Web.xml



    springMvc
    org.springframework.web.servlet.DispatcherServlet
    
    
        contextConfigLocation
        classpath:SpringMvc.xml
    
    
    1


    springMvc
    *.action

SpringMvc.xml:里面有组件的配置信息

SpringMVC三大组件:

处理映射器:制定url到指定方法的映射

处理器适配器:根据不同的Handler找到不同的处理器适配器去执行Handler

视图解析器:根据不同的视图去解析(视图可以是jsppdfwordfreeMark



        
        
        
 
     
        

        

        
        

        

 











Handler层代码

@Controller
public class ItemsController {
//指定URL到请求方法的映射
@RequestMapping("/list")
public ModelAndView itemsList() throws Exception{
        List itemList = new ArrayList();
        
        //商品列表
        Items items_1 = new Items();
        items_1.setName("联想笔记本_3");
        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苹果手机!");
        
        itemList.add(items_1);
        itemList.add(items_2);
        
        //模型和视图
        //model模型: 模型对象中存放了返回给页面的数据
        //view视图: 视图对象中指定了返回的页面的位置
        ModelAndView modelAndView = new ModelAndView();
        
        //将返回给页面的数据放入模型和视图对象中
        modelAndView.addObject("itemList", itemList);
        
        //指定返回的页面位置,"itemList"是页面取数据的变量
        modelAndView.setViewName("itemList");
        
        return modelAndView;
    
    }
}

03.ssm整合(list功能)

1)Dao层

    pojo和映射文件以及接口使用逆向工程生成

    SqlMapConfig.xml   mybatis核心配置文件

    ApplicationContext-dao.xml 整合后springdao层的配置

    数据源

    会话工厂

    扫描Mapper

2)service层

    事务   ApplicationContext-trans.xml

    @Service注解扫描 ApplicationContext-service.xml

3)controller层

    SpringMvc.xml

    注解扫描:扫描@Controller注解

    注解驱动:替我们显示的配置了最新版的处理器映射器和处理器适配器

    视图解析器:显示的配置是为了在controller中不用每个方法都写页面的全路径

4)web.xml

    springMvc前端控制器配置

    spring监听

04-1.参数绑定

1. 默认支持类型(修改功能,modelrequeststringmodelview

Model比request强大一点

String和modelview都行,不过string代码少一点

注:mapper接口中的方法,如果是单表操作,则已经自动生成;多表操作需手动创建。

@Controller
public class ItemsController {
 
@Autowired
private ItemsService itmesService;
 
/**
 * springMvc中默认支持的参数类型:也就是说在controller方法中可以加入这些也可以不加,  加不加看自己需不需要,都行.
 *HttpServletRequest
 *HttpServletResponse
 *HttpSession
 *Model
 */
@RequestMapping("/itemEdit")
public String itemEdit(HttpServletRequest reuqest, 
 Model model) throws Exception{

    String idStr = reuqest.getParameter("id");
    Items items = itmesService.findItemsById(Integer.parseInt(idStr));
    
    //Model模型:模型中放入了返回给页面的数据
    //model底层其实就是用的request域来传递数据,但是对request域进行了扩展.
    model.addAttribute("item", items);
    
    //如果springMvc方法返回一个简单的string字符串,那么springMvc就会认为这个字符串就是页面的名称
    return "editItem";
}
@Service
public class ItemsServiceImpl implements ItemsService {
 
    @Autowired
    private ItemsMapper itemsMapper;
     
    @Override
    public Items findItemsById(Integer id) throws Exception {
        Items items = itemsMapper.selectByPrimaryKey(id);
        return items;
    }
public interface ItemsMapper {
    Items selectByPrimaryKey(Integer id);

2. 基本类型和pojo类型

@Controller
public class ItemsController {
 
    @Autowired
    private ItemsService itmesService;
    //springMvc可以直接接收基本数据类型,包括string.spirngMvc可以帮你自动进行类型转换.
    //controller方法接收的参数的变量名称必须要等于页面上input框的name属性值
    //public String update(Integer id, String name, Float price, String detail) throws Exception{
    
        //spirngMvc可以直接接收pojo类型:要求页面上input框的name属性名称必须等于pojo的属性名称
        @RequestMapping("/updateitem")
        public String update(Items items) throws Exception{
        itmesService.updateItems(items);
        
        return "success";
    }
@Service
public class ItemsServiceImpl implements ItemsService {
    @Autowired
    private ItemsMapper itemsMapper;
    @Override
    public void updateItems(Items items) throws Exception {
        itemsMapper.updateByPrimaryKeyWithBLOBs(items);
    }
}
int updateByPrimaryKeyWithBLOBs(Items record);

3. 接收vo类型

public class QueryVo {
//商品对象
private Items items;
@Controller
public class ItemsController {
    @Autowired
    private ItemsService itmesService;
    //如果Controller中接收的是Vo,那么页面上input框的name属性值要等于vo的属性.属性.属性.....
    @RequestMapping("/search")
    public String search(QueryVo vo) throws Exception{
        System.out.println(vo);
        return "";
    }
}

4. 自定义类型转换器

当从界面传过来date类型的时候,使用pojo接收会报错,因为springmvc只会转换基本数据类型;对于其他类型,则需要自定义类型转换器。

具体操作:

01.先新建一个转换器类

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.core.convert.converter.Converter;
/**
 * S - source:源
 * T - target:目标
 * @author zj
 *
 */
public class CustomGlobalStrToDateConverter implements Converter {
    @Override
    public Date convert(String source) {
        try {
            Date date = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(source);
            return date;
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
}

02.在springmvc配置文件中配置


    


    
        
            
            
        
    

注意: 一定要将自定义的转换器配置到注解驱动上,因为会被处理器适配器去识别,进行转换

5. 高级参数绑定

数组:

页面


    
        
            
        
    
    商品列表:
    
        
            
            商品名称
            商品价格
            生产日期
            商品描述
            操作
        
        
            
                
                
                
                    
                
                ${item.name }
                ${item.price }
                
                ${item.detail }
            
        
         
    
@RequestMapping("/delAll")
//会将多选框中的id放入vo类中,ids数组中
public String delAll(QueryVo vo) throws Exception{
    //如果批量删除,一堆input复选框,那么可以提交数组.(只有input复选框被选中的时候才能提交)
    System.out.println(vo);
    return "";
}
public class QueryVo {
//商品对象
private Items items;
//订单对象...
//用户对象....
 
//批量删除使用
private Integer[] ids;
集合:

页面:


    查询条件:
    
        
        
        商品名称:
        商品价格:
        
        
    
    商品列表:
    
        
            
            商品名称
            商品价格
            生产日期
            商品描述
            操作
        
        
            
            
            
            
                
                
            
            
            
            "/>
            
            
            修改
             
            
        
         
    
@RequestMapping("/updateAll")
public String updateAll(QueryVo vo) throws Exception{
    System.out.println(vo);
    return "";
}
public class QueryVo {
//商品对象
private Items items;
//订单对象...
//用户对象....
 
//批量删除使用
private Integer[] ids;
//批量修改使用
private List itemsList;

04-2.controller返回值

1. Void

返回void(使用它破坏了springMvc的结构,所以不建议使用)

可以使用request.setAttribut 来给页面返回数据

可以使用request.getRquestDispatcher().forward()来指定返回的页面

如果controller返回值为void则不走springMvc的组件,所以要写页面的完整路径名称

//返回数据
//request.setAttribute("", arg1);
//指定返回的页面(如果controller方法返回值为void,则不走springMvc组件,所以要写页面的完整路径名称)
//request.getRequestDispatcher("/WEB-INF/jsp/success.jsp").forward(request, response);

2. StringModel(重定向和转发、相对路径和绝对路径)

String(推荐使用)

返回普通字符串,就是页面去掉扩展名的名称, 返回给页面数据通过Model来完成

返回的字符串以forward:开头为请求转发

返回的字符串以redirect:开头为重定向

重定向(model):

重定向,如果使用request,数据不能带的;但是如果使用model可以带上传递的数据

//重定向:浏览器中url发生改变,request域中的数据不可以带到重定向后的方法中
//model.addAttribute("id", items.getId());
//在springMvc中凡是以redirect:字符串开头的都为重定向
return "redirect:itemEdit/"+items.getId();
转发:
//请求转发:浏览器中url不发生改变,request域中的数据可以带到转发后的方法中
model.addAttribute("id", items.getId());
//spirngMvc中请求转发:返回的字符串以forward:开头的都是请求转发, 
//后面forward:itemEdit.action表示相对路径,相对路径就是相对于当前目录,当前为类上面指定的items目录.在当前目录下可以使用相对路径随意跳转到某个方法中
//后面forward:/itemEdit.action路径中以斜杠开头的为绝对路径,绝对路径从项目名后面开始算
return "forward:/items/itemEdit.action";

3. ModelAndView

ModelAndView
modelAndView.addObject("itemList", list); 指定返回页面的数据
modelAndView.setViewName("itemList");   指定返回的页面

4. 相对路径和绝对路径

相对路径:

相对于当前目录,也就是在当前类的目录下,这时候可以使用相对路径跳转

绝对路径:

从项目名后开始.

在springMvc中不管是forward还是redirect后面凡是以/开头的为绝对路径,不以/开头的为相对路径

例如:forward:/items/itemEdit.action 为绝对路径

forward:itemEdit.action为相对路径

05.乱码问题

Post


  
    CharacterEncodingFilter
    org.springframework.web.filter.CharacterEncodingFilter
    
        encoding
        utf-8
    


    CharacterEncodingFilter
    /*

Get

01.修改Tomcat配置文件添加编码与工程编码一致:server.xml

utf8 connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

02.对参数进行重编码

String username = new String(request.getParameter(username).getBytes(ISO8859-1),utf-8)

 

06.jsp传图片注意

 

07.springmvcstruts2不同

1、 springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过虑器。

2、 springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例)struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。

3、 Struts采用值栈存储请求和响应的数据,通过OGNL存取数据, springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过reques域传输到页面。Jsp视图解析器默认使用jstl

 

08.@RequestMapping用法

1. URL路径映射

2. 窄化请求映射

3. 请求方法限定

SpringMVC_第4张图片

09.异常处理器

springmvc在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑。

异常处理思路

系统中异常包括两类:预期异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。

系统的dao、servicecontroller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理,如下图:

SpringMVC_第5张图片

自定义异常类

为了区别不同的异常通常根据异常类型自定义异常类,这里我们创建一个自定义系统异常,如果controller、servicedao抛出此类异常说明是系统预期处理的异常信息。

public class CustomException extends Exception {
 
    /** serialVersionUID*/
    private static final long serialVersionUID = -5212079010855161498L;
    
    public CustomException(String message){
        super(message);
        this.message = message;
    }
     
    //异常信息
    private String message;
     
    public String getMessage() {
        return message;
    }
     
    public void setMessage(String message) {
        this.message = message;
    }
}

自定义异常处理器

public class CustomExceptionResolver implements HandlerExceptionResolver {
 
    @Override
    public ModelAndView resolveException(HttpServletRequest request,
    HttpServletResponse response, Object handler, Exception ex) {
     
        ex.printStackTrace();
         
        CustomException customException = null;
        
        //如果抛出的是系统自定义异常则直接转换
        if(ex instanceof CustomException){
            customException = (CustomException)ex;
        }else{
            //如果抛出的不是系统自定义异常则重新构造一个系统错误异常。
            customException = new CustomException("系统错误,请与系统管理 员联系!");
        }
        
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("message", customException.getMessage());
        modelAndView.setViewName("error");
         
        return modelAndView;
    }
 
}

错误页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"  prefix="fmt"%> 


    
        
        错误页面
         
    
    
        您的操作出现错误如下:
        ${message }       

异常处理器配置

在springmvc.xml中添加:


异常测试

修改商品信息,id输入错误提示商品信息不存在。

修改controller方法“editItem”,调用service查询商品信息,如果商品信息为空则抛出异常:

010.SpringMVC上传图片

1. 配置虚拟图片服务器

前提:

 环境基于Tomcat6.x系列实验, 其它版本的Tomcat虚拟目录配置可能略有不同

1. 进入Tomcat conf\Catalina\localhost

image.png

2. 新建xxx.xml文件, 我这里命名为img.xml

SpringMVC_第6张图片

3. xml文件中配置如下内容:

SpringMVC_第7张图片

path : 浏览器访问目录, 与xml文件名必须一致

       docBase : 虚拟目录

4. Tomcatconf\web.xml文件中找到如下配置:

listings 修改成true

SpringMVC_第8张图片

5. 通过浏览器访问

      http://ip:端口号/虚拟目录, 如可以显示,虚拟目录配置成功

SpringMVC_第9张图片

2. 导包

CommonsMultipartResolver解析器依赖commons-fileuploadcommons-io,加入如下jar包:

image.png

3. 配置解析器

在springmvc.xml



    
    
        5242880
    

4. 页面



    <%--   --%>
     修改商品信息:
    
        
            商品名称
            
        
        
            商品价格
            
        
        
        
            商品生产日期
            " />
        
        
        
            商品图片
            
            
            
            
                                                                                商品简介             ${item.detail }                                                                            

5. web层操作

@RequestMapping("/updateitem")
//pictureFile跟页面中” ”的name值一样
public String update(MultipartFile pictureFile,Items items, Model model, HttpServletRequest request) throws Exception{
    //1. 获取图片完整名称
    String fileStr = pictureFile.getOriginalFilename();
     
    //2. 使用随机生成的字符串+源图片扩展名组成新的图片名称,防止图片重名
    String newfileName = UUID.randomUUID().toString() + fileStr.substring(fileStr.lastIndexOf("."));
     
    //3. 将图片保存到硬盘
    pictureFile.transferTo(new File("E:\\image\\" + newfileName));
     
    //4.将图片名称保存到数据库
    items.setPic(newfileName);
    itmesService.updateItems(items);
     
    return "redirect:itemEdit/"+items.getId();
}

011.json数交互

@RequestBody

作用:

@RequestBody注解用于读取http请求的内容(字符串),通过springmvc提供的HttpMessageConverter接口将读到的内容转换为jsonxml等格式的数据并绑定到controller方法的参数上。

List.action?id=1&name=zhangsan&age=12

 

本例子应用:

@RequestBody注解实现接收http请求的json数据,将json数据转换为java对象

 

@ResponseBody

作用:

该注解用于将Controller的方法返回的对象,通过HttpMessageConverter接口转换为指定格式的数据如:json,xml等,通过Response响应给客户端

 

本例子应用:

@ResponseBody注解实现将controller方法返回对象转换为json响应给客户端

请求json,响应json实现:

1. 环境准备

Springmvc默认用MappingJacksonHttpMessageConverterjson数据进行转换,需要加入jackson的包,如下:

image.png

2. springmvc.xml配置

在注解适配器中加入messageConverters



    
        
            
        
    

注意:如果使用 则不用定义上边的内容。

3. 页面


    
        
        
        查询商品列表
    
     
        
        function sendJson(){
            //请求json响应json
            $.ajax({
                type:"post",
                url:"${pageContext.request.contextPath }/items/sendJson.action",
                contentType:"application/json;charset=utf-8",
                data:'{"name":"测试商品","price":99.9}',
                success:function(data){
                alert(data);
                }
            });
        
        }
        
        
        
            查询条件:
            
                
                
                商品名称:
                商品价格:
                
            
            
            商品列表:
            
            
                
                商品名称
                商品价格
                生产日期
                商品描述
                操作
            
            
                
                    
                    
                    
                    
                    
                    
                    
                    
                    "/>
                    
                    
                    修改
                 
                
            
             
            
        
    
     

4. controller操作

//导入jackson的jar包在 controller的方法中可以使用@RequestBody,让spirngMvc将json格式字符串自动转换成java中的pojo
//页面json的key要等于java中pojo的属性名称
//controller方法返回pojo类型的对象并且用@ResponseBody注解,springMvc会自动将pojo对象转换成json格式字符串
@RequestMapping("/sendJson")
@ResponseBody
public Items json(@RequestBody Items items) throws Exception{
    System.out.println(items);
    return items;
}

012.restful

什么是restful

Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格,是对http协议的诠释。

资源定位:互联网所有的事物都是资源,要求url中没有动词,只有名词。没有参数

资源操作:使用putdeletepostget,使用不同方法对资源进行操作。分别对应添加、删除、修改、查询。一般使用时还是postgetPutDelete几乎不使用。

需求

RESTful方式实现商品信息查询,返回json数据

添加DispatcherServletrest配置(在web.xml


  
   springMvc
   org.springframework.web.servlet.DispatcherServlet
   
    contextConfigLocation
    classpath:SpringMvc.xml
   
   
   1
  
  
   springMvc
   
   /
  

URL 模板模式映射

@RequestMapping(value="/ viewItems/{id}")

{×××}占位符,请求的URL可以是/viewItems/1”或“/viewItems/2”,通过在方法中使用@PathVariable获取{×××}中的×××变量。

@PathVariable用于将请求URL中的模板变量映射到功能处理方法的参数上。

SpringMVC_第10张图片

@RequestMapping("/viewItems/{id}") 
public @ResponseBody viewItems(@PathVariable("id") String id,Model model) throws Exception{
    //方法中使用@PathVariable获取useried的值,使用model传回页面
    //调用 service查询商品信息
    ItemsCustom itemsCustom = itemsService.findItemsById(id);
    return itemsCustom;
}

如果RequestMapping中表示为"/viewItems/{id}"id和形参名称一致,@PathVariable不用指定名称。

有多个加多个占位符就好

 

商品查询的controller方法也改为rest实现:

SpringMVC_第11张图片

// 查询商品列表
@RequestMapping("/queryItem")
public ModelAndView queryItem() throws Exception {
    // 商品列表
    List itemsList = itemService.findItemsList(null);
     
    // 创建modelAndView准备填充数据、设置视图
    ModelAndView modelAndView = new ModelAndView();
     
    // 填充数据
    modelAndView.addObject("itemsList", itemsList);
    // 视图
    modelAndView.setViewName("item/itemsList");
     
    return modelAndView;
}

静态资源访问

如果在DispatcherServlet中设置url-pattern/则必须对静态资源进行访问处理。

spring mvc 的实现对静态资源进行映射访问。

如下是对js文件访问配置:

 

013.拦截器

1. 拦截器基础

public class Interceptor1 implements HandlerInterceptor {
 
    //执行时机:controller已经执行,modelAndview已经返回
    //使用场景: 记录操作日志,记录登录用户的ip,时间等.
    @Override
    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
    throws Exception {
        System.out.println("======Interceptor1=======afterCompletion========");
    }
     
    //执行时机:Controller方法已经执行,ModelAndView没有返回
    //使用场景: 可以在此方法中设置全局的数据处理业务
    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
    throws Exception {
        System.out.println("======Interceptor1=======postHandle========");
     
    }
     
    //返回布尔值:如果返回true放行,返回false则被拦截住
    //执行时机:controller方法没有被执行,ModelAndView没有被返回
    //使用场景: 权限验证
    @Override
    public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
        System.out.println("======Interceptor1=======preHandle========");
        return true;
    }
 
}


    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
        
        
        
        
    

针对某种mapping配置拦截器


    
    
    
    
    
    


针对所有mapping配置全局拦截器



    
    
        
        
        
        
        
        
        

2. 实现登录拦截过程

SpringMVC_第12张图片