day08 Spring MVC
spring MVC相当于Servlet
mvc解释:模型,视图,控制器
**使用该思想的作用:**减少耦合性,提高可维护性
Spring MVC前端控制器
方式1
1.在web.xml中配置前端控制器
方式2
要是用前端控制器,必须在web.xml中配置DidpatcherServlet类
<!--前端控制器-->
<servlet><servlet-name>dispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!--指定加载的文件,不加的话默认在webapp里面找--><init-param><param-name>contextConfigLocation</param-name><!--里面的文件就是spring的xml配置文件--><param-value>classpath:applicationContext.xml</param-value></init-param><!--启动时tomcat初始化--><load-on-startup>1</load-on-startup>
</servlet><servlet-mapping><servlet-name>dispatcherServlet</servlet-name><url-pattern>/</url-pattern></servlet-mapping>
spring中的xml文件的基本配置
<!--ioc注解解析器--><context:component-scan base-package="cn.wolfcode"/><!--mvc注解解析器--><mvc:annotation-driven/>
Java文件中的处理器书写,使用Controller和RequestMapping注解
@Controller@RequestMapping("/HelloController")
public class HelloController {// 提供方法处理请求,在浏览器地址栏输入如下 localhost/hello,就会执行下面的方法@RequestMapping("/hello")public ModelAndView save() {ModelAndView mv = new ModelAndView();// 往作用域或者模型中存入数据mv.addObject("msg", "Hello Spring MVC");// 找视图mv.setViewName("WEB-INF/views/hello.jsp");return mv;
注意事项:
@RequestMapping(“/hello”)可以加在方法上,也可以加在类上面
加在类上面的作用:与方法里面进行联用来区分同名的不同的方法
mvc配置联用
<!--ioc注解解析器-->
<context:component-scan base-package="cn.wolfcode"/>
<!--mvc注解解析器-->
<mvc:annotation-driven/>
<!--使用tomcat内置的拦截器访问静态资源-->
<mvc:default-servlet-handler/>
**注意:**上述配置会在 Spring MVC 上下文中创建存入一个 DefaultServletHttpRequestHandler 的 bean,它会对进入 DispatcherServlet 的请求进行筛查,若不是映射的请求,就将该请求交由容器默认的 Servlet 处理。
web.xml拦截规则
*. :要求处理器的地址以.do,静态资源不会进入到前端控制器中,所以可以访问静态资源
/ :对处理地址没有要求,静态资源会被前端控制器进行拦截,里面找不到对应的处理器.解决办法:在spring配置文件中配置<mvc:default-servlet-handler/>,使用tomcat内置的处理器,jsp不会被拦截
/* :对处理地址没有要求,会拦截所有资源(html/jsp),要访问静态资源,配置**mvc:default-servlet-hander**之后可以访问,jsp可以访问但是不会渲染
处理响应的两种方式
1.返回MoudelAndView
@Controller
@RequestMapping("/HelloConctroller")
public class HelloConctroller {/*** 使用ModelAndView处理响应* @return*/@RequestMapping("/hello")public ModelAndView save() {ModelAndView mv = new ModelAndView();//向作用域中或者模型中存入数据,并进行共享mv.addObject("msg", "hello");//寻找视图mv.setViewName("WEB-INF/hello.jsp");return mv;}
2.返回String
注意:传了个model接口作为参数进行使用
@Controller
public class StringController {/** 使用model处理响应* */@RequestMapping("/getrq1")public String rq1(Model model) {model.addAttribute("msg", "123456");/* return "WEB-INF/hello.jsp";*///使用配置文件消除视图的前缀和后缀用于代替上方的放回的String类型的地址//默认是转发return "hello";}
消除视图前缀和后缀
作用:消除视图路径重复.在spring.xml中进行配置,只需要在java文件中写文件名
<!--配置视图解析器,消除前缀以及后缀-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!--视图前缀--><property name="prefix" value="/WEB-INF/"/><!--视图后缀--><property name="suffix" value=".jsp"/>
</bean>
@Controller
public class StringController {/** 使用model处理响应* */@RequestMapping("/getrq1")public String rq1(Model model) {model.addAttribute("msg", "123456");//使用配置文件消除视图的前缀和后缀用于代替上方的放回的String类型的地址//默认是转发return "hello";}
请求转发和重定向
1.请求转发
在ModelAndView/Model的返回值里面添加forward前缀,转发后地址不变,可以进行数据共享
@Controller
public class ResponseConctroller {@RequestMapping("/responseController")public String responseController(Model model){model.addAttribute("msg","请求转发前缀forward");/*使用请求转发的forward前缀,进行页面的跳转和数据的共享*/return "forward:WEB-INF/hello.jsp";}
2.重定向
在ModelAndView/Model的返回值里面添加redirect前缀,转发后地址改变,不能进行数据共享
@Controller
public class ResponseConctroller {@RequestMapping("/responseController")public String responseController(Model model){model.addAttribute("msg","请求转发前缀forward");/*使用重定向的redirect前缀,进行页面的跳转,但是不会对数据进行共享,只能访问WEB-INF外的数据*/return "redirect:index.jsp";}
注意:返回值添加了forward和redirect前缀之后不能和消除视图进行联用
3.路径问题
在请求转发或者重定向的时候,路径:
加/: 使用绝对路径进行寻找,从项目的根目录找
不加/: 使用相对路径寻找,在该路径的同级目录寻找
该模块的总结
1.spring默认使用转发的方式相当于在跳转的视图前面加上 forward
2.spring重定向是在条状的页面之前添加redirect
3.强调:重定向不能直接访问到WEB-INF下的资源
4.使用model()其实就是向request作用域中设定数据, /modeAndView.addObjiect() 也是一样
5.如果使用重定向后,一定要从作用域中取值,可以使用req.getSession().setAttr(),和之前所学的servlet中作用域的知识联用
6.在转发或者冲定向的时候跳转的页面加上 / 和不加 / 的区别
加 / :从根目录开始寻找----绝对路径
不加 /: 从同级目录开始寻找--------相对路径
处理简单类型请求参数
注意:
ModelAndView返回值为null的时候,返回的是空白页面
String返回值为null的时候,就会报空指针异常
底层会帮自动进行类型的转化
接收的参数类型一定要保持一定
1.请求名和形参名相同
可以接收到传进来的值
@Controller
public class ParaTypeController {/*** 接收一个账号和一个密码*///http://localhost:8080/paraTypeController?name=%E7%81%B0%E7%81%B0&password=123456@RequestMapping("/paraTypeController")public ModelAndView paraTypeController(String name,Integer password){System.out.println(name);System.out.println(password);return null;}
2.请求名和形参名不同
会造成接收的参数值为null
使用**@RequestParam(“请求名”)注**解保证接收参数名和形参名相同
/*** 接收一个账号和一个密码,请求参数和形参不同*/
//http://localhost:8080/paraTypeController2?username=灰灰&password=123456@RequestMapping("/paraTypeController2")
//使用@RequestParam解决参数名不一致问题
public ModelAndView paraTypeController2(@RequestParam("username")String name, Integer password){System.out.println(name);System.out.println(password);return null;
}
3.出现了中文乱码
浏览器发送中文的参数值,服务端接收到后出现乱码
3.1:在tomcat7以下的版本使用GET方式传递中文参数值会出现该问题,在pom.xml中的tomcat插件添加编码设置
**3.2:**post方式出现乱码,和tomcat版本没有关系,解决办法,web.xml进行配置
使用表单的方式进行post请求的提交
<%--解决中文乱码--%>
<form method="post" action="/paraTypeController2"><input type="text" name="username"/><input type="password" name="password"/><input type="submit">
</form>
复合类型请求参数
1.接收数组类型参数
接收数组类型的参数,用于每个参数的名字相同的情况(复选框),若里面的参数不能进行匹配,值就是null
/*** 接收多个同名的参数使用Long类型的数组进行接收* 复合类型参数---数组类型*///http://localhost:8080/idsController?ids=1&ids=2&ids=3@RequestMapping("/idsController")public ModelAndView idsController(Long[] ids){System.out.println(ids);return null;}
2.接收自定义类型参数
接收的参数名和自定义类型的属性一 一对应,使用包装类型,若传进来的类型和属性的类型不匹配就找不到,报400
/*** 自定义类型参数的接收* 使用自定义方式接收和请求的方式没有关系*///http://localhost:8080/userController?username=huihui&password=123456@RequestMapping("/userController")public ModelAndView userController(User user){System.out.println(user);return null;}
打印结果如下:
3.处理日期格式参数
接收的参数需要指定格式,底层不会自动将日期类型的参数进行转换,使用**@DateTimeFormat(pattern = “yyyy-MM-dd”)注解**,这个注解可以贴在自定义类型的属性上面
// 增加下面这个字段,并贴注解
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date date;
注意:传进来的日期不能超出范围,否则报400错误
/*** 处理日期类型的参数,将传进来的日期进行转换,需要指定格式*/
//http://localhost:8080/dataController?date=2012-25-3
@RequestMapping("/dataController")
public ModelAndView dataController(@DateTimeFormat(pattern = "yyyy-MM-dd")Date date){System.out.println(date);return null;
}
使用ModeAttribute注解
**作用:**用于回显数据
使用ModeAttribute注解是把数据存到request作用域,代替了手动设置参数值作用域中的
使用String的返回值类型更加简洁
/*** 用于回显数据,使用的返回类型使用String* 使用User自定义参数进行接收---接受的参数展示在页面上* 使用ModelAttribute注解将数据存放到request作用域,同时可以修改在共享作用域的名字* 默认使用的请求转发作用域,无法使用重定向共享数据**/
//http://localhost:8080/AttributeController?username=huihui&password=123456
@RequestMapping("/AttributeController")
public String AttributeController(@ModelAttribute("u") User user){System.out.println(user);return "hello";
}
文件上传
注意及步骤:
1.使用的post请求:有文件大小限制
2.指定文件上传的大小,在web.xml中的中进行指定
3.必须在applicationContext.xml文件中配置StandardServletMultipartResolver解析器,同时解析器必须加上id=“multipartResolver”,否则报400错误
4.使用的part类型进行接收文件,该Part是javax中的类
5.若文件没有进行上传,会报400错误
拦截器
步骤:
1.编写拦截器,实现的是HandlerInterceptor接口,并重写preHandle方法
若返回的的true,会进行拦截,之后会放行这个方法
若返回的false,会拦截这个方法,并不会放行(不会执行这个方法)
2.在applicationContext.xml中配置拦截器
/* 和/**的区别
/* 只会拦截/a /b 这种路径的方法,不会拦截/a/b这种方法
/** 会拦截根目录中所有的方法
<mvc:interceptors><!-- 配置拦截器 --><mvc:interceptor><!-- 拦截的路径 --><mvc:mapping path="/**"/><!-- 被排除的路径<mvc:exclude-mapping path="排除的路径"/> --><!-- 拦截器类 --><bean class="cn.wolfcode.web.interceptor.MyInterceptor"/></mvc:interceptor>
</mvc:interceptors>
拦截器和过滤器的区别
1.过滤器是在web.xml中进行配置, 拦截器是在applicationContext.xml中配置mvc
2.过滤器解决的如字符编码,日志记录,权限验证,拦截器解决业务流程等
执行分析流程
1.用户发请求到前端控制器DispatcherServlet(用于分发请求)
2.DispatcherServlet收到请求调用HandlerMapping(处理映射器)
3.HandlerMapping找到具体的处理器,生成处理器对象,和处理器拦截器,在返会给DispatcherServlet
4.DispatcherServlet 调用HandlerAdapter
5.HandlerAdapter通过适配调用具体的处理器的某个方法controller/hander
6.controller执行后返回ModelAndViwe对象给HandlerAdapter
7.HandlerAdapter在返回给DispatcherServlet
8.DispatcherServlet将ModleAndView传给视图解析器(viewReslover)
9.viewReslover解析后返回具体VIew(视图)
10.DispatcherServlet根据View进行渲染视图
11.DispatcherServlet将视图响应给用户
spatcherServlet收到请求调用HandlerMapping(处理映射器)
3.HandlerMapping找到具体的处理器,生成处理器对象,和处理器拦截器,在返会给DispatcherServlet
4.DispatcherServlet 调用HandlerAdapter
5.HandlerAdapter通过适配调用具体的处理器的某个方法controller/hander
6.controller执行后返回ModelAndViwe对象给HandlerAdapter
7.HandlerAdapter在返回给DispatcherServlet
8.DispatcherServlet将ModleAndView传给视图解析器(viewReslover)
9.viewReslover解析后返回具体VIew(视图)
10.DispatcherServlet根据View进行渲染视图
11.DispatcherServlet将视图响应给用户
相关文章:

day08 Spring MVC
spring MVC相当于Servlet mvc解释:模型,视图,控制器 **使用该思想的作用:**减少耦合性,提高可维护性 Spring MVC前端控制器 方式1 1.在web.xml中配置前端控制器方式2 要是用前端控制器,必须在web.xml中配置DidpatcherServlet类 <!--前端控制器--> <servlet&g…...
c++中的extern “C“
在一些c语言的library库中,我们经常可以还看下面这样的结构 #ifndef __TEST_H #define __TEST_H#ifdef _cplusplus extern "C" { #endif/*...*/#ifdef _cplusplus } #endif #endif#ifndef __TEST_H这样的宏定义应该是非常常见了,其作用是为了…...
python异常处理名称整理
Python 异常处理 python提供了两个非常重要的功能来处理python程序在运行中出现的异常和错误。你可以使用该功能来调试python程序。BaseException所有异常的基类UnboundLocalError访问未初始化的本地变量SystemExit...

SpringMVC拦截器
SpringMVC拦截器 介绍 拦截器(interceptor)的作用 SpringMVC的拦截器类似于Servlet开发中的过滤器Filter,用于对处理器 进行预处理和后处理 将拦截器按一定的顺序连接成一条链,这条链称为拦截器链(Interception Ch…...
Python第八章作业(初级)
目录 第1关:统计字母数量 第2关:统计文章字符数 第3关:查询高校信息 第4关:查询高校名 第5关:通讯录读取 第6关:JSON转列表 第7关:利用数据文件统计成绩 第8关:研究生录取数据…...

chatgpt赋能python:Python中如何取消列表
Python中如何取消列表 在Python中使用列表是一种非常常见的数据结构,它允许我们在其中存储任意数量的元素,并且可以非常容易地进行遍历和操作。但是,有时候我们需要从列表中删除元素。这个过程并不难,但是有些细节需要注意。本文…...

Java中List排序的3种方法
在某些特殊的场景下,我们需要在 Java 程序中对 List 集合进行排序操作。比如从第三方接口中获取所有用户的列表,但列表默认是以用户编号从小到大进行排序的,而我们的系统需要按照用户的年龄从大到小进行排序,这个时候,…...
flutter-读写二进制文件到设备
看了下很多文章,本地文件存储都只有存储txt文件,我们探索下存储二进制文件吧。 保存二进制文件到设备硬盘上。 我们保存一个图片到手机本地上,并读取展示图片到app上。 以百度logo图为例子 写入图片 逻辑如下: 获取本地路径 -&g…...
C语言基础知识:内存分配
目录 内存分配原理 内存分配方法 静态内存分配 动态内存分配 MALLOC() CALLOC() 内存释放 注意事项 在C语言中,内存分配是非常重要的一个概念,因为C语言中没有内置的垃圾回收机制,需要我们手动管理内存的分配和释放。下面我们来详细讲…...

【Simulink】示波器图形数据导入Matlab重新绘图(论文)
版本:Matlab2019b 效果 示波器波形图片: 黑色背景,而且坐标轴字体较小,不方便修改,不能直接用在论文上面 对比 Matlab 绘图: 接下来介绍如何设置~ Simulink 设置 选择需要导入的示波器数据 点击 Vi…...

汇编调试及学习
汇编调试 打印寄存器的值 打印内存地址 打印8字节,就是64位 打印格式 是从低位取过来的 b 字节 h 双字节 w四字节 g八字节 前变基 后变基 。 后变基这个变基会发生变化的。前变基变基不会发生变化需要用!号。 前变基 , 加了࿰…...

Linux - 第19节 - 网络基础(传输层二)
1.TCP相关实验 1.1.理解listen的第二个参数 在编写TCP套接字的服务器代码时,在进行了套接字的创建和绑定之后,需要调用listen函数将创建的套接字设置为监听状态,此后服务器就可以调用accept函数获取建立好的连接了。其中listen函数的第一个参…...

web实现日历、阳历农历之间相互转换、npm、push、unshift、includes、innerHTML
文章目录 1、原生web实现效果图htmlJavaScriptstyle vue2实现htmlJavaScript 1、原生web实现 效果图 html <div class"box"><div class"week"><div>星期日</div><div>星期一</div><div>星期二</div><…...

GcExcel v6.1 支持新的 ‘.sjs‘ 模板文件 ‘.xltx‘ 格式 Crack
GrapeCity Documents for Excel (GcExcel) v6.1 版本现已上线!该版本支持新的 SpreadJS .sjs 文件格式和 Excel 模板文件 .xltx 格式。此外,GcExcel 支持更多的SpreadJS兼容性功能和对 GcDataViewer 的多项增强。看看下面的主要亮点。 导入/导出 Spread…...

面试官:MySQL自增主键一定是连续的吗?
测试环境: MySQL版本:8.0 数据库表:T (主键id,唯一索引c,普通字段d) 如果你的业务设计依赖于自增主键的连续性,这个设计假设自增主键是连续的。但实际上,这样的假设是错的…...

2023ACP世界大赛教育者论坛:让职业教育直面AI机遇与挑战
“AI技术的普及对创意行业和教育带来的影响和变革-2023 Adobe Certified Professional教育者论坛”在苏州西交利物浦大学成功举办。 本次论坛,由Adobe Certified Professional 世界大赛中国赛区组委会主办,联动了来自院校、海内外杰出的创意公司及国际知…...

Unity基础 音频组件以及音频播放
在游戏开发中,声音是一个重要的环节。Unity中的声音组件可以帮助开发者轻松地控制游戏中音频的播放、音量、循环等属性,从而实现更好的游戏体验。本文将详细介绍Unity声音组件的相关概念和技术,以及其在游戏、影视等领域的广泛应用和发展前景…...

SAP-MM-采购申请审批那些事!
1、ME55不能审批删除行项目的PR 采购申请审批可以设置行项目审批或抬头审批。如果设置为抬头审批时,ME55集中审批时,就会发现有些采购申请时不能审批的, 那么这些采购申请时真的不需要审批么?不是的,经过核对这些采购申…...

专业解读财务共享实现财务数智化转型的有效路径
近年来,随着数字经济的飞速发展,各大企业全面开启数智化转型之路,作为企业数智化转型的重要内容,财务数智化转型始于财务共享服务。然而,财务共享建设并不是一蹴而就的,如何通过财务共享实现财务数智化转型…...

九章云极DataCanvas公司诚邀您共享AI基础软件前沿技术盛宴
“杭州通用人工智能论坛暨AIIA人工智能产业发展大会”将于2023年5月30日-31日在杭州举办。本次人工智能产业发展大会由中国信息通信研究院、中国人工智能产业发展联盟主办,杭州城西科创大走廊管委会、杭州市经济和信息化局、杭州未来科技城管理委员会、人工智能关键…...

【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...

算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...

yaml读取写入常见错误 (‘cannot represent an object‘, 117)
错误一:yaml.representer.RepresenterError: (‘cannot represent an object’, 117) 出现这个问题一直没找到原因,后面把yaml.safe_dump直接替换成yaml.dump,确实能保存,但出现乱码: 放弃yaml.dump,又切…...

Mysql故障排插与环境优化
前置知识点 最上层是一些客户端和连接服务,包含本 sock 通信和大多数jiyukehuduan/服务端工具实现的TCP/IP通信。主要完成一些简介处理、授权认证、及相关的安全方案等。在该层上引入了线程池的概念,为通过安全认证接入的客户端提供线程。同样在该层上可…...