【JavaEE】SpringMVC

目录

SpringMVC

获取连接

@RequestMapping / @GetMapping...

获取参数

获取querystring中的参数(获取表单数据基本相同)

获取URL中的参数

获取JSON对象

获取文件(通过表单)

获取Cookie

获取Header

获取Session

返回数据

返回数据

返回JSON对象

返回静态页面

请求转发 + 请求重定向


SpringMVC

SpringMVC是基于Servlet的一种Web框架。

它提供了一种模型(Model)-视图(View)-控制器(Controller)架构的实现方式,可以帮助开发者更加高效地构建Web应用程序。


在SpringMVC中,

模型指的是业务逻辑和数据访问层

视图是用户界面层

控制器是将模型和视图进行关联的桥梁

SpringMVC把请求映射为一个控制器方法,这个方法会处理请求并返回一个包含模型数据和视图信息的ModelAndView对象。视图对象则负责生成最终的HTML内容,将模型数据渲染到视图上。由于现在是前后端分离的开发模式,所以现在的都是数据。

学习SpringMVC最主要的部分就是建立连接,获取参数,返回数据。

在SpringMVC这里,几乎都是通过注解来实现相应的操作,就相当于学习注解。

获取连接

@RequestMapping / @GetMapping...

这一类注解都可以获取参数,其中@GetMapping、@Post Mapping等可以看作是@RequestMapping的具体化,这些注解获取连接只能使用指定的方法。

源码如下:

  1. value/path:指定请求的URI路径或模式,即客户端发送请求的URL地址,如@RequestMapping(value="/users")表示匹配以"/users"结尾的URI路径。
  2. method:指定请求的HTTP方法,可选值为RequestMethod.GET、RequestMethod.POST等。
  3. params:指定请求参数的条件,如@RequestParam(name="id", required=true)表示必须包含名为"id"的请求参数,且不能为空。
  4. headers:指定请求头的条件,如@RequestMapping(headers="Accept=text/plain")表示只有在"Accept"请求头为"text/plain"时才会匹配。
  5. consumes:指定请求内容类型的条件,如@RequestMapping(consumes= MediaType.APPLICATION_JSON_VALUE)表示只有当请求内容类型为JSON时才会匹配。
  6. produces:指定响应内容类型的条件,如@RequestMapping(produces=MediaType.APPLICATION_JSON_VALUE)表示请求处理方法返回的内容类型为JSON。

package com.example.demo.controller;

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

@Controller // 把这个类交给Spring管理,一启动就加载
@RequestMapping("/connection")  // 这是一个获取连接的注解  内容是路由
public class TestConnectionController {

    /**
     * 测试方法不带参数的@RequestMapping注解
     */

    @RequestMapping("/test1") // 每个方法上可以加一个路由
    public void test1() {
        System.out.println("此时已经建立连接!");
        System.out.println();
    }

    @RequestMapping("/test2/other")
    public void test2() {
        System.out.println("多级路由也可以使用!");
        System.out.println();
    }

    //这样的效果相当于@PostMapping注解
    @RequestMapping(value = "/test3", method = RequestMethod.POST)
    public void test3() {
        System.out.println("若是没有指定特定方法,此注解可以使用任何方法传递");
        System.out.println("这里只能使用POST方法进行传参!");
        System.out.println("若只想用其他方法,就可以改成GET等");
        System.out.println();
    }
}

 


获取参数

获取querystring中的参数(获取表单数据基本相同)

package com.example.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;

@Controller
@RequestMapping("/parameters")
public class TestParametersController {

    /**
     * 测试表单传递参数
     */

    @RequestMapping("/test1")
    // 这里的参数部分的名称(name)要和表单中的Key名称一致
    public void test1(String name) {
        System.out.println("test1: " + name);
        System.out.println();
    }

    @RequestMapping("/test2")
    // 顺序可以不一致,但是名称一定要能对应上
    public void test2(String name, String message, String password) {
        System.out.println("test2: " + name + " : " + password + " : " + message);
        System.out.println();
    }

    @RequestMapping("/test3")
    // 如果前端的表单名字和后端不同且两边都无法修改
    // 使用@RequestParam(value="这是前端的key") 类型  这是后端的名称
    public void test3(@RequestParam(value = "username") String name) {
        System.out.println("test3: " + name);
        System.out.println();
    }

    @RequestMapping("/test4")
    public void test4(@RequestParam(required = true) String name) {
        // 这里的 name 如果是必须要传的,则可以改成 true
        // 默认是false,表示可以不用传
        System.out.println("test4: " + name);
        System.out.println();
    }

    @RequestMapping("/test5")
    public void test5(Integer id) {
        // 一般参数的类型建议使用非基本类型
        // 比如有int类型的参数,则使用其包装类Integer更好
        // 如果没有收到参数时,默认给赋值null,后续处理
        // 如果是基本类型,此时则会直接报错
        if (id == null) {
            // 此时可以返回 传参失败的提示 给前端
            // 这里暂时不做处理
        }
        System.out.println("test5: " + id);
        System.out.println();
    }

    @RequestMapping("/test6")
    public void test6(int id) {
        // 这里如果没有收到id则会报错
        System.out.println("test6: " + id);
        System.out.println();
    }

    @RequestMapping("/test7")
    public void test7(HttpServletRequest request) {
        // 也可以像之前的 Servlet 一样
        // SpringMVC中也是内置了 HttpServletRequest 和 HttpServletResponse
        // 使用方式和方法和Servlet的一样
        String name = request.getParameter("username");
        System.out.println("test7: " + name);
        System.out.println();
    }
}

 下面参数的传递都是通过querystring方法传递的,表单也是类似

 


获取URL中的参数

package com.example.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;

@Controller
@RequestMapping("/parameters")
public class TestParametersController {

    /**
     * 测试获取URL中的参数
     */

    @RequestMapping("/test8/{username}/{password}")
    // @PathVariable中的参数部分要和路由中的参数相同
    public void test8(@PathVariable("username") String name,
                      @PathVariable("password") String password) {
        System.out.println("test8: " + name + " : " + password);
        System.out.println();
    }
}


获取JSON对象

  1. 需要在后端创建一个对应的类
  2. 使用@RequestBody来接收JSON对象

与JSON对应的类

package com.example.demo.entity;

import lombok.Data;

@Data
public class User {
    private Integer id;
    private String name;
    private Integer age;
}

package com.example.demo.controller;

import com.example.demo.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;

@Controller
@RequestMapping("/parameters")
public class TestParametersController {

    /**
     * 测试接收JSON对象
     */
    @RequestMapping("/test9")
    // 对应的类中字段顺序可以不相同,但是名称要和JSON的key相同
    // 这样才可以一一映射上,否则就无法匹配赋值
    public void test9(@RequestBody User user) {
        System.out.println("test9: ");
        System.out.println(user);
        System.out.println();
    }

}


获取文件(通过表单)

package com.example.demo.controller;

import com.example.demo.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;

@Controller
@RequestMapping("/parameters")
public class TestParametersController {
    /**
     * 测试保存传来的文件
     */
    @RequestMapping("/test10")
    public void test10(@RequestPart("keyname")MultipartFile file) {
        // 创建出一个文件对象,并且指定保存路径+文件名称
        File saveFile = new File("D:\\ATest\\cat.png");
        try {
            // 通过这个方法把文件保存下来
            file.transferTo(saveFile);
            System.out.println("test10: 文件已保存!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

  

上述代码虽然保存了文件,但是有个致命的错误,就是下次再上传文件的时候,之前的旧文件会被新文件覆盖,原因是文件名写死了。 

修改代码如下:

package com.example.demo.controller;

import com.example.demo.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.UUID;

@Controller
@RequestMapping("/parameters")
public class TestParametersController {
    /**
     * 测试保存传来的文件
     */

    @RequestMapping("/test11")
    public void test11(@RequestPart("cat") MultipartFile file) {
        // 先生成一个独一无二的文件名
        // UUID生成的字符串是独一无二的
        // 把原文件的类型拿出来
        String fileName = UUID.randomUUID() +
                file.getOriginalFilename().substring(
                        file.getOriginalFilename().indexOf("."));
        File saveFile = new File("D:\\ATest\\" + fileName);
        try {
            file.transferTo(saveFile);
            System.out.println("test11: 文件已保存!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

  


获取Cookie

package com.example.demo.controller;

import com.example.demo.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.UUID;

@Controller
@RequestMapping("/parameters")
public class TestParametersController {

    /**
     * 测试获取Cookie
     */
    @RequestMapping("/test12")
    public void test12(@CookieValue(value = "cookieKey") String cookieValue) {
        System.out.println("test12: " + cookieValue);
    }
}


获取Header

package com.example.demo.controller;

import com.example.demo.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.UUID;

@Controller
@RequestMapping("/parameters")
public class TestParametersController {

    /**
     * 测试获取Header
     */
    @RequestMapping("/test13")
    public void test13(@RequestHeader(value = "Host") String headerValue) {
        System.out.println("test13: " + headerValue);
    }
}


获取Session

package com.example.demo.controller;

import com.example.demo.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.UUID;

@Controller
@RequestMapping("/parameters")
public class TestParametersController {
    /**
     * 测试获取Session
     */
    // 首先手动存储Session
    @RequestMapping("/test16")
    public void test14(HttpServletRequest request) {
        // 这里是得不到session的
        HttpSession session = request.getSession();
        // 自行设置session
        session.setAttribute("sessionKey", "sessionValue");
    }

    @RequestMapping("/test17")
    // @SessionAttribute 中的参数是 session的key
    // 通过该注解可以直接获取到对应的session的value
    public void  test18(@SessionAttribute("sessionKey") String session) {
        System.out.println("test17: " + session);
    }
}

 


返回数据

返回text/html + json/html

package com.example.demo.controller;

import com.example.demo.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;


@ResponseBody
// @ResponseBody 会自动把要返回的数据转成合适的格式
@Controller
@RequestMapping("/data")
// @Controller + @RequestMapping = @RestController
// 这两个注解可以组合写成@RestController,效果一样
public class TestReturnDataController {

    /**
     * 测试返回对象
     * @return 返回的是User对象-->JSON对象
     */
    @RequestMapping("/test2")
    public User test2() {
        User user = new User();
        user.setId(1);
        user.setName("李四");
        user.setAge(20);
        // 这里的user会自动转成JSON对象发送过去
        return user;
    }

    /**
     * 测试返回一般数据
     * @return 返回的是非对象数据
     */
    @RequestMapping("/test1")
    public String test1() {
        // 如果是字符串,会自动转成text/html
        return "这是返回的内容";
    }
}

 


返回静态页面(视图)

这种返回静态页面的方法在现在一般不使用了,前后端分离只需要返回数据即可。

package com.example.demo.controller;

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

@Controller
@RequestMapping("/page")
public class TestPageController {

    /**
     * 测试返回一个静态页面
     * @return
     */
    @RequestMapping("/static")
    // 返回类型未知都可以使用Object类来接收
    public Object test17() {
        // 第一个 /  表示根路径
        // 只有从根路径出发,才可以访问到其他页面
        return "/user/index.html";
    }
}
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <h1>这是返回的静态页面</h1>
</body>
</html>

  


请求转发 + 请求重定向

请求转发:

请求转发是指将请求从一个Web组件(如Servlet或JSP)发送到另一个Web组件,过程中不会改变URL。在请求转发期间,Web容器将控制权传递给另一个Web组件,该组件可以继续处理请求并产生响应。
简单来说就是  客户端给服务器发送请求,服务器自己继续帮客户端找资源,然后返回给客户端(这一切客户端是未知的,所以URL不会变)


请求重定向:

请求重定向是指将请求从一个Web资源(如Servlet或JSP)发送到另一个Web资源,并且在过程中会更改URL。在请求重定向期间,Web容器会向浏览器发送一个302 HTTP状态码的响应,该响应包含一个新的URL,浏览器会自动发送一个新的请求以获取新的资源。请求重定向通常用于将客户端重定向到另一个Web资源,以便实现更好的用户体验或处理不同类别的请求。

简单来说就是  客户端像服务器发送请求,服务器这里不处理这个请求,但是会给客户端一个URL,然后客户端根据返回的URL重新访问。

package com.example.demo.controller;

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

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Controller
@RequestMapping("/page")
public class TestPageController {

    // 测试请求转发
    @RequestMapping("/forward")
    public Object test18() {
        // 在转发的网址前面 写 forward:  即可
        return "forward:/user/index.html";
    }

    // 测试请求重定向
    @RequestMapping("/redirect")
    public Object test19() {
        // 在重定向的网址前面 写 redirect:  即可
        return "redirect:/user/index.html";
    }
}

请求转发(forward)结果:

请求重定向(redirect)结果:

 

可以看到URL变了。


有什么问题评论区指出。希望可以帮到你。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值