Erlo

SpringMVC笔记

2024-06-07 13:29:20 发布   64 浏览  
页面报错/反馈
收藏 点赞

1 SpringMVC简介和体验

1.1 SpringMVC简介

Spring Web MVC是基于Servlet API构建的原始Web框架,从一开始就包含在Spring Framework中。正式名称“Spring Web MVC”来自其源模块的名称( spring-webmvc ),但它通常被称为“Spring MVC”。

在控制层框架历经Strust、WebWork、Strust2等诸多产品的历代更迭之后,目前业界普遍选择了SpringMVC作为Java EE项目表述层开发的首选方案。之所以能做到这一点,是因为SpringMVC具备如下显著优势:

- Spring 家族原生产品,与IOC容器等基础设施无缝对接
- 表述层各细分领域需要解决的问题全方位覆盖,提供全面解决方案
- 代码清新简洁,大幅度提升开发效率
- 内部组件化程度高,可插拔式组件即插即用,想要什么功能配置相应组件即可
- 性能卓著,尤其适合现代大型、超大型互联网项目要求

原生Servlet API开发代码片段

protected void doGet(HttpServletRequest request, HttpServletResponse response) 
                                                        throws ServletException, IOException {  
    String userName = request.getParameter("userName");
    
    System.out.println("userName="+userName);
}

基于SpringMVC开发代码片段

@RequestMapping("/user/login")
public String login(@RequestParam("userName") String userName,Sting password){
    
    log.debug("userName="+userName);
    //调用业务即可
    
    return "result";
}

1.2 核心组件和调用流程(面试题)

Spring MVC与许多其他Web框架一样,是围绕前端控制器模式设计的,其中 中央控制器 Servlet DispatcherServlet 做整体请求处理调度!

除了DispatcherServletSpringMVC还会提供其他特殊的组件协作完成请求处理和响应呈现。

SpringMVC处理请求流程:

SpringMVC涉及组件:

  1. DispatcherServlet(中央控制器) : SpringMVC提供,我们需要使用web.xml配置使其生效,它是整个流程处理的核心,所有请求都经过它的处理和分发![ CEO ]
  2. HandlerMapping(映射器) : SpringMVC提供,我们需要进行IoC配置使其加入IoC容器方可生效,它内部缓存handler(controller方法)和handler访问路径数据,被DispatcherServlet调用,用于查找路径对应的handler![秘书]
  3. HandlerAdapter (适配器): SpringMVC提供,我们需要进行IoC配置使其加入IoC容器方可生效,它可以处理请求参数和处理响应数据数据,每次DispatcherServlet都是通过handlerAdapter间接调用handler,他是handler和DispatcherServlet之间的适配器![经理]
  4. Handler(需要手动自己写的) : handler又称处理器,他是Controller类内部的方法简称,是由我们自己定义,用来接收参数,向后调用业务,最终返回响应结果![打工人]
  5. ViewResovler (视图解析器): SpringMVC提供,我们需要进行IoC配置使其加入IoC容器方可生效!视图解析器主要作用简化模版视图页面查找的,但是需要注意,前后端分离项目,后端只返回JSON数据,不返回页面,那就不需要视图解析器!所以,视图解析器,相对其他的组件不是必须的![财务]

1.3 SpringMVC入门程序

image

  1. 配置Maven

    需要先去下载maven并且配置

    https://maven.apache.org/download.cgi

image

maven的仓库(修改的是conf下的setting.xml)

E:softwaremvn_repo
D:softwaremvn_repo
表示的是maven的仓库地址(最终通过maven下载的依赖等 都会存储在这个位置)

阿里云镜像(修改的是conf下的setting.xml)


nexus-aliyun
*
Nexus aliyun
http://maven.aliyun.com/nexus/content/groups/public

使用国内镜像下载的更快

Maven整合在idea中

image

image

  1. 创建项目

image

项目结构

少了写java的地方

image

解决方法:

image

  1. 导入依赖

    
        6.0.6
        9.1.0
        17
        17
        UTF-8
    
    
    
        
        
            org.springframework
            spring-context
            ${spring.version}
        
    
        
        
        
        
            jakarta.platform
            jakarta.jakartaee-web-api
            ${servlet.api}
            provided
        
    
        
        
            org.springframework
            spring-webmvc
            ${spring.version}
        
    
    
    
  2. Controller声明

package com.gqk.controller;
   import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
   import org.springframework.web.bind.annotation.ResponseBody;
   /**
    * 此类用来接收客户端请求和响应客户端请求的
    */
   @Controller//表示HelloController为控制器
   public class HelloController {
       @RequestMapping("/hello")//表示请求路径
       @ResponseBody//表示向浏览器响应数据
       public String hello(){
           return "hello World!!";
       }
   }
  1. 基于xml注解的方式编写

    1. 在resources编写SpringMVC的主配置文件

      
      
          
          
          
          
      
      
    2. 在web.xml中配置前段控制器

       
        
          dispatcherServlet
          org.springframework.web.servlet.DispatcherServlet
          
          
            contextConfigLocation
            classpath:springmvc.xml
          
          1
        
        
          dispatcherServlet
          /
        
      
  2. 配置Tomcat服务器(选择10以上版本)

image

image

image

image

image

启动tomcat

  1. 测试

image

  1. Spring MVC核心组件配置类(此种方式替换xml的方式)

    不需要编写上面第5步的操作

    package com.gqk.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.HandlerAdapter;
    import org.springframework.web.servlet.HandlerMapping;
    import org.springframework.web.servlet.config.annotation.EnableWebMvc;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
    import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
    
    @EnableWebMvc//开启注解
    @Configuration//表示此类为配置类
    @ComponentScan(basePackages = "com.gqk.controller")//扫描包
    public class SpringMvcConfig implements WebMvcConfigurer {
        @Bean
        public HandlerMapping handlerMapping(){
            return new RequestMappingHandlerMapping();
        }
    
        @Bean
        public HandlerAdapter handlerAdapter(){
            return new RequestMappingHandlerAdapter();
        }
         @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/**").addResourceLocations("/");
        }
    }
    
    
  2. SpringMVC环境搭建

    package com.gqk.config;
    
    import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
    
    //TODO: SpringMVC提供的接口,是替代web.xml的方案,更方便实现完全注解方式ssm处理!
    //TODO: Springmvc框架会自动检查当前类的实现类,会自动加载 getRootConfigClasses / getServletConfigClasses 提供的配置类
    //TODO: getServletMappings 返回的地址 设置DispatherServlet对应处理的地址
    public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    
        /**
         * 指定service / mapper层的配置类
         */
        @Override
        protected Class>[] getRootConfigClasses() {
            return null;
        }
    
        /**
         * 指定springmvc的配置类
         * @return
         */
        @Override
        protected Class>[] getServletConfigClasses() {
            return new Class>[] { SpringMvcConfig.class };
        }
    
        /**
         * 设置dispatcherServlet的处理路径!
         * 一般情况下为 / 代表处理所有请求!
         */
        @Override
        protected String[] getServletMappings() {
            return new String[] { "/" };
        }
    }
    
    
  3. 启动测试

访问:http://localhost:8080/hello

image

表示成功

2 SpringMVC接收客户端数据

2.1 访问路径详解

@RequestMapping注解的作用就是将请求的 URL 地址和处理请求的方式(handler方法)关联起来,建立映射关系。

SpringMVC 接收到指定的请求,就会来找到在映射关系中对应的方法来处理这个请求。

  1. 精准路径匹配

    在@RequestMapping注解指定 URL 地址时,不使用任何通配符,按照请求地址进行精确匹配。

    @Controller
    public class UserController {
    
        /**
         * 精准设置访问地址 /user/login
         */
        @RequestMapping(value = {"/user/login"})
        @ResponseBody
        public String login(){
            System.out.println("UserController.login");
            return "login success!!";
        }
    
        /**
         * 精准设置访问地址 /user/register
         */
        @RequestMapping(value = {"/user/register"})
        @ResponseBody
        public String register(){
            System.out.println("UserController.register");
            return "register success!!";
        }
        
    }
    
    
  2. 模糊路径匹配

在@RequestMapping注解指定 URL 地址时,通过使用通配符,匹配多个类似的地址

@Controller
public class ProductController {

    /**
     *  路径设置为 /product/*  
     *    /* 为单层任意字符串  /product/a  /product/aaa 可以访问此handler  
     *    /product/a/a 不可以
     *  路径设置为 /product/** 
     *   /** 为任意层任意字符串  /product/a  /product/aaa 可以访问此handler  
     *   /product/a/a 也可以访问
     */
    @RequestMapping("/product/*")
    @ResponseBody
    public String show(){
        System.out.println("ProductController.show");
        return "product show!";
    }
}

2.2 附带请求方式限制

请求方式:客户端以何种方式发送的请求 有8中

public enum RequestMethod {
  GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
}

最常用的有两种:GET、POST

默认情况下:@RequestMapping("/logout") 任何请求方式都可以访问!

如果需要特定指定:

package com.gqk.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class UserController {

    /**
     * value:表示的是请求地址
     * method:指明请求方式
     * 中文乱码:
     *  解决方法:produces = "text/plain;charset=UTF-8"
     * @return
     */
    @RequestMapping(value ="/login",method = RequestMethod.GET,produces = "text/plain;charset=UTF-8")
    @ResponseBody
    public String userLogin(){
        return "我是登录...";
    }
    @RequestMapping(value = "/add",method = RequestMethod.POST,produces = "text/plain;charset=UTF-8")
    @ResponseBody
    public String userAdd(){
        return "我是添加...";
    }


}

注意:服务端需要什么请求,客户端就安装什么请求发送否则会报错误代码405

还有 @RequestMapping 的 HTTP 方法特定快捷方式变体:

  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @DeleteMapping
  • @PatchMapping
@RequestMapping(value="/login",method=RequestMethod.GET)
||
@GetMapping(value="/login")

2.3 客户端参数传递(重点)

2.3.1 param参数接收

只要形参数名和类型与传递参数相同,即可自动接收!

客户端代码:login.jsp

  

用户名称:

用户密码:

服务端代码:

![image-20240507162545386](/image-20240507162545386.png)package com.gqk.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("myController")
public class MyController {
    @GetMapping("/login")
    @ResponseBody
    public String login(String name,String pwd){
        System.out.println("name:"+name+" pwd:"+pwd);
        return "LOGIN";
    }
}

注意:form表单中的name属性必须和方法中的参数保持一致

image

image

  1. @RequestParam注解

    此注解也是用来获取客户端传递的参数的

    @RequestParam使用场景:

    • 指定绑定的请求参数名
    • 要求请求参数必须传递
    • 为请求参数提供默认值

    客户端代码

        

    用户名称:

    用户密码:

    控制器代码

    @Controller
    public class UserController {
        @RequestMapping("/login")
        @ResponseBody
        public String login(@RequestParam("uname") String name,
                            @RequestParam("upwd") String pwd){
            System.out.println("用户名:"+name);
            System.out.println("密码为:"+pwd);
            return "login";
        }
    

    注意:form表单中的name属性xxxx必须和@RequestParam("xxxx")参数保持一致

    如果没有获取到参数此时会报400错误

image

将参数设置非必须,并且设置默认值:

客户端发送多个值(List集合)

客户端代码:

用户注册

用户爱好:

学习 唱歌 跳舞

服务端代码:

  @RequestMapping("/regist")
    @ResponseBody
    public String regist(@RequestParam List like){
        System.out.println("爱好为:"+like);
        return "regist";
    }

注意:form表单的name属性必须和regist方法中的参数名称保持一致

实体类接收参数

当客户端传递参数过多的时候(比如用户的注册信息)此时一个一个传参麻烦

需要将所有的参数直接封装到对象中,通过对象直接获取客户端传递的参数

前段代码:

用户名称:

用户密码:

用户性别:

用户爱好:

学习 唱歌 跳舞

实体类

实体类的属性和上面表单中的name属性保持一致

@Data
public class User {
    private String name;
    private String pwd;
    private String sex;
    private List like;

}

控制层

@RequestMapping("/regist2")
    @ResponseBody
    public String regist2(User user){
        System.out.println(user);
        return "regist2";
    }

2.3.2 路径 参数接收

路径传递参数是一种在 URL 路径中传递参数的方式。在 RESTful 的 Web 应用程序中,经常使用路径传递参数来表示资源的唯一标识符或更复杂的表示方式。而 Spring MVC 框架提供了 @PathVariable 注解来处理路径传递参数。

@PathVariable 注解允许将 URL 中的占位符映射到控制器方法中的参数。

例如,如果我们想将 /user/{id} 路径下的 {id} 映射到控制器方法的一个参数中,则可以使用 @PathVariable 注解来实现。

下面是一个使用 @PathVariable 注解处理路径传递参数的示例:

/**
 * 动态路径设计: /user/{动态部分}/{动态部分}   动态部分使用{}包含即可! {}内部动态标识!
 * 形参列表取值: @PathVariable Long id  如果形参名 = {动态标识} 自动赋值!
 *              @PathVariable("动态标识") Long id  如果形参名 != {动态标识} 可以通过指定动态标识赋值!
 *
 * 访问测试:  /param/user/1/root  -> id = 1  uname = root
 */ 
@RequestMapping("/add/{id}/{name}")
    @ResponseBody
    public String add(@PathVariable Integer id,
                      @PathVariable("name") String uname){
        System.out.println("id: "+id+" name: "+uname);
        return "add";
    }

2.3.3 Json参数接收

前端传递 JSON 数据时,Spring MVC 框架可以使用 @RequestBody 注解来将 JSON 数据转换为 Java 对象。@RequestBody 注解表示当前方法参数的值应该从请求体中获取,并且需要指定 value 属性来指示请求体应该映射到哪个参数上。其使用方式和示例代码如下:

json数据类型:

前端传递json数据类型以下面的方式

{
    name:"admin",
    age:18,
    sex:"男"
}

实体类对象:

实体类对象中的属性要和json中的key保持一致

@Data
public class Person {
    private String name;
    private Integer age;
    private String sex;
}

控制器:

  @RequestMapping("/addPerson")
    @ResponseBody
    public Person addPerson(@RequestBody Person person){
        System.out.println(person);
        return person;
    }

postman测试:

image

原因:

  • 不支持json数据类型处理
  • 没有json类型处理的工具(jackson)

pom添加依赖jakson


    com.fasterxml.jackson.core
    jackson-databind
    2.15.0

正确的结果

image

3 SpringMVC响应数据

响应数据:服务端(控制层)到客户端(浏览器)

3.1 返回模版视图(jsp)

1. 导入jsp的依赖

在pom.xml中添加



    jakarta.servlet.jsp.jstl
    jakarta.servlet.jsp.jstl-api
    3.0.0

2. jsp页面创建

建议位置:/WEB-INF/下,避免外部直接访问!

位置:/WEB-INF/views/home.jsp




    Title


    

欢迎${name}登录

3. 配置jsp的视图解析器

@EnableWebMvc
@Configuration
@ComponentScan(basePackages = "com.gqk.controller")
public class SpringMvcConfig implements WebMvcConfigurer {
    @Bean
    public HandlerMapping handlerMapping(){
        return new RequestMappingHandlerMapping();
    }
    @Bean
    public HandlerAdapter handlerAdapter(){
        return new RequestMappingHandlerAdapter();
    }
	//配置jsp的视图解析器
    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.jsp("/WEB-INF/views/",".jsp");
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("/");
    }
}

4. 编写控制器

  @RequestMapping("/home")
    public String home(Model model){
        model.addAttribute("name","gqk");
        return "home";//相当于跳转至home.jsp
    }

5. 测试

输入:http://localhost:8080/home

image

3.2 转发和重定向

在 Spring MVC 中,Handler 方法返回值来实现快速转发,可以使用 redirect 或者 forward 关键字来实现重定向。

@RequestMapping("/redirect-demo")
public String redirectDemo() {
    // 重定向到 /demo 路径 
    return "redirect:/demo";
}

@RequestMapping("/forward-demo")
public String forwardDemo() {
    // 转发到 /demo 路径
    return "forward:/demo";
}

3.3 返回JSON数据(重点)

json数据格式

{
    "name":"admin",
    "age":18
}

1. 导入jackson依赖


    com.fasterxml.jackson.core
    jackson-databind
    2.15.0

2. 添加json数据转化器

在配置类中添加@EnableWebMvc

@EnableWebMvc
@Configuration
@ComponentScan(basePackages = "com.gqk.controller")
public class SpringMvcConfig implements WebMvcConfigurer {
}

编写实体类Person

@Data
public class Person {
    private int id;
    private String name;
    private String sex;
    private Date date;
}

3.控制器方法中添加注解@ResponseBody

    @RequestMapping("/query")
    @ResponseBody//自动返回json对象
    public Person queryPerson(){
        Person person = new Person();
        person.setId(101);
        person.setName("gqk");
        person.setSex("男");
        person.setDate(new Date(95,4,20));
        return person;
    }

4. SpringMVC+Ajax(重点)

SpringMVC默认情况下不能访问静态资源(html,css,js......)

在webapp下面编写login.html




    
    Title


用户名称:

用户密码:

访问的时候404

image

4.1SpringMVC静态资源的处理

开启静态资源处理

在配置类中MyWebAppInitializer.java

package com.gqk.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
@EnableWebMvc
@Configuration
@ComponentScan(basePackages = "com.gqk.controller")
public class SpringMvcConfig implements WebMvcConfigurer {
    @Bean
    public HandlerMapping handlerMapping(){
        return new RequestMappingHandlerMapping();
    }
    @Bean
    public HandlerAdapter handlerAdapter(){
        return new RequestMappingHandlerAdapter();
    }

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.jsp("/WEB-INF/views/",".jsp");
    }

   /* @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("/");
    }*/
   //开启静态资源处理 
   @Override
   public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
       configurer.enable();
   }
}

4.2 ajax发送请求

Jquery支持ajax的 所以首先需要下载Jquery的类库

4.2.1 在html页面引入jquery类库


image

测试jquery是否引入成功



image

https://www.runoob.com/jquery/jquery-ajax-intro.html

ajax语法:

$.get(URL,callback);
或
$.post( URL [, data ] [, callback ] [, dataType ] )

4.2.2 ajax发送请求

无参数的访问

客户端页面




    
    Title




用户名称:

用户密码:

服务端代码:

@Controller
public class UserController {

    @RequestMapping("/login1")
    @ResponseBody//返回给ajax的回调函数
    public String login1(){
        return "success";
    }
}

带参数发送ajax

 $.post("/login1",{'name':'gqk','pwd':"123456"},function (data){
                alert(data)
  })

登录页面发送ajax




    
    Title




用户名称:

用户密码:

服务端代码:

package com.gqk.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class UserController {

    @RequestMapping("/login1")
    @ResponseBody//返回给ajax的回调函数
    public String login1(@RequestParam("name")String name,
                         @RequestParam("pwd") String pwd){
        System.out.println(name);
        System.out.println(pwd);
        return name+" "+pwd;
    }
}

登录查看全部

参与评论

评论留言

还没有评论留言,赶紧来抢楼吧~~

手机查看

返回顶部

给这篇文章打个标签吧~

棒极了 糟糕透顶 好文章 PHP JAVA JS 小程序 Python SEO MySql 确认