SpringMVC
是Spring中负责web模块的MVC的Web应用框架。底层使用Servlet实现,主要处理客户的请求和做出响应。简化web开发。
1.1.web开发中Servlet做了那些事?
1.2.SpringMVC的组件原理
-
前端处理器
-
控制器映射器
-
控制器适配器
-
控制器/处理器
-
视图解析器
1.3.SpringMVC接口解释
-
DispatcherServlet接口
Spring提供的前端控制器,所有的请求都有经过它来统一分发。在DispatcherServlet将请求分发给Spring Controller之前,需要借助于Spring提供的HandlerMapping定位到具体的Controller。
-
HandlerMapping接口
请求到Controller映射。找到处理器的适配器
-
HandlerAdapter接口
用于调用具体的Controller,进行兼容
-
Controller接口
所有的具体的请求的处理类。处理器
-
ViewResolver接口
视图解析器 找到视图,解析数据,渲染视图
1.4.SpringMVC入门配置
-
导入jar包
aspectjweaver.jar commons-logging-1.2.jar druid-1.1.20.jar jsqlparser-2.1.jar log4j-1.2.17.jar log4j-api-2.11.2.jar log4j-core-2.11.2.jar spring-aop-4.3.25.RELEASE.jar spring-aspects-4.3.25.RELEASE.jar spring-beans-4.3.25.RELEASE.jar spring-context-4.3.25.RELEASE.jar spring-context-support-4.3.25.RELEASE.jar spring-core-4.3.25.RELEASE.jar spring-expression-4.3.25.RELEASE.jar spring-web-4.3.25.RELEASE.jar spring-webmvc-4.3.25.RELEASE.jar
-
编写处理器程序
-
实现Controller接口
package com.zw.controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; /** * @ClassName: TestController * @Description: 处理器的实现方式分为3种 : * 1. 实现 Controller接口 * 2. 实现HttpRequestHandler接口 * 3. 使用注解 * @author: KevinZeng * @date: 2020年1月4日 上午11:33:08 */ public class TestController implements Controller{ @Override public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse resp) throws Exception { ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("modelKey", "modelValue"); modelAndView.setViewName("index.jsp"); return modelAndView; } }
-
实现HttpRequestHandler接口
package com.zw.controller; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.HttpRequestHandler; /** * @ClassName: TestController * @Description: 处理器的实现方式分为3种 : * 1. 实现 Controller接口 * 2. 实现HttpRequestHandler接口 * 3. 使用注解 * @author: KevinZeng * @date: 2020年1月4日 上午11:33:08 */ public class TestController2 implements HttpRequestHandler{ @Override public void handleRequest(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("HttpRequestHandler"); req.setAttribute("modelKey", "HttpRequestHandler"); req.getRequestDispatcher("index.jsp").forward(req, resp); } }
-
使用注解
package com.zw.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; /** * @ClassName: TestController * @Description: 处理器的实现方式分为3种 : * 1. 实现 Controller接口 * 2. 实现HttpRequestHandler接口 * 3. 使用注解 * @author: KevinZeng * @date: 2020年1月4日 上午11:33:08 */ @Controller public class TestController3 { //@RequestMapping 请求映射地址 @RequestMapping("/testController3.do") public ModelAndView test() { ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("modelKey", "TestController3"); modelAndView.setViewName("index.jsp"); return modelAndView; } @RequestMapping("/testController4.do") public ModelAndView test1() { ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("modelKey", "TestController4"); modelAndView.setViewName("index.jsp"); return modelAndView; } }
-
-
编写配置文件
springmvc配置文件
<?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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!-- 配置处理器对象 --> <bean id="testController" name="/testController.do" class="com.zw.controller.TestController"></bean> <bean id="testController2" name="/testController2.do" class="com.zw.controller.TestController2"></bean> <!-- 开始相关注解配置 --> <!-- 组件扫描 --> <context:component-scan base-package="com.zw"></context:component-scan> <!-- 开启SpringMVC相关注解 --> <mvc:annotation-driven></mvc:annotation-driven> </beans>
web.xml配置文件
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>1springmvc01</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <!-- 配置springmvc的控制器 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <!-- 配置SpringMVC初始化文件 --> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> <!-- 项目启动时就初始化DispatcherServlet --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app>
1.5.SpringMVC核心配置文件
<?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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<bean name="/xml.do" class="com.zw.controller.TestController"></bean>
<!-- -->
<!-- XML映射器 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
<!-- XML的适配器 -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>
<context:component-scan base-package="com.zw"></context:component-scan>
<!-- 注解映射器 -->
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"></bean>
<!-- 注解的适配器 -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"></bean>
<context:component-scan base-package="com.zw"></context:component-scan>
<mvc:annotation-driven></mvc:annotation-driven>
</beans>
注意:
在springmvc中,一般不手动指定映射和适配器,一旦指定,其他适配器和映射器将会失效。若不指定,springmvc默认加载所有内置的支持的适配器和映射器,若要指定,建议都进行配置。
1.6.数据绑定
获取页面的数据,获取客户端的数据。
@RequestParam :
**value/name:**请求参数绑定的名称 一般可以用于别名
required : 请求参数是否必须有 默认值是 true
defaultValue : 为这个请求参数指定默认值
package com.zw.controller;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.zw.pojo.User;
/**
* @ClassName: ParamController
* @Description: TODO
* @author: KevinZeng
* @date: 2020年1月4日 下午3:08:17
*/
@Controller
@RequestMapping("/param")
public class ParamController {
/**
* @Title: getParam1
* @author: KevinZeng
* @date: 2020年1月4日 下午3:13:55
* @Description: 使用简单数据类型接收参数
* @param userName
* @param sex
* @param like
* @param city
* @param age
* @return: void
*/
@RequestMapping("/m1.do")
public void getParam1(String userName,String sex,String[] like,String city,Integer age) {
System.out.println("userName:"+userName);
System.out.println("sex:"+sex);
System.out.println("like:"+Arrays.toString(like));
System.out.println("city:"+city);
System.out.println("age:"+age);
}
@RequestMapping("/m2.do")
//@RequestParam()
public void getParam2(@RequestParam(value = "userName1",required = false,defaultValue = "韩梅梅")String userName,String sex,@RequestParam("like")List<String> like,String city,Integer age) {
System.out.println("userName:"+userName);
System.out.println("sex:"+sex);
System.out.println("like:"+like);
System.out.println("city:"+city);
System.out.println("age:"+age);
}
//使用map接收请求参数
@RequestMapping("/m3.do")
public void getParam3(@RequestParam Map<String,Object> param) {
System.out.println(param);
}
//使用简单java对象接收请求参数
@RequestMapping("/m4.do")
public void getParam4(User user) {
System.out.println(user);
}
}
jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 普通文本数据 -->
<form action="param/m4.do" method="post">
<p>
用户名:
<input type="text" name="userName" />
</p>
<p>
年龄:
<input type="text" name="age" />
</p>
<p>
性别:
<input type="radio" name="sex" value="男" />男
<input type="radio" name="sex" value="女" />女
</p>
<p>
爱好:
<input type="checkbox" name="like" value="篮球" />篮球
<input type="checkbox" name="like" value="足球" />足球
</p>
<p>
城市:
<select name="city">
<option value="wh" >武汉</option>
<option value="sh" >上海</option>
</select>
</p>
<input type="submit" value="提交" />
</form>
</body>
</html>
配置文件
<?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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启组件扫描 -->
<context:component-scan base-package="com.zw"></context:component-scan>
<!-- 开启mvc相关注解 -->
<mvc:annotation-driven></mvc:annotation-driven>
</beans>
注意点:
在SpringMVC中,可以自动注入:
HttpServletRequest
HttpServletResponse
HttpSession
Model
1.7.使用工具类获取WEB对象
package com.zw.util;
/**
* @ClassName: WebUtil
* @Description: 直接使用方法获取系统对象
* @author: KevinZeng
* @date: 2020年1月4日 下午4:46:23
*/
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
public class WebUtil {
/**
* @Title: getRequest
* @author: KevinZeng
* @date: 2020年1月4日 下午4:49:33
* @Description: 通过方法获取request 对象
* @return
* @return: HttpServletRequest
*/
public static HttpServletRequest getRequest() {
ServletRequestAttributes currentRequestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
return currentRequestAttributes.getRequest();
}
/**
* @Title: getSession
* @author: KevinZeng
* @date: 2020年1月4日 下午4:51:03
* @Description: 通过方法获取Session
* @return
* @return: HttpSession
*/
public static HttpSession getSession() {
return getRequest().getSession();
}
/**
* @Title: getServletContext
* @author: KevinZeng
* @date: 2020年1月4日 下午4:51:59
* @Description: 获取ServletContext
* @return
* @return: ServletContext
*/
public static ServletContext getServletContext() {
//当项目启动时 ServletContext 就会被初始化
//HttpServletRequest 每次请求时创建
//HttpServletRequest request = getRequest();
return ContextLoader.getCurrentWebApplicationContext().getServletContext();
}
/**
* @Title: getCurrentCode
* @author: KevinZeng
* @date: 2020年1月4日 下午4:56:35
* @Description: 获取当前验证码
* @return
* @return: String
*/
public static String getCurrentCode() {
return getSession().getAttribute("code").toString();
}
/**
* @Title: getCurrentUser
* @author: KevinZeng
* @date: 2020年1月4日 下午4:57:47
* @Description: 获取当前用户
* @return
* @return: Object
*/
public static Object getCurrentUser() {
return getSession().getAttribute("user");
}
}
1.8.配置编码过滤器
<!-- 配置spring内置的编码过滤器 -->
<filter>
<filter-name>charset</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>charset</filter-name>
<servlet-name>springmvc</servlet-name>
</filter-mapping>
1.9.springmvc的跳转问题
package com.zw.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
/**
* @ClassName: ParamController
* @Description: TODO
* @author: KevinZeng
* @date: 2020年1月4日 下午3:08:17
*/
@Controller
public class TestController {
/**
* 使用ModelAndview
*/
@RequestMapping("mv.do")
public ModelAndView test1() {
ModelAndView mv = new ModelAndView();
mv.setViewName("index.jsp");//此时页面跳转了 但是url地址没有发生变化 内部转发
return mv;
}
@RequestMapping("mv2.do")
public ModelAndView test11() {
ModelAndView mv = new ModelAndView();
mv.setViewName("redirect:index.jsp");//此时页面跳转了 但是url地址没有发生变化 内部转发
return mv;
}
@RequestMapping("str.do")
public String test2() {
//此时页面也跳转了 但是url地址没有发生改变 内部转发
return "index.jsp";
}
@RequestMapping("str2.do")
public String test21() {
//此时页面也跳转了 但是url地址没有发生改变 内部转发
return "redirect:index.jsp";
}
@RequestMapping("web.do")
public void test3(HttpServletRequest req,HttpServletResponse response) {
try {
//使用web对象 内部转发进行跳转
req.getRequestDispatcher("index.jsp").forward(req, response);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@RequestMapping("web2.do")
public void test4(HttpServletRequest req,HttpServletResponse response) {
try {
//使用web对象 重定向进行跳转
response.sendRedirect("index.jsp");
} catch (Exception e) {
e.printStackTrace();
}
}
}
注意:
- 在springmvc中,跳转默认使用内部转发。如果想使用重定向,需要使用:redirect:地址
- 在springmvc中,跳转时,/ 表示根目录,这种是绝对路径,推荐使用这种方式。
1.10.参数传递
在springmvc中,推荐使用参数传递方式是Model,也可以使用request对象进行参数传递,但是model的优先级更高,当出现参数重叠时,model中数据,会默认覆盖request中的数据。
1.11.视图解析器配置问题
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 配置视图的前缀 -->
<property name="prefix" value="/WEB-INF/jsp/"></property>
<!-- 配置视图的后缀 -->
<!-- <property name="suffix" value=".jsp"></property> -->
</bean>
注意:
配置的视图解析器,前缀和后缀,对重定向的跳转是不生效。