01_Springmvc学习及SSM整合

1. ssm的整合

思路:mvc三层架构
1. dao:mybatis
    1.1. mybatis的核心配置文件:sqlMapConfig.xml --配置Mapper映射文件的包名作为别名。
    1.2. applicationContext_dao.xml配置数据源,sqlSessionFactory(mybatis的session工厂),
    配置Mapper接口的basepackage(mybatis的动态代理开发,根据接口mybatis实现,我们只需要提供接口与mapper的sql配置即可)
    1.3. 上面1.2相当于完成了spring与mybatis的整合

2. service : spring
    2.1. applicationContext_service.xml:配置service层的注解扫描: 
        
    2.2. applicationContext_tx.xml:spring的事务管理

3. web : springmvc
    3.1. springmvc.xml : 
        1. 配置controller的注解扫描
        2. 
            
        3.  配置视图解析器,简化controller层,返回页面view的书写
        
            
            
        

4. web.xml配置servlet容器(tomcat)启动加载spring,并且配置springmvc的前端控制器
    
    
        contextConfigLocation
        classpath:resources/spring/applicationContext-*.xml
    
    
        org.springframework.web.context.ContextLoaderListener
    

    
    
        springmvc
        org.springframework.web.servlet.DispatcherServlet
        
            contextConfigLocation
            classpath:resources/spring/springmvc.xml
        
    
    
        springmvc
        *.action


这里SpringMVC在拦截url请求时有三种方式:

1. /* 拦截所有,包括JSP
2. /  拦截所有,不包括JSP
3. *.action 只拦截以.action结尾的请求,不拦截静态资源等其他资源


如果使用了第二种拦截方式,但是又要放行静态资源如 js/jquery/css等,可以在springmvc.xml中进行配置:



2. springmvc的使用

2.1 @RequestMapping

通过@RequestMapping注解可以定义不同的处理器映射规则。

1.URL路径映射(写在方法上,根据url映射到对应的方法),value的值是数组,可以将多个url映射,到同一个方法,用逗号分隔
@RequestMapping(value="item")或@RequestMapping("/item")

@RequestMapping("/item/itemList.action")
public ModelAndView findItemList() {
    // 查询商品数据
    List list = this.itemService.queryItemList();

    // 创建ModelAndView,设置逻辑视图名
    ModelAndView mv = new ModelAndView("itemList");

    // 把商品数据放到模型中
    mv.addObject("itemList", list);
    return mv;
}

2. 写在类上,窄化路径
如 
@RequestMapping("/item")
public class itemController {}

相当于将所有方法上的RequestMapping前加了/item的前缀,可以用它来抽取或统一路径的前缀

3. 对方法的限定
    限定GET方法
    @RequestMapping(method = RequestMethod.GET)
    限定POST方法
    @RequestMapping(method = RequestMethod.POST)

2.2 Controller方法的返回值

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

2. 返回String(官方推荐)
    controller方法返回字符串可以指定逻辑视图名,通过视图解析器解析为物理视图地址。数据使用Model model的model.addAttribbute(k,v)存储到request域
此外:返回String还支持重定向与请求转发,例如:
    return "redirect:/itemList.action";
    return "forward: /itemEdit.action?id="+id;

3. 返回void
    在Controller方法形参上可以定义request和response,使用request或response指定响应结果:适用于ajax请求访问

2.3 springmvc解决post请求乱码问题

在web.xml中添加拦截器,拦截所有请求,将其携带参数转为UTF-8格式


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


    encoding
    /*


如果要解决GET请求的乱码问题:
01_Springmvc学习及SSM整合_第1张图片
1.png

2.4 解决返回Json数据乱码问题



    
        
          
              
                
                text/html;charset=UTF-8
                application/json;charset=UTF-8
              
          
        
    

2.4 springmvc中的自定义参数转换器

由于日期数据有很多种格式,springmvc没办法把字符串转换成日期类型。所以需要自定义参数绑定

前端控制器接收到请求后,找到注解形式的处理器适配器,对RequestMapping标记的方法进行适配,
并对方法中的形参进行参数绑定。可以在springmvc处理器适配器上自定义转换器Converter进行参数绑定。

一般使用注解驱动加载处理器适配器,可以在此标签上进行配置。

1. 编写自定义转换器Converter 实现 Converter
//S:source,需要转换的源的类型
//T:target,需要转换的目标类型
public class DateConverter implements Converter {

    @Override
    public Date convert(String s) {
        if (StringUtils.isEmpty(s)) {
            return null;
        }

        try {
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            return df.parse(s);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
}


2. 在springmvc.xml中配置自定义Converter






    
        
            
        
    


第二种方式:(了解)



    




    




    
        
            
        
    

注意:此方法需要独立配置处理器映射器、适配器,
不再使用

3. springmvc的进阶知识点

3.1 自定义异常处理器

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

01_Springmvc学习及SSM整合_第2张图片
2.png

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

//自定义异常
public class CustomerException extends Exception {
    public CustomerException(String message) {
        super(message);
    }
}

接下来自定义异常处理器:

/**
 * 自定义异常处理器
 * Created by Administrator on 2017/8/29.
 */
public class MyEceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) {
        ModelAndView mav = new ModelAndView();

        //根据不同的异常定义友好提示信息
        if (e instanceof CustomerException) {
            mav.addObject("errorMsg", e.getMessage());
        } else {
            mav.addObject("errorMsg", "未知异常");
        }
        e.printStackTrace();
        //发生异常后跳转的页面WEB-INF/jsp/error.jsp
        mav.setViewName("error");
        return mav;
    }
}

最后,在springmvc.xml中配置该自定义异常处理器即可,那么以后碰到异常,前端控制器都会交给这个异常处理器处理:



3.2 springmvc实现图片上传

图片上传后需要保存到本地磁盘,配置tomcat的虚拟路径,在tomcat的config/server.xml中修改:
DocBase : 真实路径  path : 虚拟路径


我使用的idea也可以直接在ide工具配置:
    选择+,extra source选择要映射的真实路径,右侧ApplicationContext填写虚拟路径
01_Springmvc学习及SSM整合_第3张图片
3.png
配置完后,还需要在server勾选:勾选这里后,idea也可以直接访问tomcat的首页了,否则不行
01_Springmvc学习及SSM整合_第4张图片
4.png

加入jar包:

01_Springmvc学习及SSM整合_第5张图片
6.png

在springmvc.xml中配置 文件上传解析器:



    
    

同时前端页面需要满足:enctype="multipart/form-data

并且,input标签type为file,name与controller接收的形参名称一致

Controller实现文件上传,将上传的图片文件保存到本地服务器,并将路径保存到数据库:

//提供参数MultipartFile,参数名与前端的name一致
@RequestMapping("/updateItem.action")
public String updateItem(Items item, MultipartFile pictureFile) throws IOException {
    //获取文件原始名称
    String originalFilename = pictureFile.getOriginalFilename();
    //获取后缀名
    String ext = FilenameUtils.getExtension(originalFilename);
    //获取uuid随机文件名
    String name = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase();
    String filename = "/img/" + name + "." + ext;

    //save to disk 上传保存到本地服务器
    pictureFile.transferTo(new File("D:/upload/img/" + name + "." + ext));

    //save to database 保存路径到数据库
    item.setPic(filename);
    itemsService.updateItems(item);
    return "redirect:/item/list.action";
}

3.3 json数据交互

加入jar包:

7.png
@RequestBody:
    @RequestBody注解用于读取http请求的内容(字符串),通过springmvc提供的HttpMessageConverter接口将读到的内容(json数据)
转换为java对象并绑定到Controller方法的参数上。

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

@RequestMapping("/testAjaxJson")
public @ResponseBody
Items testAjaxJson(@RequestBody Items item, ModelMap model) {
    System.out.println(item);
    return item;
}

3.4 Restful开发

Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

1.使用注解@RequestMapping("item/{id}")声明请求的url
{xxx}叫做占位符,请求的URL可以是“item /1”或“item/2”

2.使用(@PathVariable() Integer id)获取url上的数据   

如果@RequestMapping中表示为"item/{id}",id和形参名称一致,@PathVariable不用指定名称。
如果不一致,例如"item/{ItemId}"则需要指定名称@PathVariable("itemId")。

/**
 * Restful风格开发  这里的url访问路径使用restful1.action,使用PathVariable()可以接收到url中的id
 */
@RequestMapping("restful{id}.action")
public String restful(@PathVariable() Integer id,ModelMap model) {
    Items item = itemsService.findItemsById(id);
    model.addAttribute("item",item);
    return "editItem";
}

3.5 springmvc的自定义拦截器

自定义拦截器实现HandlerIntercepter接口:进而实现它的三个方法

public class MyInterceptor1 implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("执行方法前1");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("执行方法后1");

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("渲染页面后1");
    }
}

在springmvc.xml中配置自定义拦截器:



    
        
        
    
    
        
        
    


总结:
preHandle按拦截器定义顺序调用
postHandler按拦截器定义逆序调用
afterCompletion按拦截器定义逆序调用

postHandler在拦截器链内所有拦截器返成功调用
afterCompletion只有preHandle返回true才调用

你可能感兴趣的:(01_Springmvc学习及SSM整合)