• SpringMVC------JavaEE(实现前后端交互)


    fatal是当程序被迫终止后才会打印此日志

    1)他的全称为Spring Web MVC是基于Servlet API构建的原始Web框架,但是他一开始就包含在Spring框架里面,是SpringBoot的一个外部模块

    2)由此我们可以得知:Spring MVC是一个Web框架,Spring MVC是基于Servlet API进行实现的

    3)我们在进行创建SpringBoot项目的时候,我们进行勾选的Spring Web选项其实就是Spring MVC框架,我们可以看到从pom.xml里面就可以看到spring-boot-starter-web

    我们加上Spring Boot DevTools是为了可以完成热部署的;

    4)Spring MVC要进行学习的内容:

    1)连接的功能:将用户(浏览器)和java程序进行连接起来,也就是说访问一个地址可以调用到我们的Spring程序

    2)获取参数:用户访问的时候会带一些参数,要想办法在程序中获取到这些参数

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

    一:解析:MVC通常是Model View Controller,他是软件工程中的一种常见的架构模式,他把软件系统分为模型,视图和控制器三个部分

    1)模型(Model):是应用程序中用于处理应用程序数据逻辑的部分,通常模型对象负责在数据库中存储数据

    2)视图(View):是应用程序中用于处理数据显示的部分,通常视图是一句模型数据进行创建的;

    3)控制器(Controller):通常是应用程序中用来处理用户交互的部分,通常控制器负责从视图中读取数据,控制用户输入,并向模型发送数据;

    二:MVC是一种思想,Spring MVC是对MVC思想的实现,是一种MVC模式,并继承了Servlet API的WEB框架,既然是WEB框架,那么用户在浏览器上面输入了url之后,我们的SpringMVC就可以进行感知用户的请求;

    在application.properties写上这段代码:debug=true

    三:路由映射:就是当用户访问一个url的时候,将用户的某个请求对应到程序中的某个类的某个方法的过程中就叫做路由映射

    1.接下来进行创建一个UserController类,来实现用户和Spring程序的互联互通

    @Controller//让Spring框架启动的时候,存储和获取加载这个类
    public class UserController {
        @RequestMapping("/java200")//表示请求映射直接映射到某个方法上面
        @ResponseBody//加上这个注解之后,说明表示当前的方法/类返回的是非界面而是一个数据
        public String start()
        {
            return "helloSpringMVC";
        }
    }
    我们在Main目录下的resorces的static里面创建了一个html文件,下面我们来改一下后端代码:
    1. @RequestMapping("/java200")//表示请求映射直接映射到某个方法上面
    2. // @ResponseBody//加上这个注解之后,说明表示当前的方法/类返回的是非界面而是一个数据
    3. public String start()
    4. {
    5. return "/Text.html";
    6. }
    7. }

    上面的内容都是在浏览器上面输入:http://localhost:8080/java200这个地址就可以访问到Text.html这个页面了

    1. 如果说我们给类加上一个路由注解
    2. @Controller
    3. @RequestMapping("ContextPath")
    4. public class UserController {
    5. @RequestMapping("/java200")//表示请求映射直接映射到某个方法上面
    6. // @ResponseBody//加上这个注解之后,说明表示当前的方法/类返回的是非界面而不是一个数据
    7. public String start()
    8. {
    9. return "/Text.html";
    10. }
    11. }
    12. 在static里面创建一个Text.html页面:
    13. html>
    14. <html lang="en">
    15. <head>
    16. <meta charset="UTF-8">
    17. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    18. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    19. <title>Documenttitle>
    20. head>
    21. <body>
    22. <div>我想成为一个很厉害的程序员div>
    23. body>
    24. html>

    我们此时要在浏览器上面输入的地址就变成这个了http://localhost:8080/ContextPath/java200

    1)@RequestMappering的作用就是用来注册一个URL路由,通过这个路由,就可以进行实现前端的请求和后端程序的交互了,但是@RequestMappering这个注解实际可以修饰方法,也是可以修饰类的

    2)我们在默认情况下使用@RequestMappering会返回一个html界面,但是加上

    @RsponseBody就会返回一个非页面的数据了

    3)当我们使用@RequestBody来进行修饰一个类的时候,这就表示当前类中的所有方法会返回一个非页面的数据

    4)同样我们还可以进行指定发送请求的类型:

    @RequestMapping(value="/java200",method= RequestMethod.GET),如果说我们在Postman上面发送了一个POST请求,就会出现405的报错信息
    1. Controller
    2. public class UserController {
    3. @RequestMapping(value="/Java",method=RequestMethod.GET)
    4. @ResponseBody
    5. public String start(String name)
    6. {
    7. return name+"要你管";
    8. }
    9. }

    5)@RequestMappering在不进行指定任何参数的情况下,只进行设置路由地址,那么此方法是即支持GET请求又是支持POST请求的,但是当我们给@RequestMapping设置了Method属性之后,那么它只能支持设置的请求类型,其他类型时会报错的(405)

    我们也是可以这么写的:@GetMapping("/Get");

    2.SpringBoot热加载进行配置(每一次修改Idea代码的时候不需要进行重启运行)

    1)在SpringBoot项目的POM.XML里面引入dev-Tools框架

    2)在Setting里面开启项目自动编译,打开settings,点击Bulid里面的Compiler进行选中

    3)点击选择按钮Build project automatically

    4)点击全局搜索,按两下shift就可以了,然后进行搜索Registry,然后进行双击,输入com

    进行选中

    5)点击debug按钮就可以开启热部署 

    总结:

    1)@RequestMapping:支持任意一种请求类型(get/post),既能修饰方法又是可以修饰类的

    2)@GetMapping:只是支持get方式的请求(不能修饰类)

    3)@PostMapping:只是支持post方式的请求(不能修饰类)

    下面的这两种方法只能修饰方法,是不可以进行修饰类的

    2.获取用户传递过来的参数

    1.传递单个参数,我们在SpingMVC里面可以直接通过方法中的参数来实现传参

    1. @Controller
    2. public class UserController {
    3. @ResponseBody//加上这个注解之后,说明表示当前的方法/类返回的是非界面而不是一个数据
    4. @GetMapping("/Java100")
    5. public String start(String name,String age)
    6. {
    7. return "你好"+name+"我今年"+age+"岁";
    8. }
    9. }
    10. 访问这个地址:http://localhost:8080/Java100?name=123&age=90

    1)我们通过前端传递的querystring参数Key必须要和后端的方法里面的参数保持一致,否则是不能正常地进行获取到参数的 

    2)我们要尽量使用包装类来进行接收前端传递过来的参数,因为是可以接受null值的,如果使用普通类,接收不到参数,就说明程序会出错,会报一个500的错误

    3)上面地址的URL是可以进行调换位置的

    4)当有多个参数的时候,前后端进行参数匹配的时候,是以参数的名称进行匹配的,因此参数的位置是不会影响到后端获取参数的结果;

    但是如果说我们前端传递过来的参数实在是太多了,难道我要在方法里面写成百上千个参数吗,这显然是很不现实的,所以我们要使用对象的方式来进行接收

    2.根据对象来进行接收
     

    1. 1.我们先进行创建一个User类,来进行接收前端的参数
    2. 注意这里面的User类一定要写上Getter和Setter方法:
    3. package com.example.demo;
    4. import lombok.Getter;
    5. import lombok.Setter;
    6. import lombok.ToString;
    7. @ToString
    8. @Setter
    9. @Getter
    10. public class User {
    11. public String username;
    12. public String password;
    13. public int ClassID;
    14. public int UserID;
    15. }
    16. 2.我们再写出UserController里面的代码:
    17. package com.example.demo;
    18. import org.slf4j.Logger;
    19. import org.slf4j.LoggerFactory;
    20. import org.springframework.stereotype.Controller;
    21. import org.springframework.web.bind.annotation.RequestMapping;
    22. import org.springframework.web.bind.annotation.RequestMethod;
    23. import org.springframework.web.bind.annotation.ResponseBody;
    24. @Controller
    25. @RequestMapping("/Java100")
    26. @ResponseBody
    27. public class UserController {
    28. @RequestMapping("/GetUser")
    29. public User start(User user)
    30. {
    31. return user;
    32. }
    33. }
    34. //3我们在浏览器上面输入一个这样的地址:
    35. http://localhost:8080/Java100/GetUser?username=%E6%9D%8E%E4%BD%B3%E4%BC%9F&password=12503487&ClassID=1&UserID=9

    后端参数重命名:在某一些情况下,前端传递过来的参数Key和我们后端接手过来的Key是不一致的,比如说前端传递了一个time给后端,而后端有时又createtime字段来进行接收的,这样就会出现参数接收不到的情况,如果出现了这种情况,我们就可以使用@RequestParam来进行重命名前后端的参数值

    但是如果说进行全部替换的方式有很麻烦,因为这里面的后端参数createtime的参数太多了

    1. @Controller
    2. @ResponseBody
    3. public class UserController {
    4. @RequestMapping("/Java100")
    5. public Object start(@RequestParam("name") String username)//接受前端的对象
    6. {
    7. return "name"+username;
    8. }
    9. 我们可以直接进行访问:http://localhost:8080/Java100?name=128.1

    出现这种情况是很少的:@RequestParam("time"),这个注解的作用就是把前端为time的key赋值给后端的createtime变量

    除此之外,它既可以进行重命名请求,又能保证此参数是必传参数,如果说你使用了这个注解之后@RequestParam注解之后,我们在这里填的参数必须是必填的(required属性默认是true),如果前端没有填这个参数,程序就会出现报错;

    1. @Controller
    2. @ResponseBody
    3. public class UserController {
    4. @RequestMapping("/Java100")
    5. public Object start(@RequestParam(value="name",required = false) String username)//接受前端的对象
    6. {
    7. return "name"+username;
    8. }
    9. }

    @RequestParam中的参数required=false,这就表示当前的参数非必传参数,如果我们不进行设置此属性,那么它的默认值是true,就表示此参数是必传项

    获取到JSON格式的数据:使用RequestBody来进行接收

    前端代码:他是存放在idea中的resources目录底下的static目录下的一个html文件:

    1. 前端代码:
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>Documenttitle>
    8. head>
    9. <body>
    10. <script
    11. src="https://code.jquery.com/jquery-3.6.0.js"
    12. integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk="
    13. crossorigin="anonymous">script>
    14. <script>
    15. function load(){
    16. $.ajax({
    17. method:"POST",
    18. url:"WEB",
    19. contentType:"application/json;charset=utf-8",
    20. data:JSON.stringify({"username": "李佳伟","password":"12503487","ClassID":"1","UserID":"1"}),
    21. success:function(data,status)
    22. {
    23. console.log(data);
    24. console.log(status);
    25. }
    26. });
    27. }
    28. load();
    29. script>
    30. body>
    31. html>

    后端代码:加上@RequestBody后表示要读取一个JSON数据,加到对象前面就行了;

    1. 我们先创建一个User对象,来进行接收前端的参数:
    2. package com.example.demo;
    3. import lombok.Getter;
    4. import lombok.Setter;
    5. import lombok.ToString;
    6. @ToString
    7. @Setter
    8. @Getter
    9. public class User {
    10. public String username;
    11. public String password;
    12. public int ClassID;
    13. public int UserID;
    14. }
    15. 我们在进行创建一个Controller类:
    16. package com.example.demo;
    17. import org.slf4j.Logger;
    18. import org.slf4j.LoggerFactory;
    19. import org.springframework.stereotype.Controller;
    20. import org.springframework.web.bind.annotation.RequestBody;
    21. import org.springframework.web.bind.annotation.RequestMapping;
    22. import org.springframework.web.bind.annotation.RequestMethod;
    23. import org.springframework.web.bind.annotation.ResponseBody;
    24. @Controller
    25. public class UserController {
    26. @RequestMapping("/WEB")
    27. @ResponseBody
    28. public User start(@RequestBody User user)
    29. {
    30. return user;
    31. }
    32. }

    我们在浏览器上面输入:http://127.0.0.1:8080/Text.html

    我们前后端的一个交互过程相当于是:我们先通过一个URL来进行访问html界面,当html界面进行加载的时候,就会给服务器发送一个二次请求,发送一个格式为json格式数据的post请求,然后服务器会进行返回一个json格式的数据;

    获取到特殊URL中的参数:@PathVariable

    1. 我们先创建一个User类:
    2. @ToString
    3. @Setter
    4. @Getter
    5. public class User {
    6. public String username;
    7. public String password;
    8. public int ClassID;
    9. public int UserID;
    10. }
    11. 我们进行访问的地址:http://127.0.0.1:8080/host/李佳伟/12503487
    12. @RequestMapping("/host/{username}/{password}")
    13. @ResponseBody
    14. public Object Start(@PathVariable String username,@PathVariable String password)
    15. {
    16. User user=new User();
    17. user.setUsername(username);
    18. user.setPassword(password);
    19. return user;
    20. }

    上传文件:我们想把文件传递给电脑上面,用的方法是transferTo,里面一共有两个参数,一个是File,一个是Path

    这个方法的主要作用是把当前文件的二进制流,放到一个目录底下

    1. @RequestMapping("/file")
    2. @ResponseBody
    3. public String upload(@RequestPart("myfile")//这个Key值可以任意设置 MultipartFile file) throws IOException {
    4. //保存文件
    5. file.transferTo(new File(""d:/loggs/test.jpg""));
    6. return "上传成功";
    7. }

    1)我们直接可以进行点击Body中的form-data,Key值选择myfile,右键选择file就可以进行上传文件了

    2)我们过来的文件一个是给开发环境用的,一个是给生产环境用的

    3)我们这里面的@RequestMapping里面的参数表示路由地址,表示的是url中的地址,但是@RequestPart里面的参数表示的是form-data中的Key值

    下面是Fidder抓包结果: 

     

    1)我希望创建两个配置文件,一个叫做application-dev1.properties,里面进行存放开发环境的配置文件,我峨嵋你在创建一个配置文件叫做application-dev2.properties里面存放生产环境的配置文件,我们在进行创建一个配置文件想我们再进行读取配置文件的时候,我们的系统默认是会先从自带的配置文件里面读,就是从application.properties里面读,所以我们要从系统配置文件里面设置;

    2)多环境配置文件:不同环境配置一个文件,我们只需要进行修改application.properties中的配置文件即可

    3)我们进行动态生成文件名的时候,一共是有两种方法的,第一个就是根据时间戳,第二种方法就是根据UUID,但时间戳的方式是绝对不可以的,因为不同的用户可能会在同一时间(精确到毫秒)里面上传相同的文件,但是不同的时间内生成的时间戳的确是不同的;

    1. 1)application.properties里面的代码:spring.profiles.active=dev1
    2. 2)application-dev1.properties里面的代码:FilePath.url=D://SB1//
    3. 3)我们在UserController里面的代码:
    4. import org.slf4j.Logger;
    5. import org.slf4j.LoggerFactory;
    6. import org.springframework.beans.factory.annotation.Value;
    7. import org.springframework.stereotype.Controller;
    8. import org.springframework.web.bind.annotation.*;
    9. import org.springframework.web.multipart.MultipartFile;
    10. import javax.annotation.PostConstruct;
    11. import java.io.File;
    12. import java.io.IOException;
    13. import java.util.UUID;
    14. @Controller
    15. public class UserController {
    16. @Value("${FilePath.url}")
    17. private String url;
    18. @PostConstruct
    19. public void start()
    20. {
    21. System.out.print(url);
    22. }
    23. @RequestMapping("/file")
    24. @ResponseBody
    25. public String Upload(@RequestPart("myfile") MultipartFile file) throws IOException {
    26. //1上传文件路径,从配置文件中读取,小心文件名重复而造成覆盖
    27. String BasePath=url;
    28. //2生成动态的文件名,没传过来一个文件都要生成动态的文件名,xx.jpg
    29. String filename= UUID.randomUUID()+(file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")));
    30. System.out.println(filename);
    31. file.transferTo(new File(BasePath+filename));
    32. return "上传成功";
    33. }
    34. }

     获取到Cookie和Session和Header头(这些都是系统自己产生的,不是用户进行自定义的)

    所有的SpringMVC里面,所有映射方法中,都会内置两个参数,HttpServletRequest和HttpServletResponse这两个参数

    1. @Controller
    2. class UserController{
    3. @RequestMapping("/Java")
    4. @ResponseBody
    5. public Cookie[] GetCookies(HttpServletRequest req,HttpServletRequest resp)
    6. {
    7. Cookie[] arr1= req.getCookies();
    8. System.out.println(Arrays.toString(arr1));
    9. return arr1;
    10. }
    11. }

    或者使用这种方法也是可以获取到Cookie字段的:

    1. @Controller
    2. class UserController{
    3. @RequestMapping("/Java")
    4. @ResponseBody
    5. public String GetHeader(@RequestHeader("Cookie") String Cookie)
    6. {
    7. return Cookie;
    8. }
    9. }

    获取Header头:

    1. @Controller
    2. class UserController{
    3. @RequestMapping("/Java")
    4. @ResponseBody
    5. public String GetHeader(@RequestHeader("Host") String userAgent)
    6. {
    7. return userAgent;
    8. }
    9. }
    1. package com.example.demo;
    2. import org.slf4j.Logger;
    3. import org.slf4j.LoggerFactory;
    4. import org.springframework.beans.factory.annotation.Value;
    5. import org.springframework.stereotype.Controller;
    6. import org.springframework.web.bind.annotation.*;
    7. import org.springframework.web.multipart.MultipartFile;
    8. import javax.annotation.PostConstruct;
    9. import javax.servlet.http.Cookie;
    10. import javax.servlet.http.HttpServlet;
    11. import javax.servlet.http.HttpServletRequest;
    12. import javax.servlet.http.HttpServletResponse;
    13. import java.io.File;
    14. import java.io.IOException;
    15. import java.util.UUID;
    16. @Controller
    17. public class UserController {
    18. @RequestMapping("/Java100")
    19. @ResponseBody
    20. public void run(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    21. resp.setContentType("text/html;charset=utf-8");
    22. Cookie[] cookies=req.getCookies();
    23. String username=req.getParameter("username");
    24. String password=req.getParameter("password");
    25. String data=req.getHeader("Host");
    26. String accept=req.getHeader("Accept");
    27. resp.getWriter().write("你好呀"+username+password+data+accept);
    28. }
    29. }

    1. @Controller
    2. public class UserController {
    3. @RequestMapping("/Java100")
    4. @ResponseBody
    5. public String run(@RequestHeader("User-Agent") String UserAgent,@RequestHeader("Host") String host) throws IOException {
    6. return UserAgent+host;
    7. }
    8. }

    设计登陆界面:

    1. @Controller
    2. class UserController{
    3. @RequestMapping("/Java")
    4. @ResponseBody
    5. public String login(HttpServletRequest req, String username, String password, HttpServletResponse resp) throws IOException {
    6. if(password==null||password.equals("")||username==""||username.equals(""))
    7. {
    8. return "用户名或者密码错误";
    9. }
    10. if(!username.equals("李佳伟")||!password.equals("12503487"))
    11. {
    12. return "用户名错误或者密码错误";
    13. }
    14. HttpSession httpSession=req.getSession(true);
    15. httpSession.setAttribute("username",username);
    16. resp.sendRedirect("/JS");
    17. return "";
    18. }
    19. @RequestMapping("/JS")
    20. @ResponseBody
    21. public String GetSession(HttpServletRequest req)
    22. {
    23. HttpSession session=req.getSession();
    24. if(session==null||session.equals(""))
    25. {
    26. return "当前用户没有进行登录";
    27. }
    28. String username=(String)session.getAttribute("username");
    29. if(username==null||username.equals(""))
    30. {
    31. return "当前用户没有进行登录";
    32. }
    33. return username+"当前用户已经登陆成功";
    34. }
    35. }

    下面写一种更加简单的获取Session的方法:

    1. @RequestMapping("/JS")
    2. @ResponseBody
    3. public String GetSession(@SessionAttribute(value="username",required = false) String username)
    4. {
    5. return username;
    6. }

     小结:SpringMVC进行获取用户的请求信息:

    1)获取到单个参数:我们在方法里面进行获取到对应的参数就可以实现(方法名的参数和前端的参数要一致)

    2)获取对象:在方法里面直接写对象就可以进行实现

    3)获取到JSON对象:@RequestBody加到方法的参数的前面

    4)获取文件:@RequestPart

    5)获取用户的Cookie/Session/Header:@CookieValue/@SessionSttribute/@RequestHeader

    返回结果给前端:

    1)向浏览器返回一个HTML界面 

    1. @RequestMapping("/CSS")
    2. @ResponseBody
    3. public String GetHTML(String name)
    4. {
    5. return "

      你好"+name+"

      "
      ;
    6. }
    7. 请求参数的数据类型Contnt-Type:text/html;charset=utf-8

    2.给浏览器返回一个JSON格式的数据:

    1. @RequestMapping("/JS")
    2. @ResponseBody
    3. public Object GetJson(String name)
    4. {
    5. HashMap<String,Object> map=new HashMap<>();
    6. map.put("name",name);
    7. map.put("currentTime", LocalDateTime.now());
    8. return map;
    9. }
    10. 浏览器上面输入:localhost:8080/JS?name=李佳伟
    11. {"currentTime":"2022-07-17T12:30:34.76","name":"李佳伟"}
    1. package com.example.demo;
    2. import com.fasterxml.jackson.databind.ObjectMapper;
    3. import org.slf4j.Logger;
    4. import org.slf4j.LoggerFactory;
    5. import org.springframework.beans.factory.annotation.Value;
    6. import org.springframework.stereotype.Controller;
    7. import org.springframework.web.bind.annotation.*;
    8. import org.springframework.web.multipart.MultipartFile;
    9. import javax.annotation.PostConstruct;
    10. import javax.servlet.http.Cookie;
    11. import javax.servlet.http.HttpServlet;
    12. import javax.servlet.http.HttpServletRequest;
    13. import javax.servlet.http.HttpServletResponse;
    14. import java.io.DataOutput;
    15. import java.io.File;
    16. import java.io.IOException;
    17. import java.util.UUID;
    18. @Controller
    19. public class UserController {
    20. @RequestMapping("/Java100")
    21. @ResponseBody
    22. public void run(String username,String password,Integer ClassID,Integer UserID,HttpServletResponse resp) throws IOException {
    23. ObjectMapper objectMapper=new ObjectMapper();
    24. User user=new User();
    25. user.setUserID(UserID);
    26. user.setClassID(ClassID);
    27. user.setUsername(username);
    28. user.setPassword(password);
    29. resp.setContentType("application/json;charset=utf-8");
    30. String html= objectMapper.writeValueAsString(user);
    31. resp.getWriter().write(html);
    32. }
    33. }

     

    实现一个简单的计数器:

    1. 前端Text.html: <form action="/sum" method="GET">
    2. <span>请输入数字1span><input type="text" name="s1">
    3. <span>请输入数字2span><input type="text" name="s2">
    4. <input type="submit" value="提交">
    5. form>
    6. @Controller
    7. class UserController{
    8. @RequestMapping("/sum")
    9. @ResponseBody
    10. public String sum(Integer s1,Integer s2)
    11. {
    12. return "<h1>结果最终为"+(s1+s2)+"h1><br><a href='/Text.html'>点击回到上个界面a>";
    13. }
    14. }

    上面我们使用form表单给服务器发送一个GET请求的时候,我们使用Fidder抓包的结果是:自定义的参数放到了querystring里面

    1. GET http://localhost:8080/add?num1=12&num2=23 HTTP/1.1
    2. Host: localhost:8080
    3. Connection: keep-alive
    4. sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="8"
    5. sec-ch-ua-mobile: ?0
    6. Upgrade-Insecure-Requests: 1
    7. User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 SLBrowser/8.0.0.7271 SLBChan/103
    8. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
    9. Sec-Fetch-Site: same-origin
    10. Sec-Fetch-Mode: navigate
    11. Sec-Fetch-User: ?1
    12. Sec-Fetch-Dest: document
    13. Referer: http://localhost:8080/blog1.html
    14. Accept-Encoding: gzip, deflate, br
    15. Accept-Language: zh-CN,zh;q=0.9

    当我们使用form表单发送一个POST请求的时候:

    1. "/add" method="POST">
    2. <input type="text" name="num1">
    3. <input type="text" name="num2">
    4. <input type="submit" value="提交">

    下面是给服务器发送的请求:(通过Fidder抓包)

    1. POST http://localhost:8080/add HTTP/1.1
    2. Host: localhost:8080
    3. Connection: keep-alive
    4. Content-Length: 13
    5. Cache-Control: max-age=0
    6. sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="8"
    7. sec-ch-ua-mobile: ?0
    8. Upgrade-Insecure-Requests: 1
    9. Origin: http://localhost:8080
    10. Content-Type: application/x-www-form-urlencoded
    11. User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 SLBrowser/8.0.0.7271 SLBChan/103
    12. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
    13. Sec-Fetch-Site: same-origin
    14. Sec-Fetch-Mode: navigate
    15. Sec-Fetch-User: ?1
    16. Sec-Fetch-Dest: document
    17. Referer: http://localhost:8080/blog1.html
    18. Accept-Encoding: gzip, deflate, br
    19. Accept-Language: zh-CN,zh;q=0.9
    20. num1=2&num2=3

    现在我们进行修改一下博客系统的前端页面:

    1)小技巧:ctrl+a进行全选,然后ctrl+c进行复制,然后在进行点击SpringBoot项目里面的resource目录下的static目录,在按下crtl+v进行粘贴

    2)jquery.getJSON("请求的地址url",{请求的参数},function(data,status)请求成功之后的回调函数)

    前端代码:通过ajax发送Http请求:

    1. let button=document.querySelector("#submit");
    2. button.onclick=function()
    3. {
    4. //1先拿到用户名和密码控件
    5. var username=jQuery("#input1");
    6. var password=jQuery("#input2");
    7. console.log(username.val());
    8. console.log(password.val());
    9. //jQuery里面填写的是id属性,我们可以通过username.val可以得到输入框里面的内容
    10. // 2进行非空校验
    11. if(!jQuery.trim(username.val()==""))
    12. {
    13. alert("请先输入用户名");
    14. username.focus();//光标设置到用户名输入框
    15. return;
    16. }
    17. if(!jQuery.trim(username.val()==""))
    18. {
    19. alert("请先输入密码");
    20. username.focus();
    21. return;
    22. }
    23. // 3发送ajax请求和后端进行交互
    24. jQuery.getJSON("/login",
    25. {"username":jQuery.trim(username.val()),
    26. "password":jQuery.trim(password.val()),//trim方法就是去掉里面的空格
    27. },function(data){
    28. if(data!=null&&data.succ==200)
    29. {
    30. console.log("后端接口访问成功");
    31. if(data.state==1)
    32. {
    33. alert("登陆成功");
    34. }else{
    35. alert(data.message);
    36. }
    37. }else{
    38. console.log("后端接口访问失败"+data.succ);
    39. }
    40. });
    41. //第一个参数表示请求的地址,第二个参数表示请求的参数,第三个参数表示服务器端返回的一个回调函数
    42. }

     后端代码:

    1. @RequestMapping("/login")
    2. @ResponseBody
    3. public Object login(String username,String password)
    4. {
    5. HashMap<String,Object> map=new HashMap<>();
    6. map.put("succ",200);//定义后端响应返回状态码
    7. int state=-1;//身份验证错误状态码
    8. String message="";
    9. if(username!=null&&password!=null&&username.equals("李佳伟")&&password.equals("12503487"))
    10. {
    11. state=1;
    12. }else{
    13. //登陆失败
    14. message="用户名或者密码错误";
    15. }
    16. map.put("state",state);
    17. map.put("message",message);
    18. return map;
    19. }

    这里面要注意一个问题:

    在Spring里面,通过resp.setContentType进行设置是不会进行生效的:

    1. 前端代码:
    2. let button=document.querySelector("#submit");
    3. let username=document.querySelector("#input1");
    4. let password=document.querySelector("#input2");
    5. button.onclick=function(){
    6. // console.log(username.value);
    7. // console.log(password.value);
    8. if(username.value==""||password.value=="")
    9. {
    10. alert("当前的用户名或者密码是空");
    11. return;
    12. }
    13. $.ajax({
    14. type:"GET",
    15. url:"login?"+"username="+username.value+"&password="+password.value,
    16. success:function(data,status)
    17. {
    18. console.log(data);
    19. console.log(status);
    20. }
    21. });
    22. }
    23. 后端代码:
    24. @Controller
    25. public class UserController {
    26. @RequestMapping(value="/login",produces = "text/html;charset=utf-8")
    27. @ResponseBody
    28. public String start(String username, String password, HttpServletResponse resp) throws IOException {
    29. return "

      "+username+""+password+"

      "
      ;
    30. }
    31. @RequestMapping("/cat")
    32. @ResponseBody
    33. public String start(String username,String password)
    34. {
    35. return username+password;
    36. }
    37. }

    SpringMVC中Controller处理response.setContentType() - 知乎

     请求转发和请求重定向(不能加@ResponseBody)

    他们之间有什么区别?

    1)请求转发:是服务器帮忙进行转的,是服务器帮客户端进行请求转发并将结果返回给客户端,电脑搜索栏里面的URL地址是不会发生改变的(浏览器啥也不用干)

    2)请求重定向:让浏览器重新请求另一个地址,服务器端将请求重新定义到要访问的地址上面,URL地址会发生改变(浏览器自己要干活)(和直接访问浏览器地址是一样的)

    3)使用请求转发有可能外部资源时会丢失的,是会访问不到的,但是请求重定向是直接重定向到URL地址了,所以请求重定向和直接访问目标地址的效果是一模一样的,所以是不会存在外部资源丢失的情况

    如果说请求转发的资源和转发的页面不在同一个目录下,就会造成外部资源不可以进行访问

    4)Spring是整个Spring框架体系最老的技术了,是整个Spring体系的一个基础,在18年,19年已经不适用了,他是一个IOC框架;用Spring Boot是为了快速开发Spring的一个项目,并不是一个新的技术,它的存在是为了更快更方便的创建Spring,Spring是核心,SpringBoot是辅助核心能够更方便的开发的;

    Spring MVC使Spring里面的一个模块,spring是有很多模块的,但是Spring MVC只是里面的一个外部模块,当我们使用HTTP,在浏览器输入地址之后,使用POSTman之后,可以直接映射到我们的程序里面;

    1. @Controller
    2. @RequestMapping("/User")
    3. public class TextController {
    4. @RequestMapping("/Java")
    5. public String forward(HttpServletResponse resp) throws IOException {
    6. // resp.sendRedirect("blog3.html");
    7. return "forward:/blog3.html";
    8. }
    9. @RequestMapping("CC")
    10. public String preforward()
    11. {
    12. return "redirect:/blog3.html";
    13. }
    14. }
    15. 当我们去进行访问:127.0.0.1:8080/User/Java就会进行请求转发,况且是访问不到外部资源的
    16. 但是说我们把上面的User去掉,访问地址127.0.0.1:8080/Java就可以进行访问外部资源了

    1)补充一个组合注解:@RestController=@Controller+@ResponseBody

    2)@ResponseBody返回的值如果是字符串会转换成text/html,如果返回的是对象那么会转换成application/json返回给前端

    3)@ResponseBody可以用来修饰方法或者用来修饰类,修饰类表示类中的所有方法都会返回html或者json,而不是视图

    4)Lombok项目是一个java库,它可以自动插入到编辑器和构建工具中,增强java的性能。不要再写另一个getter或equals方法,只要有一个注释,你的类就有一个功能齐全的构建器,自动记录变量等等。

  • 相关阅读:
    【自定义字符串排序】
    【Vue2】VantUI项目入门教程
    三个练手的软件测试实战项目(附全套视频跟源码)偷偷卷死他们
    ShineBlink超低代码IoT芯片App远程控制继电器接入机智云
    第八章《Java高级语法》第6节:匿名类
    如何基于OpenCV和Sklearn算法库开展机器学习算法研究
    知识分享系统
    22 河南省赛 - H.旋转水管(暴搜)
    【考研数学】高等数学第五模块 —— 级数(2,幂级数)
    类的比较大小(Comparable -> compareTo(类自己实现接口),Comparator -> compare(新建一个类作为比较器))
  • 原文地址:https://blog.csdn.net/weixin_61518137/article/details/125815152