SpringMVC - web(Servlet)
- 和用户交互的组件(获取用户传递参数, 想用数据给用户)
- jsp --> Servlet --> Jsp
- 目标
- hello world
- 怎么获取参数
- 如何响应结果
- 跳转页面
- 响应数据
- MVC
- Model 数据
- View 视图
SpringMVC会不会使用spring的功能?
- 使用
如果使用了那么容器什么时候创建(配置文件什么时候被加载)?
- web.xml中的DispatcherServlet中加载的
SpringMVC hello world
-
前置步骤
-
工程类型(webapp)
-
导包
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <!-- servlet3.1规范的坐标 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <!--jsp坐标--> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.1</version> <scope>provided</scope> </dependency> <!--spring的坐标--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.9.RELEASE</version> </dependency> <!--spring web的坐标--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.1.9.RELEASE</version> </dependency> <!--springmvc的坐标--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.1.9.RELEASE</version> </dependency> </dependencies> <!--构建--> <build> <!--设置插件--> <plugins> <!--具体的插件配置--> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.1</version> <configuration> <port>80</port> <path>/</path> <!--<uriEncoding>UTF-8</uriEncoding>--> </configuration> </plugin> </plugins> </build>
-
-
中央控制器的配置
<servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--加载配置文件--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:abc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
-
如何创建spring容器
<?xml version="1.0" encoding="UTF-8"?> <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"/> </beans>
-
编写Controller(servlet)
@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"; } }
springMVC启动流程
- tomcat启动加载web.xml ( tomcat启动加载那个配置类)
- 保证dispactherServlet能够正常加载配置文件(在配置类中加载需要的servlet以及准备工作(容器创建))
- spring配置文件必须扫描对应的Controller(404)
mybatis - dao
Spring - 三层bean统一管理
- Ioc
- 作用:容器
- 注解
- xml
- di
- AOP
- 作用:方法增强
- 通知Advice
- 切入点Pointcut
- 切面Aspect
- 事务
- API
- AOP
- 声明式
- 注解
- 作用:方法增强
静态资源放行
<mvc:default-servlet-handler/>
中乱码问题
-
web.xml中配置过滤器
<filter> <filter-name>characterEncodingFilter</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>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
-
tomcat插件uri编码配置
<!--构建--> <build> <!--设置插件--> <plugins> <!--具体的插件配置--> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.1</version> <configuration> <port>80</port> <path>/</path> <uriEncoding>UTF-8</uriEncoding> </configuration> </plugin> </plugins> </build>
纯注解
** tomcat启动的时候回去加载ServletContainerInitializer的实现类,但是具体的实现类需要在META-INF这下面配置一个配置文件**
- 文件名: javax.servlet.ServletContainerInitializer
- 内容: 你的实现类权限定类名
- DispatherServlet
- Spring的IOC
模拟SpringBoot内嵌tomcat
流程
- tomcat启动
- 加载web.xml, or 加载ServletContainerInitializer的实现类
- 后续准备工作(容器初始化, 包扫描, 过滤器)
参数获取
-
基本数据类型(String, int)
- 直接在对应的方法上写出参数即可
- 如果名字需要修改@RequestParam(“name”)
-
404问题:
-
路径写错了
-
你根本没有Controller注解
-
你根本没扫描包( spring-mvc.xml)
-
根本没有加载配置文件(web.xml)
-
资源目录写错(resources)
-
配置静态资源后
<mvc:annotation-driven/> <mvc:default-servlet-handler/>
-
-
400原因
- 你请求的参数有问题
参数获取POJO(前端那些参数时,对象当做js对象使用)
-
普通属性如何注入
-
引用属性如何注入
-
集合属性注入
-
map属性注入
-
请求路径
http://localhost/requestParam3?name=Jock&age=39
- 代码
//http://localhost/requestParam3?name=Jock&age=39
@RequestMapping("/requestParam3")
public String requestParam3(User user){
System.out.println(user);
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"> <!--覆盖格式化转换器定义规则,该规则是一个set集合,对格式化转换器来说是追加和替换的思想,而不是覆盖整体格式化转换器--> <property name="formatters"> <set> <!--具体的日期格式化转换器--> <bean class="org.springframework.format.datetime.DateFormatter"> <!--具体的规则,不具有通用性,仅适用于当前的日期格式化转换器--> <property name="pattern" value="yyyy-MM-dd"/> </bean> </set> </property> </bean>
-
注解形式
@RequestMapping("/requestParam11") public String requestParam11(@DateTimeFormat(pattern = "yyyy-MM-dd") Date date){ System.out.println(date); return "page.jsp"; }
自定义类型转换器
-
实现一个接口Converter<参数, 需要得到的类型>
-
实现convert方法
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; } }
-
配置将转换器添加到spring对应的组件
<mvc:annotation-driven conversion-service="conversionService"/> <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <!--覆盖类型转换器定义规则,该规则是一个set集合,对类型转换器来说是追加和替换的思想,而不是覆盖整体格式化转换器--> <property name="converters"> <set> <!--添加自定义的类型转换器,会根据定义的格式覆盖系统中默认的格式--> <!--当前案例中是将String转换成Date的类型转换器进行了自定义,所以添加后,系统中原始自带的String——>Date的类型转换器失效--> <bean class="com.itheima.converter.MyDateConverter"/> </set> </property> </bean>
@RequestMapping
// 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 {};
}
响应- 页面跳转
- 重定向
- 相当于页面重新刷新, 不能够拿到后端给的request,response
- 转发
- 携带有request,response,在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> <!--开启springmvc注解驱动,对@ResponseBody的注解进行格式增强,追加其类型转换的功能,具体实现由MappingJackson2HttpMessageConverter进行--> <mvc:annotation-driven/> <mvc:default-servlet-handler/>
-
在返回值中直接写上/WEB-INF/page/的静态页面名称即可
@RequestMapping("/showPage3")
public String showPage3() {
System.out.println("user mvc controller is running ...");
return "page";
}
携带数据 - jsp中使用
-
直接利用request对象存储数据
@RequestMapping("/showPageAndData1") public String showPageAndData1(HttpServletRequest request) { request.setAttribute("name","itheima"); return "page"; }
-
使用model对象存储数据,实际上依然存储在request中
@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
- view视图(jsp,html)
- model数据
//使用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; }
响应JSON数据
1. 导包
<!--json相关坐标3个-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>
2. spring-mvc配置文件添加注解支持
<mvc:annotation-driven/>
3.使用
- 注解: @ResponBody,添加到控制器中的方法上即可
@RequestMapping("/mapdata")
@ResponseBody
public Map<String, Object> mapdata() {
Map map = new HashMap();
map.put("name", "zhangsan");
map.put("age", 12);
return map;
}
Servlet原生API获取
- request、response、session
@RequestMapping("/showData4")
@ResponseBody
public Book showData4(HttpServletRequest request, HttpServletResponse response) {
return book;
}
- cookie, header
//@CookieValue
//@RequestHeader
//@SessionAttribute
重点
- hello world
- 执行流程(无配置实现)
- 获取参数
- 响应数据
- 存储到request
- 响应json