SpringMVC1

SpringMVC让你的C层更加高效.

springMVC初次

  1. SpringMVC简介
  2. SpringMVC的执行流程
  3. SpringMVC的入门案例
  4. SpringMVC相关配置文件解析
  5. SpringMVC的参数绑定
  6. SpringMVC自定义类型转换器
  7. SpringMVC控制器方法的返回值处理
  8. SpringMVC的跳转以及重定向传值

springMVC简介

  1. springMVC本身也是基于对servlet进行了封装,也是轻量级的web开发框架之一
  2. 从使用角度来说,就是依赖大量的注解,达到传统意思上面MVC的Controller的功效

springMVC的执行流程

  • 一个请求匹配前端控制器 DispatcherServlet的请求映射路径(在web.xml中指定),WEB容器将该请求转交给DispatcherServlet * 处理DispatcherServlet 接收到请求后, 将根据请求信息交给处理器映射器(HandlerMapping)
  • HandlerMapping 根据用户的url请求 查找匹配该url的 Handler,并返回一个执行链
  • DispatcherServlet 再请求 处理器适配器(HandlerAdapter)调用相应的Handler进行处理并返回ModelAndView给DispatcherServlet
  • DispatcherServlet 将 ModelAndView 请求 ViewReslover(视图解析器)解析,返回具体 View
  • DispatcherServlet 对 View 进行渲染视图(即将模型数据填充至视图中)
  • DispatcherServlet 将页面响应给用户

用港剧的方式来说明下(港剧最喜欢的就是走私贩毒什么的 贩毒是暴利,需要周密的计划和设计,才能有获利)

  1. 现在有一批毒品进行货运 (梁朝伟负责) (梁朝伟不可能直接就联络到接收人) (用户发起一个http请求)
  2. 梁朝伟打电话问周润发,因为周润发那里有一个接收人联络官(黎明)(HandlerMapping),(这里周润发就等同于DispatcherServlet)
  3. 周润发告诉接收人联络官((黎明))之后,接收联络官那里有一个联络表,肯定不是明文显示,找到了对应的接收人(刘德华)(handler) 每个人都有自己接收的方式(刘德华也不例外)(也就是执行链),
  4. 但是你想,虽然无非就是梁朝伟去找刘德华,但是我们说的,一旦被抓就可能全盘完蛋,黎明和周润发都不可能直接和梁朝伟说,你去找谁。
  5. 所以刘德华(handler)会给(快递员HandlerAdapter)说我是接收人,然后周润发也来问我接收人是谁.我不知道那个是不是毒品。我只知道谁给我,我给谁.按照他们要求的方式进行打包(毒品伪装)(HttpMessageConveter数据转换)
  6. 1 我送达之后,会有一个回执单(上面是暗号)(modelandview),我会给周润发(DispatcherServlet)
  7. 周润发根据这个暗号,然后用心里默默记住的(ViewReslover)类似解码表进行解码
  8. 将所有的交易的信息,时间点(渲染+解析)交给了什么(梁朝伟吗?不是)交给了历史。(everybody都可以阅历历史)

设计代码,就是所谓的高内聚,低耦合


SpringMVC入门

  1. 新建项目,并且导入对应的jar包

IMAGE

  1. 页面中发起一个同步的请求 hello (梁朝伟)

  2. 在web.xml中 (周润发)

注意解决乱码可以配置/,但是可能会出现不生效的情况,所以建议填写(/*)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<!-- 处理POST提交乱码问题 -->
<filter>
<filter-name>encoding</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>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<!-- 前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 不使用 默认找 /WEB-INF/[servlet的名称(springmvc)]-servlet.xml -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>

3.1 完善联络关系表 springmvc.xml 在src下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd">
<!-- 扫描包以其子包下所有类的注解 @Controler @Service等 -->
<context:component-scan base-package="com.wwj"/>

<!-- 注解驱动 -->
<mvc:annotation-driven/>

<!-- 视图解释器 使用前后缀拼接跳转页面路径 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
  1. 编写controller 刘德华
1
2
3
4
5
6
7
8
9
10
11
@Controller
public class HelloController {
@RequestMapping("/hello")
public ModelAndView login(){
//处理业务逻辑
ModelAndView mv = new ModelAndView();
mv.addObject("pOne","wwj");
mv.setViewName("main");
return mv;
}
}

注意:如果在jsp页面使用el表达式,无法取值的话,可以在jsp抬头上面添加<%@ page isELIgnored =”false” %>


SpringMVC 相关配置文件解析(了解)

  • web.xml中添加了init-param 主要是调整我们的配置文件位置加载在src目录下

  • 关于url-pattern常用规则

  1. 使用url-pattern配置为 / 拦截所有的请求

  2. 使用(*.action或者*.do) 也就是加一个动作标签

  3. 如果使用/* 而我们访问的是一个/xxx.html 或者是 /xxx.jsp 的静态资源。那么拦截了之后,返回对应的设置的value=”/WEB-INF/jsp/“ 是无法找到的。

/并不是真正意义上的拦截所有请求,它不会拦截jsp的页面请求,其他的请求则会拦截
/*才是真正意义上的拦截所有请求


SpringMVC 的参数绑定的多种方式

分类

  1. 接收多个独立的参数
  2. 接收简单的对象类型(包含时间处理)
  3. 接收复杂的对象类型 (了解)
  4. 接收restful形式的参数 (理解)
  5. 接收json数据或者是json字符串
  1. 接收多个独立的参数
1
2
3
4
5
6
7
8
9
10
<form action="a1" method="post">
<input type="text" name="a"/>
<input type="text" name="b"/>
<button>提交</button>
</form>
//接收多值的参数
@RequestMapping("/a1")
public void login(@RequestParam(value="a") String a,@RequestParam(value="b") String b){
System.out.println(a+b);
}
  1. 接收简单的对象类型(处理时间类型)
1
2
3
4
5
6
public class Person  implements  Serializable{
private int pid;
private String name;
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date bir;
}
1
2
3
4
5
6
<form action="a2" method="post">
<input type="text" name="pid"/>
<input type="text" name="name"/>
<input type="text" name="bir"/>
<button>提交</button>
</form>
1
2
3
4
5
6
@RequestMapping("/a2")
public void login(Person p){
System.out.println(p.getPid());
System.out.println(p.getName());
System.out.println(p.getBir().toString());
}

注意:如果就只传递类似时间格式的字符串而又不包含的在对象中,可以考虑使用java库处理时间字符串,也可以使用全局的自定义转换器(了解)后续会讲到

  1. 接收复杂的对象类型 (了解)

对象中多添加List属性private List<String> dognames;

1
2
3
4
5
6
7
8
9
<form action="a3" method="post">
<input type="text" name="pid"/>
<input type="text" name="name"/>
<input type="text" name="bir"/>
<input type="text" name="dognames[0]"/>
<input type="text" name="dognames[1]"/>
<input type="text" name="dognames[2]"/>
<button>提交</button>
</form>
1
2
3
4
5
6
7
@RequestMapping("/a3")
public void login2(Person p){
System.out.println(p.getPid());
System.out.println(p.getName());
System.out.println(p.getBir().toString());
System.out.println(p.getDognames().size());
}
  1. 接收restful形式的参数 (理解)

何为restful /a4/pname/wwj/ 设计请求的api

1
<a href="a4/pname/wwj">hellrestful</a>
1
2
3
4
@RequestMapping(value="/a4/{pnameattr}/{name}")
public void login3(@PathVariable(value="pnameattr") String pnameattr,@PathVariable(value="name") String name){
System.out.println(pnameattr+name);
}

5.接收json数据或者是json字符串(需要先用到jquery ajax,暂时不设置返回,因为还需额外的jar包进行转换)

暂时先引入:
<script src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$(function(){
var user = {
uname : 'wwj',
uage : 18
}
$.ajax({
url: "a5",
type: "post",
dataType:'json',
data: user,
success: function (json) {

}
})
})
//后台接收
@RequestMapping("/a5")
public void login4(@RequestParam("uname") String uname,@RequestParam("uage") String uage){
System.out.println(uname+uage);

}

注意:这种方式不推荐,也就是ajax传递json的字符串,而不是对象,那么需要在ajax中设置 contentType : ‘application/json;charset=utf-8’

赋值参数绑定

  1. 直接使用原生的servlet对象以及model(等同于设置到request作用域中)
1
2
3
@RequestMapping("/a6")
public void login5(HttpServletRequest req ,HttpServletResponse resp,Model model){
}

modelView和modelMap不推荐


自定义转换类型(处理时间类型)

1.定义转换器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.springframework.core.convert.converter.Converter;

public class StringToDate implements Converter<String,Date>{

@Override
public Date convert(String arg0) {
// TODO Auto-generated method stub
try {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date date = simpleDateFormat.parse(arg0);
return date;
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
  1. 注解驱动添加
1
2
3
4
5
6
7
8
9
	<!-- 注解驱动 -->
<mvc:annotation-driven conversion-service="conversionService"/>
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.wwj.convert.StringToDate"></bean>
</set>
</property>
</bean>

将前面对象属性中提供的注解去掉即可


SpringMVC 控制器方法的返回值处理

IMAGE


SpringMVC 的跳转 (了解)

  1. 如果使用void 采用原生servletAPI中进行请求转发和重定向即可

  2. 使用springMVC提供的快捷方式

  • return “redirect: 资源路径 “;
  • return “forward: 资源路径 “;
1
2
3
4
5
@RequestMapping("/a6")
public String login5(HttpServletRequest req ,HttpServletResponse resp,Model model){
System.out.println(111);
return "redirect: main.jsp";
}
  1. 重定向传值(了解,需要借助RedirectAttributes属性)
1
2
3
4
5
@RequestMapping("/a6")
public String login5(RedirectAttributes rs){
rs.addAttribute("pname","wwj");
return "redirect: index.jsp";
}

注意观察地址栏的变化

不想参数暴露

1
2
3
4
5
6
@RequestMapping("/a6")
public String login5(RedirectAttributes rs){
//rs.addAttribute("pname","wwj");
rs.addFlashAttribute("pname", "wwj");
return "redirect: index.jsp";
}

然后新的请求接收值的时候 一定使用@ModelAttribute String pname