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

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 {@Beanpublic 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 {@Beanpublic SpringTemplateEngine templateEngine() {SpringTemplateEngine engine = new SpringTemplateEngine();engine.setTemplateResolver(templateResolver());return engine;}@Beanpublic SpringResourceTemplateResolver templateResolver() {SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();resolver.setPrefix("classpath:/templates/");resolver.setSuffix(".html");return resolver;}@Beanpublic 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 {@Overrideprotected 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 {@Overrideprotected 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.mzph.cn/web/75205.shtml

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

相关文章

【AAOS】【源码分析】CarAudioService(二)-- 功能介绍

汽车音频是 Android 汽车操作系统 (AAOS) 的一项功能,允许车辆播放信息娱乐声音,例如媒体、导航和通信。AAOS 不负责具有严格可用性和时间要求的铃声和警告,因为这些声音通常由车辆的硬件处理。将汽车音频服务集成在汽车中,彻底改变了驾驶体验,为驾驶员和乘客提供了音乐、…

docker安装软件汇总(持续更新)

1、简介 本文介绍一些常用的软件通过docker安装并启动&#xff0c;持续更新。 2、docker安装软件 2.1、zookeeper & kafka # 1、拉取zookeeper镜像 git pull wurstmeister/zookeeper # 2、启动zookeeper容器 docker run -d --restartalways --log-driver json-file --lo…

MySQL的左连接、右连接、内连接、外连接

一、前言 MySQL中的左连接、右连接、内连接和全外连接是用于多表关联查询的核心操作。 二、内连接&#xff08;INNER JOIN&#xff09; 定义&#xff1a;返回两个表中完全匹配的行&#xff0c;即只保留两个表连接字段值相等的行。示例场景&#xff1a;查询所有有选课记录的学…

前端面试宝典---数据类型

基本数据类型 对于基本类型在创建时无需使用 new 关键字 Bigint在实际开发不常用&#xff0c;如果对于精度要求高可以使用第三方库&#xff0c;如decimal.js 基本数据类型介绍 undefined&#xff1a;当变量被声明但未赋值&#xff0c;或者函数没有返回值时&#xff0c;就会呈现…

Lua 函数使用的完整指南

在 Lua 中&#xff0c;函数是一等公民&#xff08;First-Class Citizen&#xff09;&#xff0c;这意味着函数可以像其他值一样被赋值、传递和操作。以下是 Lua 函数定义的完整指南&#xff0c;涵盖基础语法、高级特性、设计模式及性能优化。 在Lua 中&#xff0c;函数定义的完…

使用StockTV API对接印度金融市场数据全指南:K线、实时行情与IPO新股

一、印度金融市场数据特点 印度作为全球增长最快的主要经济体之一&#xff0c;其金融市场具有以下显著特征&#xff1a; 双交易所体系&#xff1a;国家证券交易所(NSE)和孟买证券交易所(BSE)高流动性品种&#xff1a;Nifty 50指数成分股、银行股等独特交易机制&#xff1a;T2…

2021-10-26 C++繁忙通信兵

缘由繁忙的通讯兵&#xff0c;可以解决一下吗-编程语言-CSDN问答 void 繁忙通信兵() {//缘由https://ask.csdn.net/questions/7544401?spm1005.2025.3001.5141int a 200, s1 8, s2 5, s3 45, p 0, n 0, c 0;std::cin >> n;while (a > n){a - s1 s2;if (a &l…

【Linux】进程控制:创建、终止、等待与替换全解析

文章目录 前言一、重谈进程创建二、进程终止2.1 正常终止的退出码机制2.2 异常终止的信号机制2.3 进程常见的退出方法 三、进程等待&#xff1a;避免僵尸进程的关键3.1 进程等待的必要性3.2 进程等待的两个系统调用接口3.2.1 wait()3.2.2 waitpid()区别 四、进程程序替换4.1 进…

基于Redis实现短信防轰炸的Java解决方案

基于Redis实现短信防轰炸的Java解决方案 前言 在当今互联网应用中&#xff0c;短信验证码已成为身份验证的重要手段。然而&#xff0c;这也带来了"短信轰炸"的安全风险 - 恶意用户利用程序自动化发送大量短信请求&#xff0c;导致用户被骚扰和企业短信成本激增。本…

【后端开发】Spring MVC-常见使用、Cookie、Session

文章目录 代码总结初始化--RestController、RequestMapping传递参数单参数多参数 传递对象后端参数重命名&#xff08;后端参数映射&#xff09;--RequestParam必传参数设置非必传参数 传递数组传递集合传递JSON数据JSON语法JSON格式转换JSON优点传递JSON对象 获取URL中参数--P…

青少年编程考试 CCF GESP Python七级认证真题 2025年3月

Python 七级 2025 年 03 月 题号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 答案 B C A B B A A B C A B B A B A 1 单选题&#xff08;每题 2 分&#xff0c;共 30 分&#xff09; 第 1 题 下列哪个选项是python中的关键字&#xff1f; A. function B. class C. method D. object…

Vue 框架组件间通信方式

组件间通信方式 不管是 vue2 还是 vue3&#xff0c;组件通信方式很重要&#xff0c;以下是常见的几种通信方式&#xff1a; props&#xff1a;可以实现父子组件、子父组件、甚至兄弟组件通信自定义事件&#xff1a;可以实现子父组件通信全局事件总线 $bus&#xff1a;可以实现…

SpringBoot学生成绩管理系统设计与实现

概述 幽络源本次分享的基于SpringBoot的学生成绩管理系统项目&#xff0c;采用主流的Java技术栈开发&#xff0c;实现了从学生信息管理到成绩统计分析的全流程数字化管理。 主要内容 管理员功能模块 ​​学生信息管理​​&#xff1a;维护学生基本信息档案&#xff0c;支持…

青少年编程与数学 02-016 Python数据结构与算法 01课题、算法

青少年编程与数学 02-016 Python数据结构与算法 01课题、算法 一、算法的定义二、算法的设计方法1. 分治法2. 动态规划法3. 贪心算法4. 回溯法5. 迭代法6. 递归法7. 枚举法8. 分支定界法 三、算法的描述方法1. **自然语言描述**2. **流程图描述**3. **伪代码描述**4. **程序设计…

Java 实现冒泡排序:[通俗易懂的排序算法系列之二]

引言 大家好!欢迎来到我的排序算法系列第二篇。今天,我们将学习另一种非常基础且广为人知的排序算法——冒泡排序 (Bubble Sort)。 冒泡排序的名字非常形象,它模拟了水中气泡上升的过程:较小(或较大)的元素会像气泡一样,通过不断交换,逐渐“浮”到数组的一端。 什么是…

struct结构体、union联合体和枚举

目录 一、结构体的声明和使用 1.1 结构体正常声明和创建 1.2 结构体特殊声明 1.3 结构体的自引用 二、结构体内存对齐 2.1 对齐规则 2.2 #pragma修改 三、结构体传参 四、结构体位段 4.1 位段内存分配 4.2 位段内存应用 五、结构体中的柔性数组概念 六、union联合…

大模型本地部署系列(2) Ollama部署DeepSeek-R1

成功运行截图 部署步骤 我们进入到ollama的官网&#xff1a; Ollama​ollama.com/​编辑 找到上方的Models &#xff0c;然后点击 此时会跳转到模型列表页面&#xff1a; 点击 deepseek-r1 链接进去&#xff0c;此时我们会看到下拉框中有各个版本的大模型&#xff0c;越往后…

绘制动态甘特图(以流水车间调度为例)

import matplotlib.pyplot as plt import matplotlib.animation as animation import numpy as np from matplotlib import cm# 中文字体配置&#xff08;必须放在所有绘图语句之前&#xff09; plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] Fa…

PyTorch实现线性回归的基础写法与封装API写法

目录 1. 基础写法 1.1导包 2.2加载读取数据 2.3原始数据可视化(画图显示) 2.4线性回归的(基础)分解写法 2.5定义训练过程 2.PyTorch实现 线性回归的封装写法(实际项目中的常用写法) 2.1创建线性回归模型 2.2定义损失函数 2.3定义优化器 2.4定义训练过程 1…

python 常用的6个爬虫第三方库

Python中有非常多用于网络数据采集的库&#xff0c;功能非常强大&#xff0c;有的用于抓取网页&#xff0c;有的用于解析网页&#xff0c;这里介绍6个最常用的库。 1. BeautifulSoup BeautifulSoup是最常用的Python网页解析库之一&#xff0c;可将 HTML 和 XML 文档解析为树形…