三层架构
1. 使用简单
2.性能突出
3.灵活性强
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<maven.compiler.source>1.8maven.compiler.source>
<maven.compiler.target>1.8maven.compiler.target>
properties>
<dependencies>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>3.1.0version>
<scope>providedscope>
dependency>
<dependency>
<groupId>javax.servlet.jspgroupId>
<artifactId>jsp-apiartifactId>
<version>2.1version>
<scope>providedscope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.1.9.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webartifactId>
<version>5.1.9.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.1.9.RELEASEversion>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.mavengroupId>
<artifactId>tomcat7-maven-pluginartifactId>
<version>2.1version>
<configuration>
<port>80port>
<path>/path>
configuration>
plugin>
plugins>
build>
<servlet>
<servlet-name>DispatcherServletservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath*:spring_mvc.xmlparam-value>
init-param>
servlet>
<servlet-mapping>
<servlet-name>DispatcherServletservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.itheima"/>
<mvc:default-servlet-handler/>
beans>
@Controller
public class UserController {
//设定当前方法的访问映射地址
@RequestMapping("/abc")
//设置当前方法返回值类型为String,用于指定请求完成后跳转的页面
public String save(){
System.out.println("user mvc controller is running ...");
//设定具体跳转的页面
return "success.jsp";
}
@RequestMapping("/hello")
public String hello(String param) {
System.out.println(param);
return "success.jsp";
}
}
服务器启动:
tomcat启动加载web.xml
1. 加载web.xml中的DispatcherServlet
2. 读取spring xml中的配置,加载所有com.itheima包中所有标记为bean 的类
3.读取bean中方法上标注@RequestMapping的内容
处理请求:
1.DispatcherServlet 配置拦截所有请求 /
2.使用请求路径与所有加载的@RequestMapping的内容进行对比
3.执行对应的方法
4.根据方法法的返回值在webapp目录查找对应的页面并展示
说明:
<filter>
<filter-name>characterEncodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
filter>
<filter-mapping>
<filter-name>characterEncodingFilterfilter-name>
<url-pattern>/url-pattern>
filter-mapping>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.mavengroupId>
<artifactId>tomcat7-maven-pluginartifactId>
<version>2.1version>
<configuration>
<port>80port>
<path>/path>
<uriEncoding>UTF-8uriEncoding>
configuration>
plugin>
plugins>
build>
<context:component-scan base-package="com.itheima">
<context:include-filter expression="org.springframework.stereotype.Controller"/>
context:component-scan>
@Configuration //标明这是一个配置类
@ComponentScan(value = "com.itheima", //里选择包含模式,排除模式,需要排除的选项太多
includeFilters =@ComponentScan.Filter(type=FilterType.ANNOTATION,
classes = {Controller.class})
)
public class SpringMVCConfiguration implements WebMvcConfigurer{ }
业务层与数据层bean加载由Spring控制,
表现层bean加载由SpringMVC单独控制
1.表现层处理器bean使用注解@Controller声明
2.bean加载控制使用包含性过滤器
3.过滤器类型为通过注解进行过滤
4.过滤的注解名称为Controller
<mvc:resources mapping="/img/**" location="/img/"/>
<mvc:resources mapping="/js/**" location="/js/"/>
<mvc:default-servlet-handler/>
@Configuration
@ComponentScan(value = "com.itheima",includeFilters =
@ComponentScan.Filter(type=FilterType.ANNOTATION,classes = {Controller.class})
)
public class SpringMVCConfiguration implements WebMvcConfigurer{
/*覆盖原有的默认功能
注解配置放行指定资源格式
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/img/**").addResourceLocations("/img/");
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
} */
//注解配置通用放行资源的格式
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
//创建Servlet容器时,使用注解的方式加载SPRINGMVC配置类中的信息,并加载成WEB专用的ApplicationContext对象
//该对象放入了ServletContext范围,后期在整个WEB容器中可以随时获取调用
@Override
protected WebApplicationContext createServletApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringMVCConfiguration.class);
return ctx;
/* 代替web.xml中的下面注释配置 加载springmvc核心配置类
DispatcherServlet
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath*:spring-mvc.xml
*/
}
//注解配置映射地址方式,服务于SpringMVC的核心控制器DispatcherServlet
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
@Override
protected WebApplicationContext createRootApplicationContext() {
return null;
}
//乱码处理作为过滤器,在servlet容器启动时进行配置,相关内容参看Servlet零配置
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
// 调用父类的 onStartu
super.onStartup(servletContext);
//1. 创建字符集过滤器对象
CharacterEncodingFilter cef = new CharacterEncodingFilter();
//2. 设置使用的字符集
cef.setEncoding("UTF-8");
//3. 添加到容器(它不是 ioc 容器,而是 ServletContainer )
FilterRegistration.Dynamic registration = servletContext.addFilter("characterEncodingFilter", cef);
//4. 添加映射
registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST,DispatcherType.FORWARD,DispatcherType.INCLUDE),false,"/*");
}
}
普通类型参数
POJO类型参数
数组类型参数
集合类型参数
//方法传递普通类型参数,数量任意,类型必须匹配 参数名与处理器方法形参名保持一致
//http://localhost/requestParam1?name=itheima
//http://localhost/requestParam1?name=itheima&age=14
@RequestMapping("/requestParam1")
public String requestParam1(String name,int age){
System.out.println(name+","+age);
return "page.jsp";
}
名称:@RequestParam
类型:形参注解
位置:处理器类中的方法形参前方
作用:绑定请求参数与对应处理方法形参间的关系
//方法传递普通类型参数,使用@RequestParam参数匹配URL传参中的参数名称与方法形参名称
//http://localhost/requestParam2?userName=Jock //访问路径
@RequestMapping("/requestParam2")
public String requestParam2(@RequestParam(value = "userName",
// required=true表示必须带有参数 否则无法访问报错
required = true) String name){
System.out.println(name);
return "page.jsp";
}
//方法传递POJO类型参数,URL地址中的参数作为POJO的属性直接传入对象
//http://localhost/requestParam3?name=Jock&age=39
@RequestMapping("/requestParam3")
public String requestParam3(User user){
System.out.println(user);
return "page.jsp";
}
//当方法参数中具有POJO类型参数与普通类型参数嘶,URL地址传入的参数不仅给POJO对象属性赋值,也给方法的普通类型参数赋值
//http://localhost/requestParam4?name=Jock&age=39
@RequestMapping("/requestParam4")
public String requestParam4(User user,int age){
System.out.println("user="+user+",age="+age);
return "page.jsp";
}
//使用对象属性名.属性名的对象层次结构可以为POJO中的POJO类型参数属性赋值
//http://localhost/requestParam5?address.city=beijing
@RequestMapping("/requestParam5")
public String requestParam5(User user){
System.out.println(user.getAddress().getCity());
return "page.jsp";
}
//通过URL地址中同名参数,可以为POJO中的集合属性进行赋值,集合属性要求保存简单数据
//http://localhost/requestParam6?nick=Jock1&nick=Jockme&nick=zahc
@RequestMapping("/requestParam6")
public String requestParam6(User user){
System.out.println(user);
return "page.jsp";
}
//POJO中List对象保存POJO的对象属性赋值,使用[数字]的格式指定为集合中第几个对象的属性赋值
//http://localhost/requestParam7?addresses[0].city=beijing&addresses[1].province=hebei
@RequestMapping("/requestParam7")
public String requestParam7(User user){
System.out.println(user.getAddresses());
return "page.jsp";
}
//POJO中Map对象保存POJO的对象属性赋值,使用[key]的格式指定为Map中的对象属性赋值
//http://localhost/requestParam8?addressMap['job'].city=beijing&addressMap['home'].province=henan
@RequestMapping("/requestParam8")
public String requestParam8(User user){
System.out.println(user.getAddressMap());
return "page.jsp";
}
//方法传递普通类型的数组参数,URL地址中使用同名变量为数组赋值
//http://localhost/requestParam9?nick=Jockme&nick=zahc
@RequestMapping("/requestParam9")
public String requestParam9(String[] nick){
System.out.println(nick[0]+","+nick[1]);
return "page.jsp";
}
//方法传递保存普通类型的List集合时,无法直接为其赋值,需要使用@RequestParam参数对参数名称进行转换
//http://localhost/requestParam10?nick=Jockme&nick=zahc
@RequestMapping("/requestParam10")
public String requestParam10(@RequestParam("nick") List<String> nick){
System.out.println(nick);
return "page.jsp";
}
<mvc:annotation-driven conversion-service="conversionService"/>
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="formatters">
<set>
<bean class="org.springframework.format.datetime.DateFormatter">
<property name="pattern" value="yyyy-MM-dd"/>
bean>
set>
property>
bean>
@DateTimeFormat
类型:形参注解,成员变量注解
位置:形参前面 或 成员变量 上方
示例1
public String requestParam12(@DateTimeFormat(pattern = "yyyy-MM-dd") Date date){
System.out.println("date="+date);
return "page.jsp";
}
示例2
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birthday;
注意:依赖注解驱动支持
<mvc:annotation-driven/>
//数据类型转换,使用自定义格式化器或@DateTimeFormat注解设定日期格式
//两种方式都依赖springmvc的注解启动才能运行
//http://localhost/requestParam11?date=1999-09-09
@RequestMapping("/requestParam11")
public String requestParam11(@DateTimeFormat(pattern = "yyyy-MM-dd") Date date){
System.out.println(date);
return "page.jsp";
}
//自定义类型转换器,实现Converter接口,接口中指定的泛型即为最终作用的条件
//本例中的泛型填写的是String,Date,最终出现字符串转日期时,该类型转换器生效
public class MyDateConverter implements Converter<String, Date> {
//重写接口的抽象方法,参数由泛型决定
public Date convert(String source) {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
Date date = null;
//类型转换器无法预计使用过程中出现的异常,因此必须在类型转换器内部捕获,不允许抛出,框架无法预计此类异常如何处理
try {
date = df.parse(source);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
}
<mvc:annotation-driven conversion-service="conversionService"/>
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.itheima.converter.MyDateConverter"/>
set>
property>
bean>
方法注解 @RequestMapping
位置: 处理器类中的方法定义上方
作用: 绑定请求地址与对应处理方法间的关系
@RequestMapping("/requestURL1")
public String requestURL1() {
return "page.jsp";
}
类注解 @RequestMapping
位置: 处理器类定义上方
作用: 绑定请求地址与对应处理方法间的关系
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/requestURL2")
public String requestURL2() {
return "page.jsp";
}
}
访问路径/user/requestURL1
//带有类映射地址访问格式,需要将类映射地址作为前缀添加在实际映射地址的前面
//最终返回的页面如果未设定绝对访问路径,将从类映射地址所在目录中查找
//http://localhost/user/requestURL2 (注意:要配合类上定义的路径使用)
@RequestMapping("/requestURL2")
public String requestURL2(){
return "/page.jsp";
}
// target代表你能写在那些地方
// type代表类型, 能写在类上
// METHOD 方法上
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
String name() default "";
//路径
//Alias别名
@AliasFor("path")
String[] value() default {};
//路径
@AliasFor("value")
String[] path() default {};
// method, 指定请求方式(GET,POST)
RequestMethod[] method() default {};
//参数
String[] params() default {};
//请求头信息指定
String[] headers() default {};
//接收的媒体类型
String[] consumes() default {};
//响应的媒体类型
String[] produces() default {};
}
public class UserController {
@RequestMapping("/showPage")
public String showPage() {
System.out.println("user mvc controller is running ...");
return "page.jsp";
}
}
@RequestMapping("/showPage")
public String showPage() {
System.out.println("user mvc controller is running ...");
//返回值直接为webapp下的路径
return "/system/userlist.jsp";
}
@RequestMapping("/showPage")
public String showPage() {
System.out.println("user mvc controller is running ...");
//返回值直接为webapp下的路径
return "/WEB-INF/page/page.jsp";
}
@RequestMapping("/showPage2")
public String showPage2() {
System.out.println("user mvc controller is running ...");
// forward 转发
// redirect 重定向
return "redirect:/WEB-INF/page/page.jsp";
}
<context:component-scan base-package="com.itheima"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/page/"/>
<property name="suffix" value=".jsp"/>
bean>
<mvc:annotation-driven/>
<mvc:default-servlet-handler/>
@RequestMapping("/showPage3")
public String showPage3() {
System.out.println("user mvc controller is running ...");
return "page";
}
//forward:page.jsp转发访问,支持访问WEB-INF下的页面
@RequestMapping("/showPage1")
public String showPage1() {
System.out.println("user mvc controller is running ...");
return "forward:/WEB-INF/page/page.jsp";
}
//redirect:page.jsp重定向访问,不支持访问WEB-INF下的页面
@RequestMapping("/showPage2")
public String showPage2() {
System.out.println("user mvc controller is running ...");
return "redirect:/WEB-INF/page/page.jsp";
}
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/page/"/>
<property name="suffix" value=".jsp"/>
bean>
//页面简化配置格式,使用前缀+页面名称+后缀的形式进行,类似于字符串拼接
@RequestMapping("/showPage3")
public String showPage3() {
System.out.println("user mvc controller is running ...");
return "page";
}
//最简页面配置方式,使用访问路径作为页面名称,省略返回值
@RequestMapping("/showPage5")
public void showPage5() {
System.out.println("user mvc controller is running ...");
}
相当于
@RequestMapping("/showPage5")
public String showPage5() {
return "showPage5";
}
//使用原生request对象传递参数
@RequestMapping("/showPageAndData1")
public String showPageAndData1(HttpServletRequest request) {
request.setAttribute("name","itheima");
return "page";
}
/使用Model形参传递参数
@RequestMapping("/showPageAndData2")
public String showPageAndData2(Model model) {
//添加数据的方式,key对value
model.addAttribute("name","Jock");
Book book = new Book();
book.setName("SpringMVC入门案例");
book.setPrice(66.66d);
//添加数据的方式,key对value
model.addAttribute("book",book);
return "page";
}
//使用ModelAndView形参传递参数,该对象还封装了页面信息
@RequestMapping("/showPageAndData3")
public ModelAndView showPageAndData3(ModelAndView modelAndView) {
//ModelAndView mav = new ModelAndView(); 替换形参中的参数
Book book = new Book();
book.setName("SpringMVC入门案例");
book.setPrice(66.66d);
//添加数据的方式,key对value
modelAndView.addObject("book",book);
//添加数据的方式,key对value
modelAndView.addObject("name","Jockme");
//设置页面的方式,该方法最后一次执行的结果生效
modelAndView.setViewName("page");
//返回值设定成ModelAndView对象
return modelAndView;
}
@RequestMapping("/showData1")
public void showData1(HttpServletResponse response) throws IOException {
response.getWriter().print("message");
}
@RequestMapping("/showData2")
@ResponseBody
public String showData2(){
return "message";
}
//使用jackson进行json数据格式转化
@RequestMapping("/showData3")
@ResponseBody
public String showData3() throws JsonProcessingException {
Book book = new Book();
book.setName("SpringMVC入门案例");
book.setPrice(66.66d);
ObjectMapper om = new ObjectMapper();
return om.writeValueAsString(book);
}
//使用SpringMVC注解驱动,对标注@ResponseBody注解的控制器方法进行结果转换,由于返回值为引用类型,自动调用jackson提供的类型转换器进行格式转换
@RequestMapping("/showData4")
@ResponseBody
public Book showData4() {
Book book = new Book();
book.setName("SpringMVC入门案例");
book.setPrice(66.66d);
return book;
}
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-coreartifactId>
<version>2.9.0version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.9.0version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-annotationsartifactId>
<version>2.9.0version>
dependency>
<mvc:annotation-driven/>
@RequestMapping("/mapdata")
@ResponseBody
public Map<String, Object> mapdata() {
Map map = new HashMap();
map.put("name", "zhangsan");
map.put("age", 12);
return map;
}
//获取request,response,session对象的原生接口
@RequestMapping("/servletApi")
public String servletApi(HttpServletRequest request, HttpServletResponse response, HttpSession session){
System.out.println(request);
System.out.println(response);
System.out.println(session);
return "page";
}
@RequestHeader
形参注解
处理器类中的方法形参前方
作用:绑定请求头数据与对应方法形参间的关系
//获取head数据的快捷操作方式
@RequestMapping("/headApi")
public String headApi(@RequestHeader("Accept-Encoding") String headMsg){
System.out.println(headMsg);
return "page";
}
@CookieValue
形参注解
处理器类中的方法形参前方
作用:绑定请求cookie数据与对应处理方法形参间的关系
//获取cookie数据的快捷操作方式
@RequestMapping("/cookieApi")
public String cookieApi(@CookieValue("JSESSIONID") String jsessionid){
System.out.println(jsessionid);
return "page";
}
@SessionAttribute
形参注解
处理器类中的方法形参前方
作用:绑定请求Session数据与对应处理方法形参间的关系
//测试用方法,为下面的试验服务,用于在session中放入数据
@RequestMapping("/setSessionData")
public String setSessionData(HttpSession session){
session.setAttribute("name","itheima");
return "page";
}
//获取session数据的快捷操作方式
@RequestMapping("/sessionApi")
public String sessionApi(@SessionAttribute("name") String name,
@SessionAttribute("age") int age,
@SessionAttribute("gender") String gender){
System.out.println(name);
System.out.println(age);
System.out.println(gender);
return "page";
}
@SessionAttributes
形参注解
处理器类中的方法形参前方
作用:声明放入Session范围的变量名称,适用于Model类型数据传参
@Controller
//设定当前类中名称为age和gender的变量放入session范围,不常用,了解即可
@SessionAttributes(names = {"age","gender"})
public class UserController {
//配合@SessionAttributes(names = {"age","gender"})使用
//将数据放入session存储范围,通过Model对象实现数据set,通过@SessionAttributes注解实现范围设定
@RequestMapping("/setSessionData2")
public String setSessionDate2(Model model) {
model.addAttribute("age",39);
model.addAttribute("gender","男");
return "page";
}
}