1、传统SSH框架的模式
SSH框架代表含义
简称 | 含义 |
---|---|
S | SpringMVC/Struts |
S | Spring |
H | Hibernate |
第一个S:表示的是控制器的解决方案,SpringMVC 是控制器的解决方案(相当于替代了原来的Servlet)
第二个S:Spring(整合第三方框架、为Service层提供事务)
第三个H:这个是DAO的解决方案
2、有了Servlet为什么还要学习SpringMVC
因为Servlet是最原生的实现、很多的实现 都比较繁琐:请求参数的自动封装、编码问题解决、文件的上传和下载问题、要实现防止重复提交的问题、在每一次编写请求的时候都需要带上方法名判断就变得复杂了、每一次跳转我们都需要自己去写代码、这就让这个Servlet的使用代码量就变得繁琐了。
SpringMVC产生以后, 也就是说我们的SpringMVC只需要写很少的代码就能够完成上述的功能了
3、SpringMVC到底是什么?
SpringMVC实际上你可以认为就是一个Servlet的封装、只不过这个封装能够更好的解决Servlet中的所有问题
4、SpringMVC能干什么?
-
请求参数的自动封装
-
编码问题的处理
-
请求的JSON格式自动转换成JAVA对象 返回的JAVA对象自动转换成JSON格式
-
页面跳转的封装
-
表单文件防止重复提交的问题
-
上传下载的简化
-
日期格式的自动转换
-
SpringMVC的第一个HelloWorld程序
5、SpringMVC的第一个HelloWorld程序
5.1:导包
Core 、aop、web、webmvc
5.2:编写web.xml的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>Demo_SpringMVC_01</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>
<servlet-name>DispatcherServlet1</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet1</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>
复制代码
5.3:在WEB-INF目录下创建一个名字和上面申明servlet名字-servlet.xml的配置文件(DispatcherServlet1-servlet.xml)
<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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd" default-autowire="byName">
<bean name="/hello.action" class="com.qy.helloworld.HelloWorldControll"></bean>
</beans>
复制代码
5.4:编写一个HelloControll类实现于Controller接口
public class HelloWorldControll implements Controller{
@Override
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {
System.out.println("我是Controll我执行了....");
ModelAndView modelAndView=new ModelAndView();
//设置跳转的页面
modelAndView.setViewName("/yuyu.jsp");
return modelAndView;
}
}
复制代码
5.5:测试
5.6:注意
-
配置文件的名字是不能乱写的,web.xml中配置的servlet的名字-servlet.xml配置的
-
SpringMVC实际上只是Spring的一个模块 所以配置文件的约束是一样的
-
编写实现于Controll接口的这个重写的方法 里面的ModelAndView返回的是视图和数据的集合(这里的数据默认是放到了request域对象里面的)
-
在SpringMVC的配置文件中 name表示的是映射的路径、映射路径前面必须加上/
-
在编写配置文件的路径映射的时候 不能写 /.action(没有这种写法),/ *.action /anana/anan
6、SpringMVC中配置文件路径的问题
6.1:在src目录下创建一个自定义的文件夹config
6.2: 在里面编写spring-mvc.xml配置文件
<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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd" default-autowire="byName">
<bean name="/hello.action" class="com.qy.helloworld.HelloWorldControll"></bean>
</beans>
复制代码
6.3:在web.xml中增加这个映射路径
<servlet>
<servlet-name>DispatcherServlet1</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--指定文件的加载路径
param-name:这个名字是不能乱写的 contextConfigLocation
-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:config/spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet1</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
复制代码
7、SpringMVC的运行的逻辑是什么?
-
请求会被转发到映射器上面去 映射器的请求会将请求分离
-
映射器将分离出来的数据转发到适配器(适配器就专门来找 是实现了接口的控制器 还是继承于类的控制器 还是既没有实现接口 也没有继承类的这个控制器)
-
控制器拿到请求处理请求 返回数据和 返回视图 到 视图解析器
-
视图解析器拿到最终要跳转的页面 进行转发 转到 显示页面
8、注解的模式怎么实现SpringMVC(常用)
8.1:配置包的扫描(包的扫描:spring-mvc.xml)
<!--配置一个扫描器-->
<context:component-scan base-package="com.qy.anotation"></context:component-scan>
<!--添加一个mvc的注解驱动-->
<mvc:annotation-driven></mvc:annotation-driven>
复制代码
8.2:使用常用的注解来完成操作
-
@Controll:表示当前的这个类是一个控制器
-
@RequestMapping:表示的是请求路径的映射
- 用在类的上面表示的是全局的地址 所有的访问都必须带上这个地址
- 用在方法上表示的是最后的映射路径
-
@GetMapping:这个表示的是当前的请求的方法必须是GET请求
-
@PostMapping:当前的请求必须是POST请求
-
@PutMapping("/login") //这个表示的是put方法的时候 会调用到这里来
-
@DeleteMapping("/login") //这个表示的是请求的方法必须是delete的时候才会被执行
8.3:限定方法的访问
/**
* 登陆的方法
* @Title: login
* @Description: TODO
* @param: @return
* @return: String
* @throws
*/
@RequestMapping(value="login",method=RequestMethod.GET)
public String login(){
System.out.println("这里是登陆的方法");
return "/yuyu/yuyu1.jsp";
}
/**
* 限定当前的方法只能post请求访问
* @Title: register
* @Description: TODO
* @param: @return
* @return: String
* @throws
*/
@RequestMapping(value="register",method=RequestMethod.POST)
public String register(){
System.out.println("这里是注册的方法");
return "/index.jsp";
}
复制代码
9、返回页面的问题
/**
* 返回页面的第一种方式 :直接返回一个页面
* @Title: insert
* @Description: TODO
* @param: @return
* @return: String
* @throws
*/
@RequestMapping("insert")
public String insert(){
System.out.println("我是部门的插入我执行了....");
return "/index.jsp";
}
/**
* 借助于ModelAndView来返回页面
* @Title: insert
* @Description: TODO
* @param: @return
* @return: String
* @throws
*/
@RequestMapping("insert1")
public ModelAndView insert1(){
ModelAndView modelAndView=new ModelAndView();
modelAndView.setViewName("/index.jsp");
System.out.println("我是部门的插入我执行了....");
return modelAndView;
}
/**
* 返回页面的第三种方式直接给个requset
* @Title: insert2
* @Description: TODO
* @param: @param request
* @param: @param response
* @param: @throws ServletException
* @param: @throws IOException
* @return: void
* @throws
*/
@RequestMapping("insert2")
public void insert2(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{
System.out.println("我是部门的插入我执行了....");
request.getRequestDispatcher("/index.jsp").forward(request, response);
}
/**
* 重定向进行页面的跳转
* @Title: insert3
* @Description: TODO
* @param: @return
* @param: @throws ServletException
* @param: @throws IOException
* @return: String
* @throws
*/
@RequestMapping("insert3")
public String insert3() throws ServletException, IOException{
System.out.println("我是部门的插入我执行了....");
return "redirect:/index.jsp";
}
/**
* 通知消息转换器可以配置这个前缀和后缀
* @Title: insert3
* @Description: TODO
* @param: @return
* @param: @throws ServletException
* @param: @throws IOException
* @return: String
* @throws
*/
@RequestMapping("/insert4.action")
public String insert4() throws ServletException, IOException{
System.out.println("我是部门的插入我执行了....");
return "index";
}
复制代码
10、将数据放到request域对象的方法
/**
* 第一种将数据放到域对象的方法
* @Title: data
* @Description: TODO
* @param: @return
* @return: String
* @throws
*/
@RequestMapping("data")
public String data(Model model){
model.addAttribute("userName","小羽1");
System.out.println("我是部门的插入我执行了....");
return "/index.jsp";
}
/**
* 借助于ModelAndView来返回页面
* @Title: data
* @Description: TODO
* @param: @return
* @return: String
* @throws
*/
@RequestMapping("data1")
public String data1(HttpServletRequest request){
request.setAttribute("userName","小羽2");
return "/index.jsp";
}
/**
* 返回页面的第三种方式直接给个requset
* @Title: data2
* @Description: TODO
* @param: @param request
* @param: @param response
* @param: @throws ServletException
* @param: @throws IOException
* @return: void
* @throws
*/
@RequestMapping("data2")
public ModelAndView data2() throws ServletException, IOException{
ModelAndView modelAndView=new ModelAndView();
modelAndView.setViewName("/index.jsp");
modelAndView.addObject("userName","小羽3");
return modelAndView;
}
复制代码
11、SpringMVC中参数的接受问题?
11.1:接受普通参数和数组参数
/**
* 第一种接受数据的方法
* @Title: param1
* @Description: TODO
* @param: @param userName
* @param: @param password
* @param: @return
* @return: String
* @throws
*/
@RequestMapping("parame1")
public String param1(String userName,String password){
System.out.println("接受到的数据是:"+userName+"----"+password);
return "/index.jsp";
}
/**
* 接受数组类型的数据
* @Title: param1
* @Description: TODO
* @param: @param userName
* @param: @param password
* @param: @param habbit
* @param: @return
* @return: String
* @throws
*/
@RequestMapping("parame2")
public String param2(String userName,String password,int[] habbit){
System.out.println("接受到的数据是:"+userName+"----"+password);
System.out.println(Arrays.toString(habbit));
return "/index.jsp";
}
/**
* 请求的参数自动封装(对象的属性必须和表单提交的name是一一对应的)
* @Title: param3
* @Description: TODO
* @param: @param user
* @param: @return
* @return: String
* @throws
*/
@RequestMapping("parame3")
public String param3(User user){
System.out.println(user);
return "/index.jsp";
}
复制代码
11.2:接受集合类型的参数
11.2.1:编写封装类
public class ManyUser {
private List<User> users=new ArrayList<User>();
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
@Override
public String toString() {
return "ManyUser [users=" + users + "]";
}
}
复制代码
11.2.2:参数的接受
@RequestMapping("parame5")
public String param5(ManyUser manyUser){
System.out.println(manyUser.getUsers());
return "/index.jsp";
}
复制代码
11.2.3:编写jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'param.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
普通用户:
<br>
<form action="${pageContext.request.contextPath}/parame5.action"
method="post">
用户名:<input type="text" name="users[0].userName"><br> 密码:<input
type="password" name="users[0].password"><br> 你的爱好: 美女<input
type="checkbox" name="users[0].habbit" value="1"> 帅哥<input
type="checkbox" name="users[0].habbit" value="2"> 其他<input
type="checkbox" name="users[0].habbit" value="3">
<hr>
用户名:<input type="text" name="users[1].userName"><br> 密码:<input
type="password" name="users[1].password"><br> 你的爱好: 美女<input
type="checkbox" name="users[1].habbit" value="1"> 帅哥<input
type="checkbox" name="users[1].habbit" value="2"> 其他<input
type="checkbox" name="users[1].habbit" value="3">
<hr>
用户名:<input type="text" name="users[2].userName"><br> 密码:<input
type="password" name="users[2].password"><br> 你的爱好: 美女<input
type="checkbox" name="users[2].habbit" value="1"> 帅哥<input
type="checkbox" name="users[2].habbit" value="2"> 其他<input
type="checkbox" name="users[2].habbit" value="3">
<hr>
<input type="submit" value="提交">
</form>
</body>
</html>
复制代码
11.3:当两个对象在同一个Controll中需要接受并且两个对象的属性是一样的时候的区分
- 编写封装类
public class UserAndAdmin {
private User user;
private Admin admin;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Admin getAdmin() {
return admin;
}
public void setAdmin(Admin admin) {
this.admin = admin;
}
@Override
public String toString() {
return "UserAndAdmin [user=" + user + ", admin=" + admin + "]";
}
}
复制代码
- 编写接受的controll
@RequestMapping("parame4")
public String param4(UserAndAdmin userAndAdmin){
System.out.println(userAndAdmin.getUser());
System.out.println(userAndAdmin.getAdmin());
return "/index.jsp";
}
复制代码
- 编写jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'param.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
普通用户:
<br>
<form action="${pageContext.request.contextPath}/parame4.action"
method="post">
用户名:<input type="text" name="user.userName"><br> 密码:<input
type="password" name="user.password"><br> 你的爱好: 美女<input
type="checkbox" name="user.habbit" value="1"> 帅哥<input
type="checkbox" name="user.habbit" value="2"> 其他<input
type="checkbox" name="user.habbit" value="3"> <input type="submit"
value="提交">
</form>
<hr>
管理员:
<br>
<form action="${pageContext.request.contextPath}/parame4.action"
method="post">
用户名:<input type="text" name="admin.userName"><br> 密码:<input
type="password" name="admin.password"><br> 你的爱好: 美女<input
type="checkbox" name="admin.habbit" value="1"> 帅哥<input
type="checkbox" name="admin.habbit" value="2"> 其他<input
type="checkbox" name="admin.habbit" value="3"> <input type="submit"
value="提交">
</form>
</body>
</html>
复制代码
12、字符编码过滤器的使用(只是处理了POST请求)
<!--只是处理了POST没有处理GET Spring 官方建议提交数据 都使用POST-->
<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>
复制代码
13、关于后缀名写法的一个说法
-
SpringMVC的默认的访问后缀就是.action
-
Struts1.x的时代 默认的访问后缀是.do
-
Struts2.x+的时代也变成了.action