前端请求------>Controller(servlet)------->Service--------------->DAO------>访问数据库
M: Model(service/DAO/pojo)
V: View
C: Controller
而: Servlet/SpringMVC 是控制器的解决方法
Spring是service层解决方法,能够整合第三方框架,为业务逻辑层提供事务
JDBC/dbutils/JdbcTempalate提供访问数据库的方案
那么也就是说SpringMVC实际上就是替代原来的Servlet
问题:现在我们有了Servlet 那么为什么我们还要使用SpringMVC呢?
原因:原来我们的Servlet在使用的时候 还是比较复杂
请求参数的时候 需要自己去getParameter ,参数不能自动封装
Servlet:没有处理编码问题
原来在使用Servlet的时候 每一个请求都需要写Servlet ---- 需要写很多的Servlet----冗余
原来在做文件下载的时候 ------ 也比较复杂
原来在使用Servlet返回JSON格式的时候 ------ 需要自己去转换成JSON的字符串
原来在接受JSON数据额时候是没有办法直接封装成Java对象
SpringMVC简单的是就是对Servlet的一个封装
SpringMVC实际上就是一个控制器的解决方案而已
简单的说就是对Servlet的封装
就是简化了原来Servlet的功能
他里面要干的事情就跟原来一样
1:接受前端数据
2:将前端数据封装成对象
3:调用业务逻辑
4:返回数据进行封装(放到域对象)
5:进行页面的跳转
SpringMVC和Spring到底是一个什么关系?SpringMVC只是Spring中的Web MVC模块而已
并不是什么框架
他里面要做的事情就跟原来一样
1:接受前端数据
2:将前端数据封装成对象
3:调用业务逻辑
4:返回数据进行封装(放到域对象)
5:进行页面的跳转
6:文件的下载和上传 数据的自动封装 返回JSON格式的自动封装 等等…
此处引用狂神说博客
图为SpringMVC的一个较完整的流程图,实线表示SpringMVC框架提供的技术,不需要开发者实现,虚线表示需要开发者实现。
简要分析执行流程
DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求。
我们假设请求的url为 : http://localhost:8080/SpringMVC/hello
如上url拆分成三部分:
http://localhost:8080服务器域名
SpringMVC部署在服务器上的web站点
hello表示控制器
通过分析,如上url表示为:请求位于服务器localhost:8080上的SpringMVC站点的hello控制器。
HandlerMapping为处理器映射。DispatcherServlet调用HandlerMapping,HandlerMapping根据请求url查找Handler。
HandlerExecution表示具体的Handler,其主要作用是根据url查找控制器,如上url被查找控制器为:hello。
HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等。
HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler。
Handler让具体的Controller执行。
Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView。
HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet。
DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名。
视图解析器将解析的逻辑视图名传给DispatcherServlet。
DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图。
最终视图呈现给用户。
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>3.1.0version>
<scope>providedscope>
dependency>
<dependency>
<groupId>javax.servlet.jsp.jstlgroupId>
<artifactId>javax.servlet.jsp.jstl-apiartifactId>
<version>1.2.1version>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>jsp-apiartifactId>
<version>2.0version>
<scope>providedscope>
dependency>
<dependency>
<groupId>org.apache.taglibsgroupId>
<artifactId>taglibs-standard-implartifactId>
<version>1.2.5version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.11version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
<version>5.2.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.2.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webartifactId>
<version>5.2.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.2.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-aopartifactId>
<version>5.2.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-txartifactId>
<version>5.2.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.10version>
dependency>
<dependency>
<groupId>cglibgroupId>
<artifactId>cglibartifactId>
<version>3.2.4version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.10version>
dependency>
<dependency>
<groupId>org.aspectjgroupId>
<artifactId>aspectjweaverartifactId>
<version>1.9.4version>
dependency>
<servlet>
<servlet-name>dispatcherServletservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>dispatcherServletservlet-name>
<url-pattern>*.actionurl-pattern>
servlet-mapping>
注意配置文件名字:核心Servlet在web.xml中名字-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"
xmlns:task="http://www.springframework.org/schema/task"
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
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.1.xsd"
>
<bean id="/user.action" class="com.szq.helloworld.UserController">bean>
beans>
public class UserController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView modelAndView=new ModelAndView();
//设置跳转的页面
modelAndView.setViewName("/hello.jsp");
//设置数据(键值对)
modelAndView.addObject("username","小小");
return modelAndView;
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
Title
前端获取到的数据:${username}
上面这种写法存在的有问题:
每一个Controller 才对应一个路径 也就是说 一个Contoller只是处理了一个请求、并没有处理多个请求 相当于将原来的Servlet 直接的给复制了一遍没有 通用性
与5.1相同,此处就不再重复
与5.2相同,此处就不再重复
<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"
xmlns:task="http://www.springframework.org/schema/task"
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
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.1.xsd"
>
<bean id="/user.action" class="com.szq.helloworld.UserController">bean>
beans>
<mvc:annotation-driven>mvc:annotation-driven>
beans>
@Controller //表示的是当前这个类是一个控制器
@RequestMapping("/say") //当前这个控制器 映射的大的路径(可以不写)
public class UserController {
@RequestMapping(value = "/hello") //当前的方法映射的路径(小的路径)
public String sayHello(){
System.out.println("hello world...");
//表示返回的页面
return "/hello.jsp";
}
}
如果使用注解方式,需要告诉它 配置文件在哪里
<servlet>
<servlet-name>dispatcherServletservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:dispatcherServlet-servlet.xmlparam-value>
init-param>
servlet>
@RequestMapping(value = "xx1")
public String aa1(HttpServletRequest request){
System.out.println("hello...");
request.setAttribute("title","哈哈哈哈哈");
return "/hello.jsp";
}
@RequestMapping(value = "aa1")
public ModelAndView aa1(ModelAndView modelAndView){
System.out.println("hello...");
modelAndView.setViewName("/hello.jsp");
modelAndView.addObject("title","第二种返回数据的方式");
return modelAndView;
}
@RequestMapping(value = "aa3")
public String aa1(Model model){
System.out.println("hello world...");
model.addAttribute("title2","你懂的...");
return "/hello.jsp";
}
@RequestMapping(value = "aa1")
public String aa(HttpServletRequest request){
request.setAttribute("username","用户1");
return "/aa2.action";
}
@RequestMapping(value = "aa2")
public ModelAndView aa(ModelAndView modelAndView){
modelAndView.setViewName("/hello.jsp");
modelAndView.addObject("username1","用户2");
return modelAndView;
}
@RequestMapping(value = "aa3")
public String aa(Model model){
model.addAttribute("username2","西瓜五元一斤");
return "aa1.action";
}
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
Title
前端获取到的数据
第一种方法:${username}
第er种方法:${username1}
第san种方法:${username2}
前端页面能获取到相应字段的数据,因为前后都是一个请求,是请求转发
如果使用重定向会出现使用重定向的那一个会取不到数据
@RequestMapping(value = "aa1")
public String aa(HttpServletRequest request){
request.setAttribute("username","用户1");
return "/aa2.action";
}
@RequestMapping(value = "aa2")
public ModelAndView aa(ModelAndView modelAndView){
modelAndView.setViewName("/hello.jsp");
modelAndView.addObject("username1","用户2");
return modelAndView;
}
@RequestMapping(value = "aa3")
public String aa(Model model){
model.addAttribute("username2","西瓜五元");
return "redirect:http://localhost:8080/aa1.action";//这里重定向(前后不是同一个请求)http://localhost:8080/
}
username2在前端会获取不到数据
/**
* 测试传递简单参数
* @param deptName
* @param deptDes
* @return
*/
@RequestMapping("parameter1")
public String parameter1(String deptName,String deptDes){
System.out.println("传递过来的数据是:"+deptName+"------"+deptDes);
return "/hello.jsp";
}
/**
* 接受数据的第二种方式直接封装成对象
* 结论:只要前端传递过来的键值对的名称 和 后台对象中 属性的名称保持一致就可以了
* @param dept
* @return
*/
@RequestMapping("parameter2")
public String parameter2(Dept dept){
System.out.println("传递过来的数据是:"+dept);
return "/hello.jsp";
}
两个实体属性字段一致,在前端如何传数据给后端,后端如何接收?
实体代码:例如(User/Admin实体类)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String username;
private String password;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Admin {
private int id;
private String username;
private String password;
}
此时我们需要再定义一个类,如下,使用这个类来接收数据
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserAndAdmin {
private Admin admin;
private User user;
}
<%--用户的实体--%>
用户数据
管理员数据
/**
* 传递参数的第四种方法
* @return
*/
@RequestMapping("parameter4")
public String parameter3(UserAndAdmin userandAdmin){
System.out.println("传递过来的用户数据是:"+userandAdmin.getUser());
System.out.println("传递过来的管理员数据是:"+userandAdmin.getAdmin());
return "/hello.jsp";
}
实体类:
/**
* 用户实体类
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String username;
private String password;
private int [] habbits;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ListObject {
private List<User> users;
}
/**
* 传递参数的第四种方法
* @return
*/
@RequestMapping("parameter5")
public String parameter5(ListObject userList){
System.out.println(userList);
return "/hello.jsp";
}
/**
* 传递参数的第四种方法
* @return
*/
@RequestMapping("parameter5")
public String parameter5(int[] habbits){
System.out.println(habbits);
return "/hello.jsp";
}
ut type=“submit” value=“提交”>
```@Data
@AllArgsConstructor
@NoArgsConstructor
public class ListObject {
private List<User> users;
}
/**
* 传递参数的第四种方法
* @return
*/
@RequestMapping("parameter5")
public String parameter5(ListObject userList){
System.out.println(userList);
return "/hello.jsp";
}
/**
* 传递参数的第四种方法
* @return
*/
@RequestMapping("parameter5")
public String parameter5(int[] habbits){
System.out.println(habbits);
return "/hello.jsp";
}