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能干什么?

  1. 请求参数的自动封装
  2. 编码问题的处理
  3. 请求的JSON格式自动转换成JAVA对象 返回的JAVA对象自动转换成JSON格式
  4. 页面跳转的封装
  5. 表单文件防止重复提交的问题
  6. 上传下载的简化
  7. 日期格式的自动转换
  8. 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:注意

  1. 配置文件的名字是不能乱写的,web.xml中配置的servlet的名字-servlet.xml配置的
  2. SpringMVC实际上只是Spring的一个模块 所以配置文件的约束是一样的
  3. 编写实现于Controll接口的这个重写的方法 里面的ModelAndView返回的是视图和数据的集合(这里的数据默认是放到了request域对象里面的)
  4. 在SpringMVC的配置文件中 name表示的是映射的路径、映射路径前面必须加上/
  5. 在编写配置文件的路径映射的时候 不能写 /.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的运行的逻辑是什么?

  1. 请求会被转发到映射器上面去 映射器的请求会将请求分离
  2. 映射器将分离出来的数据转发到适配器(适配器就专门来找 是实现了接口的控制器 还是继承于类的控制器 还是既没有实现接口 也没有继承类的这个控制器)
  3. 控制器拿到请求处理请求 返回数据和 返回视图 到 视图解析器
  4. 视图解析器拿到最终要跳转的页面 进行转发 转到 显示页面

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中需要接受并且两个对象的属性是一样的时候的区分

  1. 编写封装类
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 + "]";
}

}
  1. 编写接受的controll
@RequestMapping("parame4")
public String param4(UserAndAdmin userAndAdmin){
System.out.println(userAndAdmin.getUser());
System.out.println(userAndAdmin.getAdmin());
return "/index.jsp";
}
  1. 编写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