您的位置:首页 > 编程语言 > Java开发

spring mvc+mybatis笔记(二)

2016-11-30 14:56 344 查看
spring MVC部分



一、处理请求的流程



1、  首先用户发送请求——>DispatcherServlet,前端控制器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制;
2、  DispatcherServlet——>HandlerMapping,DispatcherServlet 接收到请求后, 将根据请求信息(包括 URL、 HTTP 方法、请求头、请求参数、 Cookie 等)及 HandlerMapping 的配置找到处理请求的处理器(Handler).可将 HandlerMapping 看成路由控制器,将 Handler 看成目标主机;
3、  DispatcherServlet——>HandlerAdapter,通过 HandlerAdapter 对 Handler 进行封装,再以统一的适配器接口调用 Handler从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;
4、  HandlerAdapter——>处理器功能处理方法的调用,HandlerAdapter将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView对象(包含模型数据、逻辑视图名);
5、  ModelAndView的逻辑视图名——> ViewResolver, ViewResolver将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术;
6、  View——>渲染,View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构,因此很容易支持其他视图技术;
7、返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。

二、相关注解说明

@Controller:声明控制器

@Service: 声明Service组

@Repository: 声明Dao组件

@Component:泛指组件(不推荐)

@RequestMapping:将URL映射到整个类或特定的方法上

consumes-指定处理请求的提交内容类型Content-Type,例如 application/json,text/html。

produces-指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回。

value-指定请求的实际地址,指定的地址可以是URI Template 模式。

params-指定request中必须包含某些参数值是,才让该方法处理。

headers-指定request中必须包含某些指定的header值,才能让该方法处理请求。

method-指定请求方式,枚举类RequestMethod。

@Transactional:事务管理(参考:http://www.cnblogs.com/caoyc/p/5632963.html)

事物传播行为介绍:

  @Transactional(propagation=Propagation.REQUIRED) :如果有事务, 那么加入事务, 没有的话新建一个(默认情况下)

  @Transactional(propagation=Propagation.NOT_SUPPORTED) :容器不为这个方法开启事务

  @Transactional(propagation=Propagation.REQUIRES_NEW) :不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务

  @Transactional(propagation=Propagation.MANDATORY) :必须在一个已有的事务中执行,否则抛出异常

  @Transactional(propagation=Propagation.NEVER) :必须在一个没有的事务中执行,否则抛出异常

  @Transactional(propagation=Propagation.SUPPORTS) :如果其他bean调用这个方法,在其他bean中声明事务,那就用事务.如果其他bean没有声明事务,那就不用事务.

事务隔离级别:

       @Transactional(isolation = Isolation.DEFAULT):使用数据库默认的隔离级别(默认情况下)

  @Transactional(isolation = Isolation.READ_UNCOMMITTED):读取未提交数据(会出现脏读, 不可重复读) 基本不使用

  @Transactional(isolation = Isolation.READ_COMMITTED):读取已提交数据(会出现不可重复读和幻读)

  @Transactional(isolation = Isolation.REPEATABLE_READ):可重复读(会出现幻读)

  @Transactional(isolation = Isolation.SERIALIZABLE):串行化

大多数数据库的默认隔离级别为: Read Commited,如Sql Server , Oracle.

少数数据库默认的隔离级别为Repeatable Read, 如MySQL InnoDB存储引擎

@Resource:  用于注入,( j2ee提供的 ) 默认按名称装配,找不到再按照类型

@Autowired: 用于注入, 默认按类型装配

@PathVariable:注解方法参数并将其绑定到URI模板变量的值。例如:

@ResponseBody
@RequestMapping(value="load_{name}",produces="application/json;charset=UTF-8")
public String loadAddress(@PathVariable("name") String name, HttpServletRequest request,HttpServletResponse response) {
String id = request.getParameter("id");
UsrAddress add = addressService.loadPrimaryAddress(Long.valueOf(id), 1L);
System.out.println(name);
return JSON.toJSONString(add);
}

@RequestParam:将请求的参数绑定到方法中的参数上。其实即使不配置该参数,注解也会默认使用该参数

@RequestBody:用于content type为json格式请求,可以将请求的json内容,转为javabean。例如:

@ResponseBody
@RequestMapping(value="test",produces="application/json;charset=UTF-8")
public String test(@RequestBody UsrAddress add,HttpServletRequest request,HttpServletResponse response) {
System.out.println(add.getProvince());
return JSON.toJSONString(add);
}
@ResponseBody:返回的数据不是页面,而是其他文本格式的数据时(如json、xml等)。注意与RequestBody的区别,RequestBody是用于请求数据是json/xml。
@RequestHeader:可以把Request请求header部分的值绑定到方法的参数上。例如:
@ResponseBody
@RequestMapping(value="test",produces="application/json;charset=UTF-8")
public String test(@RequestHeader("Accept-Encoding") String encoding,HttpServletRequest request,HttpServletResponse response) {
System.out.println(encoding);
return "";
}
@CookieValue:可以把请求中关于cookie的值绑定到方法的参数上
@SessionAttributes:把数据存储到session中。例如:
@Controller
@RequestMapping(value = "/address")
@SessionAttributes("address")
public class AddressController {
@Resource
private IAddressService addressService;

@RequestMapping(value="test")
public String test(ModelMap map) {
UsrAddress  address=new UsrAddress();
address.setProvince("02");
map.put("address", address);
return "success";
}
}

@ModelAttribute:可以作用在方法或方法参数上,当它作用在方法上时,该Controller的所有方法在调用前,先执行此@ModelAttribute注解的方法;当作用在方法参数上时,会把请求的参数,赋值到javabean对象,另外还可以从session中取值。例如:

@ResponseBody
@RequestMapping(value="test1",produces="application/json;charset=UTF-8")
public String test1(@ModelAttribute("address") UsrAddress  address,HttpServletRequest request,HttpServletResponse response) {
System.out.println(address.getProvince());
return JSON.toJSONString(address);
}

三、拦截器

1、继承HandlerInterceptorAdapter,重写需要的方法:

preHandle:该方法将在Controller处理之前进行调用

postHandle:在Controller的方法调用之后,DispatcherServlet进行视图的渲染之前执行,可以修改ModelAndView(preHandle方法的返回值为true时才会执行)

afterCompletion:方法将在整个请求完成之后,也就是DispatcherServlet渲染了视图执行,主要作用是用于清理资源(preHandle方法的返回值为true时才会执行)

afterConcurrentHandlingStarted():这个方法会在Controller方法异步执行时开始执行, 而Interceptor的postHandle方法则是需要等到Controller的异步执行完才能执行。

注:有多个拦截器满足时,先要执行全部拦截器的preHandle,再执行全部拦截器的postHandle,最后执行全部的afterCompletion。执行单个preHandle顺序是按照配置拦截器的先后,执行postHandle和afterCompletion顺序跟配置相反。

2.配置spring-mvc.xml

<mvc:interceptors>
<!-- 使用bean定义一个Interceptor,直接定义在mvc:interceptors根下面的Interceptor将拦截所有的请求 -->
<bean class="com.lzj.test.interceptor.AllInterceptor"/>
<mvc:interceptor>
<mvc:mapping path="/address/test1.do"/>
<!-- 定义在mvc:interceptor下面的表示是对特定的请求才进行拦截的 -->
<bean class="com.lzj.test.interceptor.Interceptor1"/>
</mvc:interceptor>
</mvc:interceptors>

3.过滤器和拦截器的区别

拦截器是基于Java的反射机制的,而过滤器是基于函数回调。

拦截器不依赖与servlet容器,归spring管理可以使用spring的资源;过滤器依赖与servlet容器

拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用

拦截器更灵活可以多次被调用,而过滤器只能在容器初始化时被调用一次

四、容器启动初始化

1.实现spring接口 ApplicationListener<ContextRefreshedEvent>,重写onApplicationEvent方法,实现自己的初始化逻辑

2.spring 配置文件定义bean

<bean class="com.lzj.test.listener.InitListener"/>

五、文件上传

1.spring配置文件定义CommonsMultipartResolver

<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 默认编码 -->
<property name="defaultEncoding" value="utf-8" />
<!-- 文件大小最大值 -->
<property name="maxUploadSize" value="10485760000" />
<!-- 内存中的最大值 -->
<property name="maxInMemorySize" value="40960" />
</bean>
2.Controller代码

@RequestMapping("springUpload")
public String springUpload(HttpServletRequest request) {
try {
long startTime = System.currentTimeMillis();
// 将当前上下文初始化给 CommonsMutipartResolver (多部分解析器)
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
request.getSession().getServletContext());
// 检查form中是否有enctype="multipart/form-data"
if (multipartResolver.isMultipart(request)) {
// 将request变成多部分request
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
// 获取multiRequest 中所有的文件名
Iterator iter = multiRequest.getFileNames();
while (iter.hasNext()) {
// 一次遍历所有文件
MultipartFile file = multiRequest.getFile(iter.next().toString());
if (file != null) {
String path = "D:/"	+ file.getOriginalFilename();
// 上传
file.transferTo(new File(path));
}
}
}
long endTime = System.currentTimeMillis();
System.out.println("运行时间:" + String.valueOf(endTime - startTime) + "ms");
} catch (Exception e) {
e.printStackTrace();
}
return "success";
}
3.jsp页面

<form name="Form" action="springUpload.do" method="post"  enctype="multipart/form-data">
<h1>使用spring mvc提供的类的方法上传文件</h1>
<input type="file" name="file">
<input type="submit" value="upload"/>
</form>

六、其他

1.Controller跳转其他Controller

return的String为“redirect:/xx/xx.do”
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: