SpringMVC的使用

SpringMVC的使用

1、之前开发使用的三层架构

前端请求------>Controller(servlet)------->Service--------------->DAO------>访问数据库

M: Model(service/DAO/pojo)

V: View

C: Controller

SpringMVC的使用_第1张图片

而: Servlet/SpringMVC 是控制器的解决方法

​ Spring是service层解决方法,能够整合第三方框架,为业务逻辑层提供事务

​ JDBC/dbutils/JdbcTempalate提供访问数据库的方案

那么也就是说SpringMVC实际上就是替代原来的Servlet

问题:现在我们有了Servlet 那么为什么我们还要使用SpringMVC呢?

原因:原来我们的Servlet在使用的时候 还是比较复杂

​ 请求参数的时候 需要自己去getParameter ,参数不能自动封装

​ Servlet:没有处理编码问题

​ 原来在使用Servlet的时候 每一个请求都需要写Servlet ---- 需要写很多的Servlet----冗余

​ 原来在做文件下载的时候 ------ 也比较复杂

​ 原来在使用Servlet返回JSON格式的时候 ------ 需要自己去转换成JSON的字符串

​ 原来在接受JSON数据额时候是没有办法直接封装成Java对象

SpringMVC简单的是就是对Servlet的一个封装

2、SpringMVC是什么

SpringMVC实际上就是一个控制器的解决方案而已

简单的说就是对Servlet的封装

就是简化了原来Servlet的功能

他里面要干的事情就跟原来一样

​ 1:接受前端数据

​ 2:将前端数据封装成对象

​ 3:调用业务逻辑

​ 4:返回数据进行封装(放到域对象)

​ 5:进行页面的跳转

SpringMVC和Spring到底是一个什么关系?SpringMVC只是Spring中的Web MVC模块而已

并不是什么框架

3、SpringMVC具体能做什么

他里面要做的事情就跟原来一样

​ 1:接受前端数据

​ 2:将前端数据封装成对象

​ 3:调用业务逻辑

​ 4:返回数据进行封装(放到域对象)

​ 5:进行页面的跳转

​ 6:文件的下载和上传 数据的自动封装 返回JSON格式的自动封装 等等…

4、SpringMVC执行原理

此处引用狂神说博客

SpringMVC的使用_第2张图片

图为SpringMVC的一个较完整的流程图,实线表示SpringMVC框架提供的技术,不需要开发者实现,虚线表示需要开发者实现。
SpringMVC的使用_第3张图片
简要分析执行流程

  1. DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求。

    我们假设请求的url为 : http://localhost:8080/SpringMVC/hello

    如上url拆分成三部分:

    http://localhost:8080服务器域名

    SpringMVC部署在服务器上的web站点

    hello表示控制器

    通过分析,如上url表示为:请求位于服务器localhost:8080上的SpringMVC站点的hello控制器。

  2. HandlerMapping为处理器映射。DispatcherServlet调用HandlerMapping,HandlerMapping根据请求url查找Handler。

  3. HandlerExecution表示具体的Handler,其主要作用是根据url查找控制器,如上url被查找控制器为:hello。

  4. HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等。

  5. HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler。

  6. Handler让具体的Controller执行。

  7. Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView。

  8. HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet。

  9. DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名。

  10. 视图解析器将解析的逻辑视图名传给DispatcherServlet。

  11. DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图。

  12. 最终视图呈现给用户。

5、使用SpringMVC的第一个HelloWorld程序(不使用注解的方式)

5.1、导包
 
        <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>
5.2、配置核心的Servlet(在web.xml中配置)
 
  <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>
5.3、编写配置文件

注意配置文件名字:核心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>
5.4、编写Controller程序
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;
    }
}
5.5、在webapp下创建一个hello.jsp文件
<%@ page contentType="text/html;charset=UTF-8" language="java"  isELIgnored="false" %>


    Title


前端获取到的数据:${username}
5.6、测试

上面这种写法存在的有问题:

每一个Controller 才对应一个路径 也就是说 一个Contoller只是处理了一个请求、并没有处理多个请求 相当于将原来的Servlet 直接的给复制了一遍没有 通用性

6、使用SpringMVC的第二个HelloWorld程序(使用注解的方式)

6.1、导包

与5.1相同,此处就不再重复

6.2、编写web.xml配置文件

与5.2相同,此处就不再重复

6.3、编写配置文件

<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>
6.4、编写Controller
@Controller                   //表示的是当前这个类是一个控制器
@RequestMapping("/say")     //当前这个控制器 映射的大的路径(可以不写)
public class UserController {
    
    @RequestMapping(value = "/hello")     //当前的方法映射的路径(小的路径)
    public String sayHello(){
        System.out.println("hello world...");
        //表示返回的页面
        return "/hello.jsp";
    }
}
6.5、解决配置文件路劲的问题

如果使用注解方式,需要告诉它 配置文件在哪里

  <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>

7、SpringMVC如何向前端返回数据

7.1、第一种返回第数据的方式
 @RequestMapping(value = "xx1")
    public String aa1(HttpServletRequest request){
        System.out.println("hello...");
        request.setAttribute("title","哈哈哈哈哈");
        return "/hello.jsp";
    }
7.2、第二种返回数据的方式
   @RequestMapping(value = "aa1")
    public ModelAndView aa1(ModelAndView modelAndView){
        System.out.println("hello...");
        modelAndView.setViewName("/hello.jsp");
        modelAndView.addObject("title","第二种返回数据的方式");
        return modelAndView;
    }
7.3、第三种返回数据的方式
  @RequestMapping(value = "aa3")
    public String aa1(Model model){
        System.out.println("hello world...");
        model.addAttribute("title2","你懂的...");
        return "/hello.jsp";
    }
7.4、拓展:Contoller转发到Controller 然后传递数据的问题
7.4.1编写Controller
   @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";
    }
7.4.2、编写jsp测试
<%@ page contentType="text/html;charset=UTF-8" language="java"  isELIgnored="false" %>


    Title


前端获取到的数据
第一种方法:${username}
第er种方法:${username1}
第san种方法:${username2}
7.4.3测试结果

前端页面能获取到相应字段的数据,因为前后都是一个请求,是请求转发

如果使用重定向会出现使用重定向的那一个会取不到数据

 @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在前端会获取不到数据

8、SpringMVC如何接受前端传递过来的数据

8.1、传递简单的键值对的数据
 /**
     * 测试传递简单参数
     * @param deptName
     * @param deptDes
     * @return
     */
    @RequestMapping("parameter1")
    public String parameter1(String deptName,String deptDes){
        System.out.println("传递过来的数据是:"+deptName+"------"+deptDes);
        return "/hello.jsp";
    }
8.2、传递键值对自动封装成对象
 /**
     * 接受数据的第二种方式直接封装成对象
     * 结论:只要前端传递过来的键值对的名称  和 后台对象中 属性的名称保持一致就可以了
     * @param dept
     * @return
     */
    @RequestMapping("parameter2")
    public String parameter2(Dept dept){
        System.out.println("传递过来的数据是:"+dept);
        return "/hello.jsp";
    }
8.3、在同一个页面同一个方法不同对象相同的属性如何区分的问题

两个实体属性字段一致,在前端如何传数据给后端,后端如何接收?

实体代码:例如(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;
}
8.3.1、首先就是前端页面编写
 <%--用户的实体--%>
  
用户数据
用户名:
密码:<
管理员数据
用户名:
密码:<
8.3.2、编写后端Controller
 /**
     * 传递参数的第四种方法
     * @return
     */
    @RequestMapping("parameter4")
    public String parameter3(UserAndAdmin userandAdmin){
        System.out.println("传递过来的用户数据是:"+userandAdmin.getUser());
        System.out.println("传递过来的管理员数据是:"+userandAdmin.getAdmin());
        return "/hello.jsp";
    }
8.4、前端传递集合数据如何接受

实体类:

/**
 * 用户实体类
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private int id;
    private String username;
    private String password;
    private int [] habbits;
}
8.4.1、前端代码的编写
用户名:
密码:
你的爱好: 美女 帅哥 其他
用户名:
密码:
你的爱好: 美女 帅哥 其他
用户名:
密码:
你的爱好: 美女 帅哥 其他
用户名:
密码:
你的爱好: 美女 帅哥 其他
8.4.2、后台接受数据的编写
@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";
    }
8.5、前端传递chexkbox类型的数据后台如何处理(传数组)
    /**
     * 传递参数的第四种方法
     * @return
     */
    @RequestMapping("parameter5")
    public String parameter5(int[] habbits){
        System.out.println(habbits);
        return "/hello.jsp";
    }

ut type=“submit” value=“提交”>

```
8.4.2、后台接受数据的编写
@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";
    }
8.5、前端传递chexkbox类型的数据后台如何处理(传数组)
    /**
     * 传递参数的第四种方法
     * @return
     */
    @RequestMapping("parameter5")
    public String parameter5(int[] habbits){
        System.out.println(habbits);
        return "/hello.jsp";
    }

你可能感兴趣的:(Spring,spring,mvc,java)