您现在的位置是:首页 >技术教程 >Spring MVC网站首页技术教程

Spring MVC

学习自省 2024-06-12 18:01:02
简介Spring MVC

日升时奋斗,日落时自省 

目录

1、MVC

1.1、MVC定义

1.2、MVC和 Spring MVC的关系

 2、Spring MVC

2.1、Spring MVC创建和连接

2.1.1、创建Spring MVC项目

2.1.2、设置路由

2.1.3、@RequestMapping的请求类型

 2.1.3、设置请求方法

3、获取参数

3.1、传递单个参数

 3.2、Servlet传递单个参数

3.3、传递对象

3.4、传递多个参数(非对象)

 3.5、设置参数必传

3.6、接收JSON对象

 3.7、获取URL中参数

 3.8、上传文件

3.9、注解获取Cookie/Session/header

4、访问页面与跳转

4.1、访问静态页面

4.2、请求转发与请求重定向


1、MVC

Spring MVC全称叫做 Spring Web MVC 是基于Servlet API构建的原始Web框架

通常叫做:“Spring MVC”

Spring MVC是一种基于Java的web框架,它是Spring Framework的一部分。

1.1、MVC定义

Spring MVC基于Model-View-Controller(MVC)软件架构模式,它通过前端控制器DispatcherServlet将HTTP请求转发给控制器Controller,然后控制器处理请求并返回对应的响应视图View,再由视图渲染器(View Resolver)将响应视图渲染为HTML文件返回给浏览器进行展示。在这个过程中,模型对象Model可以在控制器和视图之间传递数据

整个过程前后端都是在一起的

 但是现在不同了,前后端都是分开的,为的就是部分功能可以再其后进行加载,不需要上来就把所有的东西都加在出来(慢)

1.2、MVC和 Spring MVC的关系

MVC是一种思想,而,Spring MVC是对MVC思想的具体实现

可以认为Spring MVC是MVC的一种实现方式,Spring MVC是MVC架构在Web应用程序开发中的一种实现方式,是基于MVC设计模式的一种Web框架

Spring的核心就是Spring MVC ,Spring Boot是Spring的脚手架

在创建Spring Boot项目时,勾选Spring Web 框架其实就是Spring MVC框架,Spring,Spring Boot项目基本都是基于Spring MVC的

 2、Spring MVC

从以下三个功能进行解释:

<1>连接的功能:用户与Java程序连接起来,访问一个地址能够调用到Spring程序

<2>获取参数的功能:用户访问的时候会带一些参数,在程序中要想办法获取参数

<3>输出数据的功能:执行了业务逻辑后,要把程序执行结果返回给用户

2.1、Spring MVC创建和连接

Spring MVC项目创建和Spring Boot创建项目相同(Spring MVC 使用Spring Boot的方式创建),在创建的时候选择Spring Web 就相当于创建了Spring MVC的项目

在Spring MVC中使用,注解来时先URL路由映射

2.1.1、创建Spring MVC项目

Spring MVC可以基于Spring Boot创建,也就是创建一个Spring Boot项目,勾选上Spring Web模块即可

 Spring boot项目创建好以后 ,在demo包下创建controller层,controller层内写一个类,启动项目访问路由看看出现页面说明创建成功

@RestController  //让spring 框架启动时 加载
@RequestMapping("/user")  //设置路由
public class UserController {
    //路由器规则注册
    @RequestMapping("/sayhi")
    public String sayhi(){
        return "spring mvc sayhi()";
    }
}

 启动成功表示:

2.1.2、设置路由

@RequestMapping是Spring MVC框架中的注解之一,它用于将一个HTTP请求映射到一个处理器方法上,告诉DispatcherServlet处理来自客户端的一种或多种请求。

@RequestMapping的使用方式非常灵活,可以在控制器类上和控制器类中的方法上使用

@RequestMapping可以修饰类,也可以修饰方法,当修饰类和方法时,访问地址就是类+方法

注:路由可以设置多级路由

2.1.3、@RequestMapping的请求类型

访问上面设置好的路由 127.0.0.1:8080/user/sayhi

@RequestMapping是post请求还是get请求这里我们就以当前写的一个代码进行访问路由看看,是什么,F12打开检查页面,点击操作如下查看请求方法

 那post请求行不行,那我们来试一下就知道了,现在项目仍然是启动状态,这里拿postman测试一下(当然是可以的)

如果我这里规定只能接受post或者get方法其中一个呢??? 

@RequestMapping本身就支持这里请求方法,同时也可以设定

 2.1.3、设置请求方法

以下所有设置方法的代码仅此修改一行代码

 

I、只针对get请求的两种写法:

<1>@RequestMapping注解设置参数

method请求方法参数设置为RequestMethod.GET,后缀为点GET 就表示只接收GET请求

@RequestMapping(value = "/sayhi",method = RequestMethod.GET)

 这里设置以后我们重启项目(使用postman)尝试一下,看看会有什么结果,

post方法已经不被允许了

 <2>@GetMapping注解,只允许接收get方法

该注解也是可以实现只接收get请求的

    @GetMapping("/sayhi")

II、只针对post请求的两种写法:

<1>@RequestMapping注解设置参数

@RequestMapping(value = "/sayhi",method = RequestMethod.POST)

 这里设置以后我们重启项目(使用postman)尝试结果:

get请求就不行了

<2> @PostMapping注解

    @PostMapping("/sayhi")

3、获取参数

3.1、传递单个参数

Spring MVC可以直接用方法中的参数实现传参

@RestController  //让spring 框架启动时 加载
@RequestMapping("/user")  //设置路由
public class UserController {

    //路由器规则注册
    @RequestMapping("/sayhi")
    public String sayhi(String name){
        return "name 的 参数 :"+name;
    }
}

使用postman访问方法:

注:传递过程中,如果其中的参数没有给值,那就是null(但是如果这参数是基础类型,就会报错,需要使用其包装类进行获取)

这里演示一个基础类型的情况:

 3.2、Servlet传递单个参数

在Spring boot中也可以使用Servlet方式进行接收和传递请求,这里只是片段代码展示

@RequestMapping("/sayhi4")
    public String sayhi4(HttpServletRequest request, HttpServletResponse response){
        return "Servlet接收 queryString :"+request.getParameter("name");
    }

postman中访问:

 同样也可以调用Servlet中的其他方法,使用方式和Servlet一样

3.3、传递对象

并且Spring MVC可以自动实现参数对象的赋值

这里我们需要写一个实体类,存储对象属性

涉及到一个新的注解:@Data注解 是Lombok提供的是一个复合注解

注解作用
@Data@Getter + @Setter + @ToString +
@EqualsAndHashCode +
@RequiredArgsConstructor +
@NoArgsConstructor
@Data
public class User {
    private int userId;
    private String username;
    private int password;
    private int age;
}

 这里我们没有使用User类去定义方法,而是Object因为User如果是个null的话能强转吗,不能,所以防止null情况,这里直接用Object接收

@Controller
@ResponseBody
@RequestMapping("/user2")
public class UserController2 {
    @RequestMapping("/index")
    public Object sayhi(User user){
        System.out.println(user.toString());
        return user;
    }
}

3.4、传递多个参数(非对象)

  能传一个参数,也就能传递多个参数

@Controller
@ResponseBody
@RequestMapping("/user2")
public class UserController2 {
    @RequestMapping("/index2")
    public String sayhi(String name ,String password){
        return  "name:"+name+" | password "+password;
    }
}

进行路由访问:

 3.5、设置参数必传

上面的所有例子,都没有设置传参类型,如果没有传值的情况下都为null,@RequestParam注解设置参数必传,可以将要紧的参数传值设为必须,提高了数据的连贯性

同时也可以更改需要接收的参数的名称

@RequestParam内部:

注:默认状态下,只要使用@RequestParam注解,参数就必须有(下面附加的代码required设置为true其实是灰色的,默认状态)

 在原来的访问中,我这里都使用的是name传输数据和接收数据,但是现在前端就不想用name传,那不争的情况下就使用如下操作(这里required其实可以不写因为是默认值):

@Controller
@ResponseBody
@RequestMapping("/user2")
public class UserController2 {
    @RequestMapping("/index2")
    public String sayhi(@RequestParam(value = "username",required = true) String name , String password){
        return  "name:"+name+" | password "+password;
    }
}

注:这里required设置参数为false,就可以不穿参数,并且也不会报错 

postman路由访问:

 注:使用别名之后就不能再使用原来的名称

如果此时不传username的参数,会报错

注:如果不想让这个值是必传值,只是想改一个名称,这里required参数设置为false就可以了

3.6、接收JSON对象

普通方法是接收不了JSON对象,此处需要对应的注解来接收JSON格式的数据

这里我们先写一个实体类,我们这里接收一个对象(还是前面的创建过的User类对象)

@Data
public class User {
    private int userId;
    private String username;
    private int password;
    private int age;
}

注:设置形参的前面加上该注解(此处注解设置required设置false就是可以不传值也不会报错)

@Controller
@ResponseBody
@RequestMapping("/user3")
public class UserController3 {
    @RequestMapping("/method")
    public Object method_5(@RequestBody(required = false) User user){
        System.out.println("user:"+user);
        return user;
    }
}

postman测试代码:

 postman功能比较多,这里大体简述下面的这节选择

 3.7、获取URL中参数

@PathVariable注解,在参数较少的特殊情况下可以给路径中加入参数,直接从路径中获取

该注解有点类似于queryString,但是比queryString更快,直接将参数放在路径中,在访问路径的时候参数已经被拿到了,相比获取访问路径后,再获取url后面的请求参数更快

代码:

@Controller
@ResponseBody
@RequestMapping("/user3")
public class UserController3 {
    @RequestMapping("/method2/{name}/{password}")
    public Object method2(@PathVariable String name,@PathVariable String password){
        return "name:"+name+" | password:"+password;
    }
}

这里注解中路径涵盖参数 是需要与我们写的参数一样的,形参是什么,这里就需要写什么(用大括号抱起来) 

postman测试结果: 

 如果参数不一样,那就获取不到了,也会直接报错,因为没有参数传递进来,默认必传参数

如果真的不想写一样的,那就需要我们亲自去设置了(注解中参数设置一个需要的别名)

注解参数中取一个别名(路径中和别名一样就行)

 3.8、上传文件

@RequestPart针对上传文件一个注解,同时也对应这定义的类是MultipartFile(这里需要注意)

代码(注释比较详细):

@RestController
@RequestMapping("/file")
public class FileController {
    //第一个参数其实没有啥实际意义, 第二个参数需要使用@RequestPart注解修饰
    //形参定义 也必须是 MultipartFile类型 才能被接收
    @RequestMapping("/param")
    public Object param(String name, @RequestPart("myfile")MultipartFile file){
        //获取文件名后缀     文件名这里我们只取点 后面的部分
        String fileNamelast=file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        //新的文件名   文件名 + 后缀
        String filename= UUID.randomUUID()+fileNamelast;
        //这里存放的就是路径了 路径 + 文件名
        File savefile=new File("E:\Test\"+filename);
        //将选择文件传到 我们选择的路径下
        try {
            file.transferTo(savefile);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }
}

postman测试结果:

启动类后路径下实现操作:

3.9、注解获取Cookie/Session/header

<1>传统方式获取Cookie

 Spring MVC就是在Web应用程序开发中的一种实现方式,所以同样能使用原来的方式进行操作

@Controller
@ResponseBody
@RequestMapping("/user3")
public class UserController3 {
    @RequestMapping("/param10")
    public String param10(HttpServletRequest request, HttpServletResponse response){
        String name=request.getParameter("name");
        //获取cookie信息
        Cookie[] cookies=request.getCookies();
        String userAgent=request.getHeader("User-Agent");
        return name+" : "+ userAgent;
    }
}

注:当前cookie是什么都没有的,所以这里也看见啥(下面使用注解时候给友友们展示cookie)

<2>使用@CookieValue注解获取Cookie

代码很简单,@CookieValue注解传参就是cookie名称,

@RequestMapping("/cookie")
    public String method(@CookieValue(value = "bite",required = false) String bite){
        return "cookie:"+bite;
    }

 F12设置以下cookie的名称和值,刷新一下网页

 再次刷新的结果:

 <3>@RequestHeader注解获取header值

一级路由:还是user3

@RequestMapping("/header")
    public String header(@RequestHeader("User-Agent")String userAgent){
        return "User-Agent:"+userAgent;
    }

访问路由结果: 

 <4>@SessionAttribute注解获取Session值

注:没有注解设置Session值,只能使用注解获取,所以这里再写获取Session值时还需要写设置Session值

//这里设置一个 Session的键   其实也可以不用设定,就是为了好看 
    private static final  String SESSION_KEY="USERINFO_SESSION_KEY";
    //Session 设置   
    @RequestMapping("/setsession")
    public String setsession(HttpServletRequest request){
        //获取 HttpSession 对象的参数 参数true
        HttpSession session=request.getSession(true);
        if(session!=null){
            //给session设置一个哈希值
            session.setAttribute(SESSION_KEY,hashCode());
        }
        return "session 设置成功";
    }
    //获取session
    @RequestMapping("/getsession")
    public Object getSession(@SessionAttribute(value =SESSION_KEY,required = false)String content){
        return "session ->"+content;
    }

首先 要先 访问 设置Session的路由,然后才是访问获取Session路由

设置session路由:

 获取session路由:

4、访问页面与跳转

4.1、访问静态页面

在访问静态页面的时候一定记得把依赖带上,否则会访问不了

在pom.xml文件中导入依赖,我们在开始的时候一般都会导入的

 代码:

//不能使用该注解@ResponseBody,该注解是将显示内容转化为字符串的,这里为了显示静态页面
@Controller
@RequestMapping("/user4")
public class UserController4 {
    @RequestMapping("/index")
    public Object method(){
        return "/index.html";
    }
}

访问路由结果: 

4.2、请求转发与请求重定向

return不能返回视图,但是可以通过跳转到视图,跳转方式这里涉及到两个关键词(forward,redirect)

<1>forward:针对请求转发

举个例子:请求转发是当前请求需要去一个地方交给了另一个人来跑腿(转发过去),但是这件事情还是我的(url还是我的),前面提到访问静态页面的方法就是一个请求转发,注意到细节的友友们应该会看见其实url是没有改变的,但是页面发生了变化

这里来看一下演示代码预期结果:

@Controller
@RequestMapping("/user4")
public class UserController4 {
    @RequestMapping("/index")
    public String method(){
        return "forward:/index.html";
    }
}

<2>redirect:针对请求重定向

请求重定向是资源重新定位,我需要去一个地方,我们没有请人去,我亲自去的(指哪到哪url会改变跳转到我们要去的位置)

@RequestMapping("/index2")
    public String method2(){
        return "redirect:/index.html";
    }

 <3>forward和redirect区别

I、请求重定向(redirect)将请求重新定位到资源;请求转发(forward)服务器端转发

II、请求重定向地址发生变化,请求转发地址不发生变化

III、请求重定向与直接访问新地址的效果一样,不存在原来的外部资源不能访问;请求转发服务器端转发有可能造成原外部资源不能访问

注:请求转发forward诱发问题:请求转发毕竟不是自己亲自移动到对应的url,资源和转发页面不在同一目录下,导致资源不可访问

 

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。