SpringMVC是一个基于DispatcherServlet的MVC框架,每一个请求最先访问的都是DispatcherServlet,DispatcherServlet负责转发每一个Request请求给相应的Handler,Handler处理以后再返回相应的视图(View)和模型(Model),返回的视图和模型都可以不指定,即可以只返回Model或只返回View或都不返回。在使用注解的SpringMVC中,处理器Handler是基于@Controller和@RequestMapping这两个注解的,@Controller声明一个处理器类,@RequestMapping声明对应请求的映射关系,这样就可以提供一个非常灵活的匹配和处理方式。
DispatcherServlet是继承自HttpServlet的,既然SpringMVC是基于DispatcherServlet的,那么我们先来配置一下DispatcherServlet,好让它能够管理我们希望它管理的内容。HttpServlet是在web.xml文件中声明的。
- <servlet>
- <servlet-name>blog</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>blog</servlet-name>
- <url-pattern>*.do</url-pattern>
- </servlet-mapping>
上面声明了一个名为blog的DispatcherServlet,该Servlet将处理所有以“.do”结尾的请求。在初始化DispatcherServlet的时候,SpringMVC默认会到/WEB-INF目录下寻找一个叫[servlet-name]-servlet.xml的配置文件,来初始化里面的bean对象,该文件中对应的bean对象会覆盖spring配置文件中声明的同名的bean对象。如上面的就会在/WEB-INF目录下寻找一个叫blog-servlet.xml的文件;当然也可以在Servlet中声明配置文件的位置,那就是通过Servlet的初始化参数来设置contextConfigLocation参数的值。
- <servlet>
- <servlet-name>blog</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <init-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>/WEB-INF/blog-servlet.xml</param-value>
- </init-param>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>blog</servlet-name>
- <url-pattern>*.do</url-pattern>
- </servlet-mapping>
DispatcherServlet会利用一些特殊的bean来处理Request请求和生成相应的视图返回。
关于视图的返回,Controller只负责传回来一个值,然后到底返回的是什么视图,是由视图解析器控制的,在jsp中常用的视图解析器是InternalResourceViewResovler,它会要求一个前缀和一个后缀
- <bean
- class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <property name="prefix" value="/WEB-INF/" />
- <property name="suffix" value=".jsp" />
- </bean>
在上述视图解析器中,如果Controller返回的是blog/index,那么通过视图解析器解析之后的视图就是/WEB-INF/blog/index.jsp。
要使用注解的SpringMVC需要在SpringMVC的配置文件中进行声明,具体方式为先引入mvc命名空间,然后利用<mvc:annotation-driven />进行声明。
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
- <span style="background-color: #00ff00;"><span style="color: #ff0000;">xmlns:mvc="http://www.springframework.org/schema/mvc"</span>
- </span>
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-3.0.xsd
- <span style="background-color: #00ff00; color: #ff0000;"> http://www.springframework.org/schema/mvc
- http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"</span>
- >
- <mvc:annotation-driven />
- </beans>
主要是说说Controller.
在SpringMVC中Controller不需要继承什么类,也不需要实现什么接口,一切使用了@Controller进行标记的类都是Controller
- @Controller
- public class BlogController {
- }
有了Controller之后,那么到底是怎样请求一个Controller具体的方法的呢,那是通过@RequestMapping来标记的,@RequestMapping可以标记在类上面,也可以标记在方法上,当方法上和类上都标记了@RequestMapping的时候,那么对应的方法对应的Url就是类上的加方法上的,如下面的index方法,其对应的URL应为类上的/blog加上index方法上的/index,所以应为/blog/index,所以当请求/blog/index.do的时候就会访问BlogController的index方法。加在类上的@RequestMapping不是必须的,当Controller类上加上了@RequestMapping的时候,那么Controller方法上的@RequestMapping就是相对于类上的@RequestMapping而言的,也就是前面说的请求映射的时候是类上的地址加方法上的地址,而当Controller类上没有加@RequestMapping的时候,方法上的@RequestMapping就是绝对路径了。
- @Controller
- @RequestMapping("/blog")
- public class BlogController {
- @RequestMapping("/index")
- public String index(Map<String, Object> map) {
- return "blog/index";
- }
- }
在上面的代码中,如果index方法上没有RequestMapping注解,而只有BlogController类上有,且该类只有一个方法的时候,直接请求类上的URL就会调用里面的方法,即直接请求/blog.do的时候就会调用index方法。
在RequestMapping中还可以指定一个属性method,其主要对应的值有RequestMethod.GET和RequestMethod.POST,利用该属性可以严格的控制某一方法只能被标记的请求路径对应的请求方法才能访问,如指定method的值为GET,则表示只有通过GET方式才能访问该方法,默认是都可以访问。RequestMapping中的URL映射还支持通配符*,如:
- @Controller
- @RequestMapping("/blog")
- public class BlogController {
- @RequestMapping("/*/index")
- public String index(Map<String, Object> map) {
- return "blog/index";
- }
- }
在@RequestMapping中还有一个属性params,可以通过该属性指定请求参数中必须包含某一参数,或必须不包含某一参数,或某参数的值必须是什么,以此来缩小指定的映射范围。
- @Controller
- @RequestMapping("/blog")
- public class BlogController {
- @RequestMapping(value="/index", params="param1=value1")
- public String index(Map<String, Object> map) {
- return "blog/index";
- }
- }
在上面示例中,只有当请求/blog/index.do并且请求参数param1的值为value1的时候才能访问到对应的index方法。如果params的值为"param1",则表示请求参数只要包含param1就可以了,至于它的值是什么无所谓;如果params的值为"!param1",则表示请求参数必须不包含param1才可以。@RequestMapping中还可以使用header来缩小映射范围,如:
- @Controller
- @RequestMapping("/blog")
- public class BlogController {
- @RequestMapping(value="/index",headers="content-type=text/html")
- public String index(Map<String, Object> map) {
- return "blog/index";
- }
- }
在SpringMVC中常用的注解还有@PathVariable,@RequestParam,@PathVariable标记在方法的参数上,利用它标记的参数可以利用请求路径传值,看下面一个例子
- @RequestMapping(value="/comment/{blogId}", method=RequestMethod.POST)
- public void comment(Comment comment,@PathVariable int blogId, HttpSession session, HttpServletResponse response) throws IOException {
- }
在该例子中,blogId是被@PathVariable标记为请求路径变量的,如果请求的是/blog/comment/1.do的时候就表示blogId的值为1,@PathVariable在进行赋值的时候如果像上面那样没有指定后面接的变量是对应URL中的哪个变量时默认是从URL中取跟后面接的变量名相同的变量,如上面示例中的@PathVariable int blogId,没有指明要获取URL中的哪个变量,这个时候就默认取URL中的blogId变量对应的值赋给方法参数中的blogId,那如果方法参数的名称跟RequestMapping中定义的访问路径中的变量名不一样,或者我要利用PathVariable明确指定后面接的方法参数是对应于URL中的哪个变量时,可以像下面这样做,在PathVariable中给定一个value="blogId"(只有一个参数的时候value是可以省略的)值明确指定方法参数中的id变量是对应请求路径定义中的blogId变量的。
- @RequestMapping(value="/comment/{blogId}", method=RequestMethod.POST)
- public void comment(Comment comment,@PathVariable("blogId") int id, HttpSession session, HttpServletResponse response) throws IOException {
- }
同样@RequestParam也是用来给参数传值的,但是它是从头request的参数里面取值,相当于request.getParameter("参数名")方法。它的取值规则跟@PathVariable是一样的,当没有指定的时候,默认是从request中取名称跟后面接的变量名同名的参数值,当要明确从request中取一个参数的时候使用@RequestParam("参数名"),如下所示:
- @RequestMapping("/show")
- public void showParam(@RequestParam int id, @RequestParam("name") String username) {
- //这样做进行URL请求访问这个方法的时候,就会先从request中获取参数id的值赋给参数变量id,从request中获取参数name的值赋给参数变量username
- }
在Controller的方法中,如果需要WEB元素HttpServletRequest,HttpServletResponse和HttpSession,只需要在给方法一个对应的参数,那么在访问的时候SpringMVC就会自动给其传值,但是需要注意的是在传入Session的时候如果是第一次访问系统的时候就调用session会报错,因为这个时候session还没有生成。
接下来讨论一下方法的返回值,主要有以下情况:
- 返回一个ModelAndView,其中Model是一个Map,里面存放的是一对对的键值对,其可以直接在页面上使用,View是一个字符串,表示的是某一个View的名称
- 返回一个字符串,这个时候如果需要给页面传值,可以给方法一个Map参数,该Map就相当于一个Model,往该Model里面存入键值对就可以在页面上进行访问了
- 返回一个View对象
- 返回一个Model也就是一个Map,这个时候将解析默认生成的view name,默认情况view name就是方法名,这里之前搞错了,感谢网友的指正。默认的View Name是由RequestToViewNameTranslator来解析的,顾名思义就是把request翻译成viewName,在没有指定RequestToViewNameTranslator时,Spring将使用其自身的默认实现DefaultRequestToViewNameTranslator的默认配置,即取到当前请求的URI,去掉最前和最后的斜杠“/”,以及对应的后缀。所以当你请求“http://localhost/app/abc”的时候,对应的默认viewName就是请求URI——“/abc”去掉最前最后的斜杠和后缀之后的结果,即“abc”,请求“http://localhost/app/abc/efg”时对应的默认视图名称是“abc/efg”,“http://localhost/app/abc/efg/hi.html”——>“abc/efg/hi”。如果需要改变默认的视图名称的解析方式,可以在SpringMVC的配置文件中配置一个名称为viewNameTranslator,类型为RequestToViewNameTranslator的bean。如果该bean是DefaultRequestToViewNameTranslator,那么你可以通过prefix属性指定视图名称的前缀,通过suffix指定后缀,通过stripLeadingSlash指定是否需要去掉最前面的斜杠,更多可指定的属性请参考DefaultRequestToViewNameTranslator的实现。当然你也可以定义自己的RequestToViewNameTranslator实现类,实现RequestToViewNameTranslator接口的getViewName(HttpServletRequest request)方法,实现自己的获取默认视图名称的逻辑。
- 什么也不返回,这个时候可以在方法体中直接往HttpServletResponse写入返回内容,否则将会由RequestToViewNameTranslator来决定
- 任何其他类型的对象。这个时候就会把该方法返回类型对象当做返回Model模型的一个属性返回给视图使用,这个属性名称可以通过在方法上给定@ModelAttribute注解来指定,否则将默认使用该返回类名称作为属性名称。
- @RequestMapping("/{owner}/index")
- public String userIndex(Map<String, Object> map,@PathVariable String owner, HttpServletRequest request) throws ParserException {
- List<DefCategory> categories = categoryService.find(owner);
- int offset = Util.getOffset(request);
- Pager<Blog> pager = blogService.find(owner, 0, offset, maxResults);
- int totalRecords = pager.getTotalRecords();
- List<Blog> blogs = pager.getData();
- Util.shortBlog(blogs);
- List<Message> messages = messageService.find(owner, 0, 5).getData();
- Util.shortMessage(messages, 20);
- map.put("messages", messages);
- map.put("totalRecords", totalRecords);
- List<BlogStore> stores = storeService.find(owner, 0, 5).getData();
- map.put("maxResults", maxResults);
- map.put("blogs", blogs);
- map.put("totalRecords", totalRecords);
- map.put("owner", userService.find(owner));
- map.put("defCategories", categories);
- map.put("stores", stores);
- return "blog/userIndex";
- }
给页面传值
在Controller中把请求转发给业务逻辑层进行处理之后需要把业务逻辑层的处理结果进行展现,在展现的过程中就需要我们把处理结果传给展示层进行展示。那么处理结果是怎么进行传递的呢?前面已经说了Controller的返回结果可以是一个包含模型和视图的ModelAndView,也可以仅仅是一个视图View,当然也可以什么都不返回,还可以是仅仅返回一个Model。我们知道模型Model是用来封装数据给视图View进行展示的,那么,在SpringMVC中,如果要把我们后台的信息传递给前台进行展示的话应该怎么做呢?这主要有两种方式:
1.返回包含模型Model的ModelAndView,或者是直接返回一个Model(这个时候就需要考虑默认的视图),这种类型的返回结果是包含Model的,这个Model对象里面的对应属性列都可以直接在视图里面使用。
2.如果是直接返回一个视图View,这个时候SpringMVC提供了一种类似于在Controller方法中获取HttpRequest对象的机制,这个时候我们只需要给定Controller方法一个Map参数,然后在方法体里面给这个Map加上需要传递到视图的键值对,这样在视图中就可以直接访问对应的键值对
本文转载,原文地址:http://haohaoxuexi.iteye.com/blog/1343761#comments
相关推荐
U盘量产工具FLASH量产工具SM3280&3281&3282-AvidiaV0209整合版
java课程期末考试
分布式消息中间件,参考kafka,未完成
修木工施工规范及流程.docx
内容概要:本文详细介绍了VECTOR提供的MICROSAR OBD协议栈解决方案,涵盖了OBD模块、ECU支持、监控功能和服务请求等方面的内容。此外,还讨论了OBD在不同国家和地区的技术标准与法规要求,以及MICROSAR OBD解决方案的优势,如适应不同项目的需求和高度集成于AUTOSAR 4平台。 适合人群:汽车电子工程师、软件开发者、汽车制造商及相关行业从业人员。 使用场景及目标:① 适用于车辆诊断系统的开发和维护;②帮助工程师理解和掌握OBD协议的具体实施方法和应用场景;③ 提供了一个成熟、可扩展的解决方案,用于满足OBD相关标准和法规的要求。 其他说明:本文不仅提供了技术层面的详细解析,还探讨了实际操作过程中可能遇到的问题和解决方案。同时强调了屏蔽信息过载的重要性,提醒工程师保持内心平静,专注做好本职工作。
适用于 Python 的 LINE 消息 API SDK适用于 Python 的 LINE Messaging API 的 SDK。介绍适用于 Python 的 LINE Messaging API SDK 可以轻松使用 LINE Messaging API 开发机器人,您可以在几分钟内创建一个示例机器人。文档请参阅官方 API 文档了解更多信息英语https //developers.line.biz/en/docs/messaging-api/overview/日语https://developers.line.biz/ja/docs/messaging-api/overview/要求Python >= 3.9安装$ pip 安装 line-bot-sdk概要用法from flask import Flask, request, abortfrom linebot.v3 import ( WebhookHandler)from linebot.v3.exceptions import ( InvalidSig
Java字节码工程工具包Javassist 版本 3版权所有 (C) 1999-2023 Shigeru Chiba,保留所有权利。Javassist(JAVA 编程助手)使 Java 字节码操作变得简单。它是一个用于编辑 Java 字节码的类库它使 Java 程序能够在运行时定义新类并在 JVM 加载类文件时对其进行修改。与其他类似的字节码编辑器不同,Javassist 提供两个级别的 API源代码级别和字节码级别。如果用户使用源代码级别 API,他们可以编辑类文件而无需了解 Java 字节码的规范。整个 API 仅使用 Java 语言的词汇表进行设计。您甚至可以以源文本的形式指定插入的字节码Javassist 会即时编译它。另一方面,字节码级别 API 允许用户像其他编辑器一样直接编辑类文件。该软件根据 Mozilla 公共许可证版本 1.1、GNU 宽通用公共许可证版本 2.1 或更高版本或 Apache 许可证版本 2.0 分发。文件README.md 此自述文件。Changes.md 发行说明。License.html 许可证文件。tuto
本项目是基于Python语言开发的西西家居全屋定制系统,旨在为家居行业提供一个高效、智能的定制解决方案。项目涵盖了从客户需求分析、设计方案生成、材料选购到最终订单生成的全过程,力求实现家居定制的数字化和智能化。 在主要功能方面,系统具备强大的客户管理模块,能够详细记录和分析客户的定制需求。设计模块则采用先进的三维建模技术,为客户提供直观、真实的家居设计方案预览。此外,系统还整合了丰富的材料数据库,方便客户根据自身喜好和预算进行材料选择。 框架方面,项目采用了B/S架构,确保了系统的稳定性和可扩展性。后端使用Python的Django框架,前端则结合了HTML、CSS和JavaScript等技术,实现了用户界面的友好和响应速度。 开发此项目的目的,不仅是为了满足家居行业对个性化定制的需求,也为计算机相关专业的学生提供了一个实践和学习的平台,有助于提升他们的实际开发能力。
Javascript 是数字化创新的起点,是语言的基础,也是基本概念。Basecamp JavascriptJavascript 是数字化创新的起点,是语言的基础,也是基本概念。嵌套存储库,可作为启动项下待办事项的实践活动。
已弃用 — Coinbase Python APICoinbase Coinbase API V2的官方 Python 库。重要提示此库当前针对的是 API V2,而 OAuth 客户端需要 V2 权限(即wallet:accounts:read)。如果您仍在使用 API V1,请使用此库的旧版本。特征接近 100% 的测试覆盖率。支持API Key + Secret和OAuth 2身份验证。调用 API 的便捷方法 - 为您打包 JSON!自动将 API 响应解析为相关的 Python 对象。使用IPython时,所有对象都具有可制表完成的方法和属性。安装coinbase可以在PYPI上使用。使用以下命令安装pippip install coinbase或者easy_installeasy_install coinbase该库目前针对 Python 版本 2.7 和 3.4+ 进行了测试。注意此软件包名称过去是指George Sibble维护的非官方 coinbase_python 库。George 慷慨地允许我们使用此软件包
基于RBAC权限控制的基础后台
本项目是基于Python爬虫的网络小说数据分析系统的设计与实现,旨在为计算机相关专业的大学生提供一个实践平台,特别是在毕业设计和项目实战练习方面。项目通过Python强大的网络爬虫技术,从流行的网络小说网站自动抓取数据,包括书籍信息、章节内容、用户评论等。 主要功能涵盖数据采集、数据清洗、数据存储和数据分析。数据采集模块利用Scrapy等爬虫框架高效抓取网页内容;数据清洗模块确保数据的准确性和一致性;数据存储则采用MySQL等数据库系统,便于数据管理和查询;数据分析模块通过Pandas、NumPy等工具进行数据处理和分析,生成多维度的统计报告和可视化图表。 此项目不仅帮助学生掌握Python编程和网络爬虫技术,还能让他们深入了解数据分析的全过程,提升解决实际问题的能力。同时,系统的实现和应用也反映了现代信息技术在文学创作和消费领域的应用价值和潜力。
本项目是一个基于Java的在线日语培训平台的设计与实现,采用SSM框架(Spring+SpringMVC+MyBatis)进行开发,旨在为计算机相关专业的学生提供一个实践和学习的平台,同时也为日语学习者提供一个在线学习的空间。项目中主要功能涵盖了用户管理、课程管理、学习资源上传下载、在线测试与反馈等多个方面。通过该平台,教师能够轻松管理课程内容和学生信息,学生则可以随时随地访问学习资源,参与在线课程和测试,从而提高学习效率和兴趣。 在开发此项目的过程中,我们重点关注了系统的可维护性和可扩展性,确保代码结构清晰,便于后续的功能迭代和优化。此外,通过使用SSM框架,实现了前后端的分离,提高了开发效率和系统的响应速度。该项目不仅能够满足毕设的需求,还能作为Java学习者提升编程能力和实践经验的实用工具。
基于java的机票管理系统设计与实现.docx
该项目为《基于Java实现的数据结构设计源码》,共包含51个文件,主要由46个Java源文件构成,辅以2个文本文件、1个Git忽略文件、1个许可证文件以及1个XML文件,全面涵盖了数据结构设计的核心内容。
绿色食品 水稻生产操作规程.docx
他妈的 Fuck是一款出色的应用程序,其灵感来自@liamosaur 的 推文,它可以纠正以前控制台命令中的错误。The Fuck太慢了吗?试试实验性的即时模式!更多示例➜ apt-get install vimE: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?➜ fucksudo apt-get install vim [enter/↑/↓/ctrl+c][sudo] password for nvbn:Reading package lists... Done...➜ git pushfatal: The current branch master has no upstream branch.To push the current branch and set the remote
全国大学生FPGA创新设计竞赛作品 “泡罩包装药品质量在线检测平台“.zip
桃苗木质量基本要求表.docx
使用 Python 漂亮地打印表格数据,这是一个库和一个命令行实用程序。存储库从 bitbucket.org/astanin/python-tabulate 迁移而来。python-tabulate使用 Python、库和命令行实用程序漂亮地打印表格数据。该库的主要用例是轻松打印小表格只需一个函数调用,格式由数据本身引导为轻量级纯文本标记创作表格数据多种输出格式适合进一步编辑或转换混合文本和数字数据的可读表示智能列对齐、可配置数字格式、小数点对齐安装要安装 Python 库和命令行实用程序,请运行pip install tabulate命令行实用程序将在 Linux 上安装为(例如tabulate)或者在 Windows 上的 Python 安装中安装为(例如)。bin/usr/bintabulate.exeScriptsC:\Python39\Scripts\tabulate.exe您可以考虑仅为当前用户安装该库pip install tabulate --user在这种情况下,命令行实用程序将安装到 ~/.local/bin/tabula