Spring MVC 逻辑视图(JSP、Thymeleaf、FreeMarker)与非逻辑视图(JSON、Excel、PDF、XML)详解及示例

news2025/4/18 7:33:01

Spring MVC 逻辑视图与非逻辑视图详解及示例


一、逻辑视图与非逻辑视图的定义
类型定义
逻辑视图通过视图解析器(ViewResolver)将逻辑名称(如 success)映射到具体视图实现。
非逻辑视图直接返回具体视图对象(如 JsonView),或通过注解/方法直接生成响应,无需解析器。

二、逻辑视图与非逻辑视图的接口类型
类型接口示例
逻辑视图JSP、Thymeleaf、FreeMarker(模板引擎生成HTML)
非逻辑视图JSON(MappingJackson2JsonView)、Excel(ExcelView)、PDF(PdfView)、XML等

三、逻辑视图与非逻辑视图的对比
维度逻辑视图非逻辑视图
视图解析需要配置视图解析器(如 ThymeleafViewResolver无需解析器,直接返回视图对象或通过注解(如 @ResponseBody
响应格式HTML(模板引擎渲染)JSON、Excel、PDF、XML 等特定格式
解耦性控制器与视图解耦,通过名称间接关联控制器直接绑定视图实现,耦合度较高
配置复杂度需配置解析器和模板引擎简单(如直接使用注解或自定义View类)
典型场景前端页面渲染(如网页跳转)API返回数据、文件下载、特殊格式输出

四、代码示例

1. 逻辑视图示例

(1)JSP 示例

// 配置JSP视图解析器(在Spring配置类中)
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/"); // JSP文件存放路径
        resolver.setSuffix(".jsp");            // 文件后缀
        return resolver;
    }
}

// 控制器方法
@Controller
public class UserController {
    @GetMapping("/user/jsp")
    public String showUserJsp(Model model) {
        model.addAttribute("userName", "John Doe");
        return "userProfile"; // 返回逻辑视图名,对应userProfile.jsp
    }
}

// userProfile.jsp 文件(存放于 /WEB-INF/views/)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>User Profile</title></head>
<body>
    <h1>User Name: ${userName}</h1>
</body>
</html>

(2)Thymeleaf 示例

// 配置Thymeleaf视图解析器(在Spring配置类中)
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Bean
    public SpringTemplateEngine templateEngine() {
        SpringTemplateEngine engine = new SpringTemplateEngine();
        engine.setTemplateResolver(templateResolver());
        return engine;
    }

    @Bean
    public SpringResourceTemplateResolver templateResolver() {
        SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
        resolver.setPrefix("classpath:/templates/");
        resolver.setSuffix(".html");
        return resolver;
    }

    @Bean
    public ThymeleafViewResolver viewResolver() {
        ThymeleafViewResolver resolver = new ThymeleafViewResolver();
        resolver.setTemplateEngine(templateEngine());
        return resolver;
    }
}

// 控制器方法
@Controller
public class UserController {
    @GetMapping("/user/thymeleaf")
    public String showUserThymeleaf(Model model) {
        model.addAttribute("user", new User("John", "Doe"));
        return "userProfile"; // 对应userProfile.html模板
    }
}

// userProfile.html(存放于 templates/)
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><title>User Profile</title></head>
<body>
    <h1 th:text="${user.firstName} + ' ' + ${user.lastName}"></h1>
</body>
</html>

2. 非逻辑视图示例

(1)JSON 示例

// 直接返回JSON(使用@ResponseBody注解)
@RestController
public class UserController {
    @GetMapping("/user/json")
    public User getUserJson() {
        return new User("John", "Doe"); // 自动序列化为JSON
    }
}

// 或通过ModelAndView返回JSON视图
@Controller
public class UserController {
    @GetMapping("/user/json-view")
    public ModelAndView getUserJsonView() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setView(new MappingJackson2JsonView());
        modelAndView.addObject("user", new User("John", "Doe"));
        return modelAndView;
    }
}

(2)Excel 示例(使用Apache POI)

// 自定义Excel视图类
public class ExcelView extends AbstractView {
    @Override
    protected void renderMergedOutputModel(
        Map<String, Object> model,
        HttpServletRequest request,
        HttpServletResponse response
    ) throws Exception {
        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-Disposition", "attachment; filename=users.xls");
        
        HSSFWorkbook workbook = new HSSFWorkbook();
        HSSFSheet sheet = workbook.createSheet("Users");
        
        HSSFRow headerRow = sheet.createRow(0);
        headerRow.createCell(0).setCellValue("First Name");
        headerRow.createCell(1).setCellValue("Last Name");
        
        List<User> users = (List<User>) model.get("users");
        for (int i = 0; i < users.size(); i++) {
            HSSFRow row = sheet.createRow(i + 1);
            row.createCell(0).setCellValue(users.get(i).getFirstName());
            row.createCell(1).setCellValue(users.get(i).getLastName());
        }
        
        workbook.write(response.getOutputStream());
        workbook.close();
    }
}

// 控制器方法
@Controller
public class ExcelController {
    @GetMapping("/generate/excel")
    public ModelAndView generateExcel() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setView(new ExcelView());
        modelAndView.addObject("users", Arrays.asList(
            new User("John", "Doe"),
            new User("Jane", "Smith")
        ));
        return modelAndView;
    }
}

(3)PDF 示例(使用iText)

// 自定义PDF视图类
public class PdfView extends AbstractView {
    @Override
    protected void renderMergedOutputModel(
        Map<String, Object> model,
        HttpServletRequest request,
        HttpServletResponse response
    ) throws Exception {
        response.setContentType("application/pdf");
        response.setHeader("Content-Disposition", "inline; filename=document.pdf");
        
        Document document = new Document();
        PdfWriter.getInstance(document, response.getOutputStream());
        document.open();
        document.add(new Paragraph("Hello PDF!"));
        document.close();
    }
}

// 控制器方法
@Controller
public class PdfController {
    @GetMapping("/generate/pdf")
    public ModelAndView generatePdf() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setView(new PdfView());
        return modelAndView;
    }
}

五、总结表格
类型接口示例响应格式是否需要解析器配置方式典型场景
逻辑视图JSP、ThymeleafHTML配置ViewResolver前端页面渲染
非逻辑视图JSON、Excel、PDFJSON、XLS、PDF直接实例化View或使用注解API响应、文件下载、特殊格式

关键区别
  • 逻辑视图:依赖模板引擎生成HTML,需配置视图解析器,适合前后端分离场景。
  • 非逻辑视图:直接返回数据或文件,无需解析器,适合API、文件导出等场景,配置更灵活。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2331392.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

K8s 老鸟的配置管理避雷手册

Yining, China 引言 对于这种案例&#xff0c;你们的处理思路是怎么样的呢&#xff0c;是否真正的处理过&#xff0c;如果遇到&#xff0c;你们应该怎么处理。 最后有相关的学习群&#xff0c;有兴趣可以加入。 开始 一、血泪教训&#xff1a;环境变量引发的真实灾难 1.1 …

3-Visual Studio 2022打包NET开发项目为安装包

引言 本文将上一期博文>>>门店管理系统开发<<<开发的项目打包为Windows安装包 一&#xff0c;安装扩展 安装此扩展&#xff1a;installer Projects 二&#xff0c;创建安装程序项目 创建项目 右键解决方案-添加-新建项目 选择setup Project项目 填写项目名…

国内外网络安全政策动态(2025年3月)

▶︎ 1.《关于进一步加强智能网联汽车产品准入、召回及软件在线升级管理的通知》发布 3月1日&#xff0c;工业和信息化部、市场监管总局联合发布《关于进一步加强智能网联汽车产品准入、召回及软件在线升级管理的通知》&#xff08;以下简称《通知》&#xff09;。 该通知旨在…

已知Word内容格式固定,通过宏实现Word转Excel

文章目录 需求描述一、宏是什么&#xff1f;二、使用步骤1.启用开发工具2.VBA基础知识3.单个Word文件转为Excel4.批量将Word文件转为Excel文件 总结 需求描述 现在有多个Word文档&#xff0c;Word文档格式固定&#xff0c;假如Word内容分为单选题和多选题&#xff0c;每个题目…

SpringDoc【使用详解】

SpringDoc使用详解 一、何为SpringDoc二、概念解释三、SpringDoc使用2.1简单集成2.2 配置SpringDoc2.2.1 yml方式配置2.2.2配置文档信息 2.3配置文档分组2.4使用注解2.4.1 Tag2.4.2 Operation2.4.3 Schema2.4.4 NotNull2.4.5 Parameter2.4.6 Parameters2.4.7 ApiResponses 和Ap…

Redis持久化 | RDB AOF | 常见问题

目录 RDB&#xff08;Redis DataBase&#xff09; 给什么内存数据做快照——&#xff08;全量&#xff09; 触发机制 RDB文件生成的时候会阻塞主线程吗&#xff1f; 关闭持久化命令 bgsave执行流程 RDB文件怎么配置&#xff1f;有哪些优缺点 优点&#xff1a; 缺点&am…

React 列表渲染

开发环境&#xff1a;Reacttsantd 你可能经常需要通过 JavaScript 的数组方法 来操作数组中的数据&#xff0c;从而将一个数据集渲染成多个相似的组件。在这篇文章中&#xff0c;你将学会如何在 React 中使用 filter() 筛选需要渲染的组件和使用 map() 把数组转换成组件数组。 …

[ctfshow web入门] web25

信息收集 要想拿到flag&#xff0c;需要突破两层if。 解题 第一个if 传入r0&#xff0c;拿到mt_rand的值&#xff0c;由于每一次访问都会重新设置种子&#xff0c;所以每一次访问都是一样的随机数。 所以我们的r mt_rand-显示的值 1799250188 r1799250188就可以突破第一…

【数据结构】树的介绍

目录 一、树1.1什么是树&#xff1f;1.2 树的概念与结构1.3树的相关术语1.4 树形结构实际运用场景 二、二叉树2.1 概念与结构2.2 特殊的二叉树2.2.1 满二叉树2.2.2 完全二叉树 个人主页&#xff0c;点击这里~ 数据结构专栏&#xff0c;点击这里~ 一、树 1.1什么是树&#xff1…

Android源码之App启动

目录 App启动概述 App启动过程 App启动过程图 源码概述 跨进程启动 进程内启动 下面以应用桌面Launcher启动App的MainActivity来举例&#xff1a; App启动概述 首先&#xff0c;MainActivity是由Launcher组件来启动的&#xff0c;而Launcher又是通过Activity管理服务Act…

【GESP】C++二级练习 luogu-B3721 [语言月赛202303] Stone Gambling S

GESP二级练习&#xff0c;多层循环分支练习&#xff0c;难度★✮☆☆☆。 题目题解详见&#xff1a;https://www.coderli.com/gesp-2-luogu-b3721/ 【GESP】C二级练习 luogu-B3721 [语言月赛202303] Stone Gambling S | OneCoderGESP二级练习&#xff0c;多层循环分支练习&am…

2. Qt界面文件原理

本节主要介绍ui文件如何与窗口关联&#xff0c;并通过隐式连接方式显示对话框 本文部分ppt、视频截图原链接&#xff1a;[萌马工作室的个人空间-萌马工作室个人主页-哔哩哔哩视频] 1 UI文件如何与窗口关联 1.1 mainwindow.cpp的头文件ui_mainwindow.h 根据编译原理的基本规…

Elastic 的 OpenTelemetry 分发版(EDOT)现已正式发布:开源、可用于生产环境的 OTel

作者&#xff1a;来自 Elastic Miguel Luna 及 Bahubali Shetti Elastic 自豪地宣布正式发布 Elastic OpenTelemetry 分发版&#xff08;Elastic Distributions of OpenTelemetry - EDOT&#xff09;&#xff0c;其中包含 Elastic 自定义版本的 OpenTelemetry Collector 以及多…

docker部署jenkins并成功自动化部署微服务

一、环境版本清单&#xff1a; docker 26.1.4JDK 17.0.28Mysql 8.0.27Redis 6.0.5nacos 2.5.1maven 3.8.8jenkins 2.492.2 二、服务架构&#xff1a;有gateway&#xff0c;archives&#xff0c;system这三个服务 三、部署步骤 四、安装linux 五、在linux上安装redis&#…

【NLP 53、投机采样加速推理】

目录 一、投机采样 二、投机采样改进&#xff1a;美杜莎模型 流程 改进 三、Deepseek的投机采样 流程 Ⅰ、输入文本预处理 Ⅱ、引导模型预测 Ⅲ、候选集筛选&#xff08;可选&#xff09; Ⅳ、主模型验证 Ⅴ、生成输出与循环 骗你的&#xff0c;其实我在意透了 —— 25.4.4 一、…

VScode连接CentOS 7.6虚拟机

本文内容&#xff1a;在Windows上使用VMware运行虚拟机&#xff0c;然后使用VScode连接CentOS 7.6虚拟机。 进入系统前 安装VMware 安装教程参考&#xff1a;VMware安装 下载CentOS 7.6镜像 可以使用国内镜像源&#xff0c;但是一般国内镜像源要么已经不维护CentOS 7.6这个…

高德地图 3D 渲染-区域纹理图添加

引入-初始化地图&#xff08;关键代码&#xff09; // 初始化页面引入高德 webapi -- index.html 文件 <script src https://webapi.amap.com/maps?v2.0&key您申请的key值></script>// 添加地图容器 <div idcontainer ></div>// 地图初始化应该…

搭建hadoop集群模式并运行

3.1 Hadoop的运行模式 先去官方看一看Apache Hadoop 3.3.6 – Hadoop: Setting up a Single Node Cluster. 本地模式&#xff1a;数据直接存放在Linux的磁盘上&#xff0c;测试时偶尔用一下 伪分布式&#xff1a;数据存放在HDFS&#xff0c;公司资金不足的时候用 完全分布式&a…

Qt实现鼠标右键弹出弹窗退出

Qt鼠标右键弹出弹窗退出 1、鼠标右键实现1.1 重写鼠标点击事件1.2 添加头文件1.3 添加定义2、添加菜单2.1添加菜单头文件2.2创建菜单对象2.3 显示菜单 3、添加动作3.1添加动作资源文件3.2 添加头文件3.3 创建退出动作对象3.4菜单添加动作对象 4、在当前鼠标位置显示菜单4.1当前…