• 深入了解springmvc响应数据


    目录

    一、前后端分离开发与混合开发

    1.1 混合开发模式

    1.2  前后端分离模式【重点】

    二、页面跳转控制

    2.1 通过JSP实现页面跳转

    2.2 转发与重定向

    三、返回JSON数据

    3.1 导包与配置

     3.2 使用@ResponseBody

    四、返回静态资源

    4.1 为什么无法直接查询静态资源

    4.2 配置实现静态资源查找


    一、前后端分离开发与混合开发

    一个项目的开发可以分为两种开发模式,分别是前后端分离和混合开发。以下介绍两种开发模式的特点。

    1.1 混合开发模式

    指将前端和后端的代码集成在同一个项目中,共享相同的技术栈和框架。这种模式在小型项目中比较常见,可以减少学习成本和部署难度。但是,在大型项目中,这种模式会导致代码耦合性很高,维护和升级难度较大。

    对于混合开发,我们就需要使用动态页面技术,动态展示Java的共享域数据!!

    1.2  前后端分离模式【重点】

    指将前端的界面和后端的业务逻辑通过接口分离开发的一种方式。开发人员使用不同的技术栈和框架,前端开发人员主要负责页面的呈现和用户交互,后端开发人员主要负责业务逻辑和数据存储。前后端通信通过 API 接口完成,数据格式一般使用 JSON 或 XML。前后端分离模式可以提高开发效率,同时也有助于代码重用和维护。


    二、页面跳转控制

    这里页面跳转都是基于jsp技术。即混合开发模式下的应用。

    2.1 通过JSP实现页面跳转

    1.使用jsp技术,需要导入以下依赖

    1. <dependency>
    2. <groupId>jakarta.servlet.jsp.jstlgroupId>
    3. <artifactId>jakarta.servlet.jsp.jstl-apiartifactId>
    4. <version>3.0.0version>
    5. dependency>

    2.jsp页面创建

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

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

    1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    2. <html>
    3. <head>
    4. <title>Titletitle>
    5. head>
    6. <body>
    7. ${data}
    8. body>
    9. html>

    1.为什么/WEB-INF/能够实现避免外部访问

    这种限制的实现是由 Java Web 容器(比如 Tomcat、Jetty 等)来完成的,它们会拦截对 /WEB-INF/ 目录及其子目录的请求,阻止这些内容被直接访问。这样做的目的是为了保护应用程序的安全性和完整性,避免敏感信息和代码被非授权用户获取。

    3. 快速响应模版页面

    配置对应的mvc类

    1. @EnableWebMvc //json数据处理,必须使用此注解,因为他会加入json处理器
    2. @Configuration
    3. @ComponentScan(basePackages = "com.atguigu.controller") //TODO: 进行controller扫描
    4. //WebMvcConfigurer springMvc进行组件配置的规范,配置组件,提供各种方法! 前期可以实现
    5. public class SpringMvcConfig implements WebMvcConfigurer {
    6. //配置jsp对应的视图解析器
    7. @Override
    8. public void configureViewResolvers(ViewResolverRegistry registry) {
    9. //快速配置jsp模板语言对应的前缀和后缀
    10. registry.jsp("/WEB-INF/views/",".jsp");
    11. }
    12. }

    handler返回视图 

    1. /**
    2. * 跳转到提交文件页面 /save/jump
    3. *
    4. * 如果要返回jsp页面!
    5. * 1.方法返回值改成字符串类型
    6. * 2.返回逻辑视图名即可
    7. *
    8. * + 逻辑视图名 +
    9. *
    10. */
    11. @GetMapping("jump")
    12. public String jumpJsp(HttpServletRequest request){
    13. //设置共享域
    14. request.setAttribute( s: "data", o: "hello jsp!!!");
    15. model.addAttribute("data","]spController.index");
    16. return "index";
    17. }

    运行后结果:

    1. 由于在配置中加上了前缀和后缀,所以return的值只需要对应jsp页面的名称即可

    2. 混合开发模式下,前后端的数据交流是通过共享域进行的。


    2.2 转发与重定向

    在springMvc中实现转发和重定向是通过关键词Forward和Redirect来实现的。

    1. @RequestMapping("/redirect-demo")
    2. public String redirectDemo() {
    3. // 重定向到 /demo 路径
    4. return "redirect:/demo";
    5. }
    6. @RequestMapping("/forward-demo")
    7. public String forwardDemo() {
    8. // 转发到 /demo 路径
    9. return "forward:/demo";
    10. }
    11. //注意: 转发和重定向到项目下资源路径都是相同,都不需要添加项目根路径!填写项目下路径即可!

    注意转发是只能访问项目下的资源,而重定向是可以重定向到其它资源,比如其它不属于本项目的网站。

     可能会问,转发下既然访问项目下的资源,而tomcat在部署的时候设置了根路径,是否需要把根路径也一并导入进去?答案是不需要

    springmvc对转发做了优化,即自动帮你加上了对应的根路径,而如果再转发时候写上根路径,就会导致重复的根路径的填写。


    三、返回JSON数据

    由于使用JSON返回数据使用到@ResponseBody,就不再使用页面跳转中的跳转(forward)和重定向(redirect)

    3.1 导包与配置

    使用JSON数据需要导入以下包

    1. <dependency>
    2. <groupId>com.fasterxml.jackson.coregroupId>
    3. <artifactId>jackson-databindartifactId>
    4. <version>2.15.0version>
    5. dependency>

    写配置类

    1. //TODO: SpringMVC对应组件的配置类 [声明SpringMVC需要的组件信息]
    2. //TODO: 导入handlerMapping和handlerAdapter的三种方式
    3. //1.自动导入handlerMapping和handlerAdapter [推荐]
    4. //2.可以不添加,springmvc会检查是否配置handlerMapping和handlerAdapter,没有配置默认加载
    5. //3.使用@Bean方式配置handlerMapper和handlerAdapter
    6. @EnableWebMvc //json数据处理,必须使用此注解,因为他会加入json处理器
    7. @Configuration
    8. @ComponentScan(basePackages = "com.atguigu.controller") //TODO: 进行controller扫描
    9. //WebMvcConfigurer springMvc进行组件配置的规范,配置组件,提供各种方法! 前期可以实现
    10. public class SpringMvcConfig implements WebMvcConfigurer {
    11. }

     3.2 使用@ResponseBody

    如果使用JSON格式数据与前端进行交互,那么也就意味着抛弃了混合开发的模式,所以需要用到@ResponseBody注解,这个注解让解析器不会去找视图层,而是直接返回数据。

    对于handler方法而言,使用注解只需要在方法上进行定义。

    1. @GetMapping("/accounts/{id}")
    2. @ResponseBody
    3. public Object handle() {
    4. // ...
    5. return obj;
    6. }
    1. @RequestMapping(value = "/user/detail", method = RequestMethod.POST)
    2. @ResponseBody
    3. public User getUser(@RequestBody User userParam) {
    4. System.out.println("userParam = " + userParam);
    5. User user = new User();
    6. user.setAge(18);
    7. user.setName("John");
    8. //TODO:返回的对象,会使用jackson的序列化工具,转成json返回给前端!
    9. return user;
    10. }

    通过POSTMAN工具访问后结果如下:

    如果每一个方法都需要进行返回JSON格式数据,那么是否可以简化一下呢?打开注解源码

    可以看到该注解是可以作用在类上的,也就意味,只需要在 类上直接加上注解即可

    1. //TODO:只需要在类上加上@ResponseBody即可表示所有handler方法都是直接返回数据
    2. @Controller
    3. @ResponseBody
    4. @RequestMapping("appointment")
    5. public class AppointmentController {
    6. @RequestMapping("Hello/{name}/{sex}")
    7. public String hello(@PathVariable String name, @PathVariable String sex) {
    8. System.out.println("name = " + name + ", sex = " + sex);
    9. return "name = " + name + ", sex = " + sex;
    10. }
    11. @RequestMapping("/JsonTest")
    12. // TODO:通过设置响应体注解@RequestBody实现接收json数据
    13. public String Json(@RequestBody JSONObject jsonObject){
    14. System.out.println("成功接受到JSON数据");
    15. return "返回接收到的JSON数据为:"+jsonObject.toJSONString();
    16. }
    17. @RequestMapping("/save")
    18. public String CookieTest(HttpServletResponse servletResponse){
    19. Cookie cookie = new Cookie("CookieTestName","AlphaMilk");
    20. servletResponse.addCookie(cookie);
    21. System.out.println("成功设置好cookie");
    22. return "设置cookie成功";
    23. }
    24. @RequestMapping("/GetCookie")
    25. public String GetCookie(@CookieValue("CookieTestName") String value){
    26. return "获取到的Cookie值为"+value;
    27. }
    28. @RequestMapping("/Header")
    29. public String GetHead(@RequestHeader("HOST") String value){
    30. return "获取到的HOST值为"+value;
    31. }
    32. }

    那么既然又需要将类加载在ioc容器中,又要声明为@ResponseBody。是否能够再进一步简化注解呢?答案是有的。

     注解:@ResController = @Controller + @ResponseBody

    通过观看源码可以看到


    四、返回静态资源

    4.1 为什么无法直接查询静态资源

    如果在项目下,在WEB-INF外有一个图片,想要通过访问地址去查找。

    这里发现通过地址无法进行查找对应的资源,这是为什么呢?

    其实是因为在访问时候DispactherServlet老板 会向HandlerMapping秘书询问是否项目下存在这个资源。而HandlerMapping只能查找Handler方法。即那些RequestMapping("路径")的这些对应的方法。而没办法找静态的资源。所以会返回给DIspatcherServlet一个404.


    4.2 配置实现静态资源查找

    那么应该如何设置才能让DispatcherServlet能够正常获取到静态资源呢? 那就需要用到配置类中继承方法覆写。

     那么这个方法的原理是什么呢?为什么这个方法能够访问到静态资源。在找寻到对应源码后如下:

    可以看到,其实原理就是用到前面页面跳转的转发功能,而转发可以访问到项目下的资源。

    在配置访问静态资源后之后,这时候访问一个资源的流程变成了

    DispatcherServlet首先会询问HandlerMapping是否有对应的资源,如果没有就会去访问DefaultServletHandler是否有对应的路径,如果都没有就会显示404.


  • 相关阅读:
    基础测试干了4年,自学了自动化(太片面),突然接到被裁员消息
    会议OA项目(六)--- (待开会议、历史会议、所有会议)
    代码随想录算法训练营总结篇
    java动态代理技术
    苹果上架Guideline 4.3 - Design
    CentOS安装IRIS
    《向量数据库指南》——向量数据库会是 AI 的“iPhone 时刻”吗?
    app简单控件了解——常用布局——相对布局RelativeLayout
    Java项目:SSM网上家具商城网站系统平台
    ZKP6.2 Discrete-log-based Polynomial Commitments (KZG10)
  • 原文地址:https://blog.csdn.net/dogxixi/article/details/134371616