JAVAWEB开发之SpringMVC详解(一)——SpringMVC的框架原理、架构简介、与mybatis整合和注解方式的使用、

知识清单

基础知识清单

SpringMVC框架(重点)
  • MVC在B/S系统中的应用方式
  • SpringMVC框架原理(DispatcherServlet前端控制器、处理器映射器、处理器适配器、视图解析器)
SpringMVC入门程序
  • 需求:商品列表查询
  • 常用的处理器映射器,处理器适配器
  • 注解的处理器映射器,处理器适配器用于注解开发(重点)
注解开发基础
  • 常用注解的使用
  • 参数绑定
  • 自定义参数绑定
SpringMVC与Struts的区别

高级知识清单(第二部分)

使用SpringMVC上传图片
集合参数的绑定
validation校验器
异常处理器的使用(用于系统异常处理)
Restful支持
拦截器

SpringMVC框架

SpringMVC是什么?

springmvc是Spring的一个模块,提供web层解决方案(就与MVC设计架构)
JAVAWEB开发之SpringMVC详解(一)——SpringMVC的框架原理、架构简介、与mybatis整合和注解方式的使用、_第1张图片

MVC在B/S系统中的应用

MVC是一种设计模式,在B/S中的应用如下图所示:
JAVAWEB开发之SpringMVC详解(一)——SpringMVC的框架原理、架构简介、与mybatis整合和注解方式的使用、_第2张图片

SpringMVC的框架

JAVAWEB开发之SpringMVC详解(一)——SpringMVC的框架原理、架构简介、与mybatis整合和注解方式的使用、_第3张图片
执行过程大致如下:
第一步:用户发起request请求,请求至DispatcherServlet前端控制器。
第二步:DispatcherServlet前端控制器请求HandlerMapping处理器映射器查找Handler。DispatcherServlet: 前端控制器,相当于中央调度器,各个组件都和前端控制器进行交互,降低了各个组件之间的耦合度。
第三步:HandlerMapping处理器映射器,根据url及一些配置规则(xml配置、注解配置)查找Handler,将Handler返回给DispatcherServlet前端控制器。
第四步:DispatcherServlet前端控制器调用适配器执行Handler,有了适配器通过适配器去扩展对不同Handler执行方式(比如:原始servlet开发,注解开发)
第五步:适配器执行Handler;Handler是后端控制器,可以当成模型
第六步:Handler执行完后后返回ModelAndView。ModelAndView: SpringMVC的一个对象,对model和view进行封装。
第七步:适配器将ModelAndView返回给DispatcherServlet前端控制器。
第八步:DispatcherServlet调用视图解析器进行视图解析,解析后生成view,视图解析器根据逻辑视图名解析出真正的视图。view:SpringMVC视图封装对象,提供了很多view,比如jsp、freemarker、pdf、execel.......
第九步:ViewResolver视图解析器给前端控制器返回view。
第十步:DispatcherServlet调用view的渲染视图的方法,将模型数据填充到request域。
第十一步:DispatcherServlet向用户响应结果(jsp页面、json数据......).

DispatcherServlet:前端控制器,由SpringMVC提供。
HandlerMapping:处理器映射器,由SpringMVC提供。
HandlerAdapter:处理器适配器,由SpringMVC提供。
Handler:处理器,需要程序员开发。
ViewResolver:视图解析器,由SpringMVC提供。
view:真正的视图页面,由程序员编写。

入门程序

需求

实现商品列表查询

需要的jar包

使用spring3.2.0(带springmvc模块)  如下图所示
JAVAWEB开发之SpringMVC详解(一)——SpringMVC的框架原理、架构简介、与mybatis整合和注解方式的使用、_第4张图片

前端控制器

在web.xml中进行配置

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

springmvc.xml

在springmvc.xml中配置springmvc架构的三大组件(处理器映射器、处理器适配器、视图解析器)

工程结构

JAVAWEB开发之SpringMVC详解(一)——SpringMVC的框架原理、架构简介、与mybatis整合和注解方式的使用、_第5张图片

处理器映射器

在springmvc.xml中进行配置:
BeanNameURLHandlerMapping:根据url( xxx.action ) 匹配Spring容器的name。
找到对应的Bean(程序员编写的Handler)

		
注意:所有处理器映射器都实现HandlerMapping接口

处理器适配器

在springmvc.xml中配置:

		
注意:所有的适配器都是实现了HandlerAdapter接口

程序员编写Handler要根据所配置的适配器的要求编写。
SimpleControllerHandlerAdapter适配器要求:通过supports方法知道Handler必须要实现哪个接口
查看HandlerAdapter(适配器接口)源代码如下:
public interface HandlerAdapter {
	// 已经去除文档注释
	boolean supports(Object handler); 
		
	ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;

	long getLastModified(HttpServletRequest request, Object handler);

}
查看SimpleControllerHandlerAdapter适配器源码如下:
public class SimpleControllerHandlerAdapter implements HandlerAdapter {

	public boolean supports(Object handler) {
		return (handler instanceof Controller);
	}

	public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		return ((Controller) handler).handleRequest(request, response);
	}

	public long getLastModified(HttpServletRequest request, Object handler) {
		if (handler instanceof LastModified) {
			return ((LastModified) handler).getLastModified(request);
		}
		return -1L;
	}

}
可以发现 SimpleControllerHandlerAdapter类型的处理器适配器通过support方法根据Handler对象是否实现了Controller接口来进行判断是否支持Handler,凡是实现了Controller接口的类都可以被简单类型的处理器适配器匹配调用,简单处理器适配器通过在handle方法中调用Handler实现Controller接口的HandleRequest方法向前端控制器返回ModelAndView。

Handler的编写

需要实现Controller接口
public class ItemController1 implements Controller {

	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// 使用静态数据将商品信息展示在jsp页面上
		// 商品列表
		List itemsList = new ArrayList();

		Items items_1 = new Items();
		items_1.setName("联想笔记本");
		items_1.setPrice(6000f);
		items_1.setCreatetime(new Date());
		items_1.setDetail("ThinkPad T430 联想笔记本电脑!");

		Items items_2 = new Items();
		items_2.setName("苹果手机");
		items_2.setPrice(5000f);
		items_2.setDetail("iphone6苹果手机!");

		itemsList.add(items_1);
		itemsList.add(items_2);

		ModelAndView modelAndView = new ModelAndView();
		// 将数据填充到request
		// request.setAttribute("itemList", itemsList);
		modelAndView.addObject("itemsList", itemsList);
		// 指定转发到JSP页面
		modelAndView.setViewName("/WEB-INF/jsp/itemsList.jsp");
		return modelAndView;
	}

}

配置Handler

在springmvc.xml中配置Handler,由Spring管理Handler。

        

配置视图解析器

配置视图解析,能够解析jsp视图

		
		

工程部署

访问:http://localhost:8080/springmvc_first/itemList.action
JAVAWEB开发之SpringMVC详解(一)——SpringMVC的框架原理、架构简介、与mybatis整合和注解方式的使用、_第6张图片

异常

地址中Handler名称输入错误

HandlerMapping没有找到Handler,message中不显示jsp路径,这种错误一般是由于输入地址操作导致
JAVAWEB开发之SpringMVC详解(一)——SpringMVC的框架原理、架构简介、与mybatis整合和注解方式的使用、_第7张图片

要转向的JSP页面不存在

JAVAWEB开发之SpringMVC详解(一)——SpringMVC的框架原理、架构简介、与mybatis整合和注解方式的使用、_第8张图片

其它非注解处理器映射器和适配器

BeanNameUrlHandlerMapping(映射器)

根据请求url (xxx.action)匹配Spring容器中bean的name
找到对应的bean(程序编写的Handler)

SimpleUrlHandlerMapping(映射器)


	
		
			
				itemController1
				itemController1
			
		
	
注意:在springmvc.xml中配置了多个处理器映射器,多个处理器映射器就可以共存,不会排斥

SimpleControllerHandlerAdapter(适配器)

要求程序编写的Handler (controller)需要实现Controller接口。

HttpRequestHandlerAdapter(适配器)

在springmvc.xml中配置:HttpRequestHandlerAdapter
要求编写的Handler实现 HttpRequestHandler接口

配置HttpRequestHandlerAdapter适配器


	

开发Handler

public class ItemController2 implements HttpRequestHandler {

	public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 使用静态数据将商品信息展示在jsp页面上
		// 商品列表
		List itemsList = new ArrayList();

		Items items_1 = new Items();
		items_1.setName("联想笔记本");
		items_1.setPrice(6000f);
		items_1.setCreatetime(new Date());
		items_1.setDetail("ThinkPad T430 联想笔记本电脑!");

		Items items_2 = new Items();
		items_2.setName("苹果手机");
		items_2.setPrice(5000f);
		items_2.setDetail("iphone6苹果手机!");

		itemsList.add(items_1);
		itemsList.add(items_2);
		
		request.setAttribute("itemsList", itemsList);
		request.getRequestDispatcher("/WEB-INF/jsp/itemsList.jsp").forward(request, response);
	}

}
可以发现。HttpRequestHandler的开发方式和原始的Servlet开发方式很相近

配置Handler

 
	
使用简单URL映射器

	
		
			
				itemController1
				itemController2
			
		
	

DispatcherServlet.properties

JAVAWEB开发之SpringMVC详解(一)——SpringMVC的框架原理、架构简介、与mybatis整合和注解方式的使用、_第9张图片

DispatcherServlet前端控制器加载DispatcherServlet.properties配置文件,从而默认加载各个组件。
如果在springmvc.xml中配置了处理器映射器和适配器,以springmvc.xml的为准。

注解映射器和适配器

注解映射器

Spring3.1之前默认加载器是org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping,3.1之后要使用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping。
在springmvc.xml中配置RequestMappingHandlerMapping:

	
使用RequestMappingHandlerMapping 注解映射器需要在Handler中使用@Controller标识此类是一个控制器,使用@RequestMapping指定Handler方所对应的url。

注解适配器

Spring3.1之前默认加载映射器是org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter,3.1之后要使用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
RequestMappingHandlerAdapter 注解适配器不要求Handler实现任何接口,但它需要和RequestMappingHandlerMapping注解映射器配对使用,主要解析Handler方法中的形参。在springmvc.xml中配置RequestMappingHandlerAdapter如下:

	

注解开发Handler

@Controller
public class ItemController3 {
    // 商品列表,@RequestMapping中的url建议和方法名一致,方便开发维护
	@RequestMapping("/queryItems")
	public ModelAndView queryItems() throws ServletException, IOException {
		// 使用静态数据将商品信息展示在jsp页面上
		// 商品列表
		List itemsList = new ArrayList();

		Items items_1 = new Items();
		items_1.setName("联想笔记本");
		items_1.setPrice(6000f);
		items_1.setCreatetime(new Date());
		items_1.setDetail("ThinkPad T430 联想笔记本电脑!");

		Items items_2 = new Items();
		items_2.setName("苹果手机");
		items_2.setPrice(5000f);
		items_2.setDetail("iphone6苹果手机!");

		itemsList.add(items_1);
		itemsList.add(items_2);
		
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.addObject("itemsList",itemsList);
		// 指定逻辑视图名
		modelAndView.setViewName("/WEB-INF/jsp/itemsList.jsp");
		
        return modelAndView;
	}

}

配置Handler


    
    
    
建议使用组件扫描,组件扫描可以扫描@Controller、@Service、@Component、@Repository
注意:要想使用注解扫描器,Spring的版本要在4.0以上,不然会抛出异常

小结

DispatcherServlet:前端控制器,相当于中央调度器,可以降低组件之间的耦合度。
HandlerMapping:处理器映射器,负责根据url查找Handler。
HandlerAdapter:处理器适配器,负责根据适配器要求的规则去执行处理器。可以通过扩展适配器支持不同类型的Handler。
ViewResolver:视图解析器,根据逻辑视图名解析成真正的视图。

	
		
		
	
真正的视图地址=前缀+逻辑视图名+后缀
注意:逻辑视图名只是在ModelAndView对象中设置视图时适用,对于原始的Servlet(使用request和response进行转发或重定向)不适用。

执行过程中关键源代码如下:
1.DispatcherServlet通过HandlerMapping查找Handler
JAVAWEB开发之SpringMVC详解(一)——SpringMVC的框架原理、架构简介、与mybatis整合和注解方式的使用、_第10张图片
2.DispatcherServlet通过适配器去执行Handler,得到ModelAndView (在DispatcherServlet中的doDispatch方法中执行整个流程)

3.视图解析
视图解析后得到一个view
JAVAWEB开发之SpringMVC详解(一)——SpringMVC的框架原理、架构简介、与mybatis整合和注解方式的使用、_第11张图片
4.进行视图渲染
所谓的视图渲染就是将Model中的数据填充到request域

springmvc入门源码

代码已经上传GitHub https://github.com/LX1993728/springmvc_first
JAVAWEB开发之SpringMVC详解(一)——SpringMVC的框架原理、架构简介、与mybatis整合和注解方式的使用、_第12张图片JAVAWEB开发之SpringMVC详解(一)——SpringMVC的框架原理、架构简介、与mybatis整合和注解方式的使用、_第13张图片

web.xml


	springmvc_first
	
	
		springmvc
		org.springframework.web.servlet.DispatcherServlet
		
		
			
			
			contextConfigLocation
			classpath:springmvc.xml
		
	
	
		springmvc
		
		*.action
	
	
		index.html
		index.htm
		index.jsp
		default.html
		default.htm
		default.jsp
	
springmvc.xml



	
	
    
    
	
    
    
    
    
    
   

	
	
	

	
	
		
			
				itemController1
				itemController2
			
		
	
	
	
	

	
	
	
	
	

	
	

	
	
		
		
	
		
itemsList.jsp
<%@ 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"%>




查询商品列表

 
查询条件:
商品列表:
商品名称 商品价格 生产日期 商品描述 操作
${item.name } ${item.price } ${item.detail } 修改
ItemController1.java
package lx.springmvc.first;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import lx.springmvc.po.Items;

/**
 * 入门程序,商品列表查询
 * 
 * @author liuxun
 *
 */
public class ItemController1 implements Controller {

	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// 使用静态数据将商品信息展示在jsp页面上
		// 商品列表
		List itemsList = new ArrayList();

		Items items_1 = new Items();
		items_1.setName("联想笔记本");
		items_1.setPrice(6000f);
		items_1.setCreatetime(new Date());
		items_1.setDetail("ThinkPad T430 联想笔记本电脑!");

		Items items_2 = new Items();
		items_2.setName("苹果手机");
		items_2.setPrice(5000f);
		items_2.setDetail("iphone6苹果手机!");

		itemsList.add(items_1);
		itemsList.add(items_2);

		ModelAndView modelAndView = new ModelAndView();
		// 将数据填充到request
		// request.setAttribute("itemList", itemsList);
		modelAndView.addObject("itemsList", itemsList);
		// 指定转发到JSP页面
		modelAndView.setViewName("/WEB-INF/jsp/itemsList.jsp");
		return modelAndView;
	}

}
ItemController2.java
package lx.springmvc.first;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.HttpRequestHandler;

import lx.springmvc.po.Items;

/**
 * 入门程序,商品列表查询
 * 
 * @author liuxun
 *
 */
public class ItemController2 implements HttpRequestHandler {

	public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 使用静态数据将商品信息展示在jsp页面上
		// 商品列表
		List itemsList = new ArrayList();

		Items items_1 = new Items();
		items_1.setName("联想笔记本");
		items_1.setPrice(6000f);
		items_1.setCreatetime(new Date());
		items_1.setDetail("ThinkPad T430 联想笔记本电脑!");

		Items items_2 = new Items();
		items_2.setName("苹果手机");
		items_2.setPrice(5000f);
		items_2.setDetail("iphone6苹果手机!");

		itemsList.add(items_1);
		itemsList.add(items_2);

		request.setAttribute("itemsList", itemsList);
		request.getRequestDispatcher("/WEB-INF/jsp/itemsList.jsp").forward(request, response);
	}

}
ItemController3.java
package lx.springmvc.first;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletException;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import lx.springmvc.po.Items;

/**
 * 入门程序,商品列表查询
 * 
 * @author liuxun
 *
 */
@Controller
public class ItemController3 {
    // 商品列表,@RequestMapping中的url建议和方法名一致,方便开发维护
	@RequestMapping("/queryItems")
	public ModelAndView queryItems() throws ServletException, IOException {
		// 使用静态数据将商品信息展示在jsp页面上
		// 商品列表
		List itemsList = new ArrayList();

		Items items_1 = new Items();
		items_1.setName("联想笔记本");
		items_1.setPrice(6000f);
		items_1.setCreatetime(new Date());
		items_1.setDetail("ThinkPad T430 联想笔记本电脑!");

		Items items_2 = new Items();
		items_2.setName("苹果手机");
		items_2.setPrice(5000f);
		items_2.setDetail("iphone6苹果手机!");

		itemsList.add(items_1);
		itemsList.add(items_2);
		
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.addObject("itemsList",itemsList);
		// 指定逻辑视图名
		modelAndView.setViewName("itemsList");
		
        return modelAndView;
	}

}

SpringMVC和Mybatis整合工程搭建

整合思路

在Mybatis和Spring整合的基础上 添加springmvc
Spring要管理springmvc编写的Handler(controller)、mybatis的SqlSessionFactory、mapper
第一步:整合Dao,Spring和mybatis整合
第二步:整合Service,Spring管理Service接口,Service中可以调用Spring容器中的dao (mapper)
第三步:整合controller,Spring管理controller接口,在controller调用Service

导入jar包

mybatis:3.2.7
Spring:3.2.0
mybatis的jar
mybatis和Spring整合包
Spring的相关Jar包(包括SpringMVC的包)
数据库驱动包
log4j日志

工程结构

JAVAWEB开发之SpringMVC详解(一)——SpringMVC的框架原理、架构简介、与mybatis整合和注解方式的使用、_第14张图片

配置文件

applicationContext-dao.xml——配置数据源、SqlSessionFactory、mapper扫描器
applicationContext-service.xml——配置Service接口
applicationContext-transaction.xml——事务管理
springmvc.xml——SpringMVC的配置,配置处理器映射器、适配器、视图解析器
SqlMapConfig.xml——mybatis的配置文件,配置别名、settings、mapper

applicationContext-dao.xml

配置mybatis的数据源、sqlSessionFactory、mapper扫描器

	
	
	
      ${jdbc.driver}
      ${jdbc.url}
      ${jdbc.username}
      ${jdbc.password}
      
      
	
	
	
    
	    
	    
	    
	    
    
    
    
     
	     
	     
	     
	     
     

applicationContext-transaction.xml

在此配置文件配置事务,声明式事务控制

	
		
	

	
	
		
			
			
			
			
			
			
			
		
	

	
	
		
	

前端控制器配置


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

配置springmvc.xml


	

	
	

	
	

    
    

    
	
	
		
		
	

商品列表开发

需求

查询商品列表

mapper

功能描述:根据条件查询商品信息,返回商品列表
一般情况下对查询mapper需要自定义mapper
首先针对单表进行逆向工程,生成代码(包括PO类、mapper.xml、mapper.java)如下图所示:
JAVAWEB开发之SpringMVC详解(一)——SpringMVC的框架原理、架构简介、与mybatis整合和注解方式的使用、_第15张图片

mapper.xml

为了避免影响逆向工程生成的代码,一般不去修改,新建一个自定义的mapper(.xml和.java) 
新建ItemsMapperCustom.xml 添加如下配置

     
     	
     	 and name like '%${itemsCustom.name.trim()}%'
     	
     	
     		and id = #{itemsCustom.id}
     	
     
   
   
   
    

包装类:ItemsQueryVo

public class ItemsQueryVo {

	// 商品信息
	private ItemsCustom itemsCustom;

       // setter与getter
       ......
}

mapper.java

新建接口ItemsMapperCustom.java
// 商品查询列表
	public List findItemsList(ItemsQueryVo itemsQueryVo) throws Exception;

Service

public class ItemsServiceImpl implements ItemsService {
   
	// 注入mapper
	@Autowired
	private ItemsMapperCustom itemsMapperCustom;
	
	@Autowired
	private ItemsMapper itemsMapper;
	
	public List findItemsList(ItemsQueryVo itemsQueryVo) throws Exception {
		return itemsMapperCustom.findItemsList(itemsQueryVo);
	}

}

在applicationContext-service.xml中配置Service


   

controller

@Controller
public class ItemsController {

	// 注入Service
	@Autowired
	private ItemsService itemsService; 

	@RequestMapping("queryItems")
	public ModelAndView queryItems(HttpServletRequest request) throws Exception {

		// 调用Service查询商品列表
		List itemsList = itemsService.findItemsList(null);

		ModelAndView modelAndView = new ModelAndView();
		modelAndView.addObject("itemsList", itemsList);
		// 指定逻辑视图名
		modelAndView.setViewName("itemsList");

		return modelAndView;
	}
}

jsp


在web.xml中配置Spring监听器


	
		contextConfigLocation
		classpath:spring/applicationContext-*.xml 
	
	
		org.springframework.web.context.ContextLoaderListener
	

注解开发基础

商品修改

需求

功能描述:商品信息修改
操作流程:
1.在商品列表页面点击修改链接。
2.打开商品修改页面,显示了当前商品的信息。
(根据商品的id查询商品信息)
3.修改商品信息,点击提交
(更新商品信息)

mapper

已使用逆向工程生成代码:
根据商品id查询商品信息
更新商品信息

Service

// 根据商品id查询商品信息
	public ItemsCustom findItemsById(int id) throws Exception;
	
	// 更新商品信息
	/**
	 * 定义Service接口,遵循单一职责,将业务参数细化(不要使用包装类型,比如Map)
	 * @param id  修改商品的id
	 * @param itemsCustom  修改商品的信息
	 * @throws Exception
	 */
	public void updateItems(Integer id,ItemsCustom itemsCustom) throws Exception;

@RequestMapping

设置方法对应的url(完成url映射)

一个方法对应一个url
@RequestMapping("/queryItems")
	public ModelAndView queryItems(HttpServletRequest request) throws Exception {

窄化请求映射

在Class上定义根路径
@Controller
//定义url的根路径,访问时 根路径+方法的url
@RequestMapping("/items")
public class ItemsController {
好处:重新规范系统的url,避免url冲突

限制http请求的方法

通过requestMapping限制url请求的http方法
如果限制请求必须是post,如果get请求就会抛出异常
JAVAWEB开发之SpringMVC详解(一)——SpringMVC的框架原理、架构简介、与mybatis整合和注解方式的使用、_第16张图片

商品修改方法,限制为http的get:
@RequestMapping(value="/editItems",method={RequestMethod.GET})

controller方法返回值

返回ModelAndView

@RequestMapping("/queryItems")
	public ModelAndView queryItems(HttpServletRequest request) throws Exception {

		// 调用Service查询商品列表
		List itemsList = itemsService.findItemsList(null);

		ModelAndView modelAndView = new ModelAndView();
		modelAndView.addObject("itemsList", itemsList);
		// 指定逻辑视图名
		modelAndView.setViewName("itemsList");

		return modelAndView;
	}

返回字符串

如果controller方法返回JSP页面,可以简单将方法返回值类型定义为字符串,最终返回逻辑视图名称
//方法返回字符串,字符串就是逻辑视图名,Model作用就是将数据填充到request域,在页面展示
	@RequestMapping(value="/editItems",method={RequestMethod.GET})
	public String editItems(Model model) throws Exception{
		
		// 调用Service查询商品信息
		ItemsCustom itemsCustom = itemsService.findItemsById(1);
		//将模型数据传到jsp
		model.addAttribute("item", itemsCustom);

		return "editItem";
	}

返回void

// 方法返回void
	@RequestMapping(value="/editItems",method={RequestMethod.GET})
	public void editItems(HttpServletRequest request,HttpServletResponse response) throws Exception{
		
		// 调用Service查询商品信息
		ItemsCustom itemsCustom = itemsService.findItemsById(1);
		request.setAttribute("item", itemsCustom);
		// 注意如果使用request转向页面,这里指定页面的完整路径
		request.getRequestDispatcher("/WEB-INF/jsp/editItem.jsp").forward(request, response);
	}
使用此方法,容易输出json、xml格式的数据:
通过response指定响应结果,例如响应json数据如下:
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write("json串");

redirect重定向

如果方法重定向到另一个url,方法返回值为 "redirect:url路径",url路径一般指的具体的路径或别的请求路径 不能是虚拟视图名。
使用redirect进行重定向,request数据无法共享,url的地址栏会发生变化。

forward转发

使用forward进行请求转发,request数据可以共享,url地址栏不会改变。
方法返回值为"forward:url路径"

参数绑定

参数绑定过程

JAVAWEB开发之SpringMVC详解(一)——SpringMVC的框架原理、架构简介、与mybatis整合和注解方式的使用、_第17张图片

默认支持的参数类型

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

HttpServletRequest

通过request对象获取请求信息

HttpServletResponse

通过response处理响应信息

HttpSession

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

Model

通过model向页面传递数据,如下:
// 调用Service查询商品信息
		ItemsCustom itemsCustom = itemsService.findItemsById(id);
		//将模型数据传到jsp
		model.addAttribute("item", itemsCustom);
页面通过${item.xxx}获取对象的属性值

@RequestParam

如果request请求的参数名和controller方法的形参参数名一致,适配器自动进行参数绑定。如果不一致可以通过@RequestParam指定request请求的参数名(value属性)绑定到哪个方法形参上。
对于必须要传入的参数,通过@RequestParam中的属性required设置为true,设置后如果不传入此参数则会报错。
对于有些参数如果不传入,还需要设置默认值,使用@RequestParam中属性defaultvalue设置默认值。

可以绑定简单类型

可以绑定整型、字符串、单精/双精度、日期、布尔型

可以绑定简单pojo类型

简单pojo类型只包括简单类型的属性。
绑定过程:request请求的参数名称和pojo的属性名一致,就可以绑定成功。
问题:
如果controller方法形参中有多个pojo且pojo中有重复的属性,使用简单pojo绑定无法有针对性的绑定。
比如:方法形参中有items和User,pojo同时存name属性,从http请求过程的name无法有针对性的绑定到items或user。

可以绑定包装的pojo

包装的pojo里包括的pojo
页面参数定义:
JAVAWEB开发之SpringMVC详解(一)——SpringMVC的框架原理、架构简介、与mybatis整合和注解方式的使用、_第18张图片
包装类型的属性也是itemsCustom

按照上边的规则进行包装类型的绑定。

自定义绑定使用属性编辑器

SpringMVC没有提供对日期类型的绑定,需要自定义日期类型的绑定。

使用WebDataBinder(了解)

在controller类中定义
//自定义属性编辑器
	@InitBinder
	public void initBinder(WebDataBinder binder) throws Exception {
		// Date.class必须是与controler方法形参pojo属性一致的date类型,这里是java.util.Date
		binder.registerCustomEditor(Date.class, new CustomDateEditor(
				new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), true));
	}
使用这种方法是无法在多个controller共用

使用WebBindingInitializer(了解)

使用WebBindingInitializer让多个控制器共用属性编辑器
自定义WebBindingInitializer,注入到处理器适配器中。
如果想使多个controller共用属性编辑器,需要共同注册相同的属性编辑器,可以实现PropertyEditorRegistrar接口,并且注入到webBindingInitializer中。
编写CustomPropertyEditor
public class CustomPropertyEditor implements PropertyEditorRegistrar {

	public void registerCustomEditors(PropertyEditorRegistry binder) {
		binder.registerCustomEditor(Date.class,
				new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), true));
	}

}
在springmvc.xml中添加如下配置
     
       
    	
    	
       
	
	
		
		
			
				
			
		
	
	
	
	
配置步骤:
编写自定义转换器 实现PropertyEditorRegistrar接口
注册自定义的属性编辑器。
注册webBinder(org.springframework.web.bind.support.ConfigurableWebBindingInitializer类型),并将已经注册的属性编辑器注入到propertyEditorRegistrars的list属性集合中。
最后将已注册的webBinder注入到注解适配器中。

自定义参数绑定使用转换器(重点)

实现Converter接口

定义日期类型转换器和字符串去除前后空格的转换器

配置转换器

配置方式:
自定义转换器实现Converter 接口 K:原始数据类型  V:转换后的数据类型
自定义日期转换器
/**
 * 自定义日期转换器
 * @author liuxun
 *
 */
public class CustomDateConverter implements Converter {

	@Override
	public Date convert(String source) {
		
		// 进行日期转换
		try {
			return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(source);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}

}
自定义去空格转换器
/**
 * 自定义去除字符串前后空格的转换器
 * @author liuxun
 *
 */
public class StringTrimConverter implements Converter{

	@Override
	public String convert(String source) {
		
		//去掉字符串两边空格,如果去除后为空设置为null
		if (source!=null) {
			source = source.trim();
			if (source.equals("")) {
				return null;
			}
		}
		
		return source;
	}

}
配置如下
注册FormattingConversionServiceFactoryBean,并将自定义的转换器注入到converters数组属性中

	
		
			
				
				
			
		
	
并将注册的转换器注入到webBinder中

	
		
		
	
最后将其webBinder注入到注解适配器中
 
    
    	
    	
    

问题处理

post乱码

在web.xml中加入

	
		CharacterEncodingFilter
		org.springframework.web.filter.CharacterEncodingFilter
		
			encoding
			utf-8
		
	
	
		CharacterEncodingFilter
		/*
	
以上可解决post乱码问题

get乱码

对于get请求中文参数出现乱码解决方法有两个
修改Tomcat配置文件添加编码与工程一致 如下:
另外一种方法对参数进行重新编码:
String userName=new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")
ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码
(具体源码在第二篇中综合展示)

你可能感兴趣的:(JAVA,WEB基础知识,JAVAWEB开发)