安庆大理运城常德铜陵江西
投稿投诉
江西南阳
嘉兴昆明
铜陵滨州
广东西昌
常德梅州
兰州阳江
运城金华
广西萍乡
大理重庆
诸暨泉州
安庆南充
武汉辽宁

牛啊!终于有人把主流服务层框架SpringMVC讲明白了

11月7日 拭朱砂投稿
  SpringMVC简介
  首先我们先来简单了解一下SpringMVC:SpringMVC是一种基于Java实现MVC模型的轻量级Web框架SpringMVC致力于服务层,同Servlet一样应用于服务层,用于服务层开发SpringMVC隶属于Spring,同样具有简化代码,使用简单,开发便捷,灵活性强的优点SpringMVC入门案例
  在未学习SpringMVC之前,我们的服务端开发通常采用Servlet:packagecom。itheima。web。servlet。importcom。alibaba。fastjson。JSON;importcom。itheima。pojo。Bimportcom。itheima。service。BrandSimportcom。itheima。service。impl。BrandServiceIimportjavax。servlet。ServletEimportjavax。servlet。annotation。WebSimportjavax。servlet。http。HttpSimportjavax。servlet。http。HttpServletRimportjavax。servlet。http。HttpServletRimportjava。io。BufferedRimportjava。io。IOEimportjava。util。LWebServlet(addServlet)publicclassAddServletextendsHttpServlet{privateBrandServicebrandServicenewBrandServiceImpl();OverrideprotectedvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{1。接收品牌数据BufferedReaderbrrequest。getReader();Stringparamsbr。readLine();json字符串转为Brand对象BrandbrandJSON。parseObject(params,Brand。class);2。调用service添加brandService。add(brand);3。响应成功的标识response。getWriter()。write(success);}OverrideprotectedvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{this。doGet(request,response);}}
  我们可以注意到其过程非常繁琐,因为我们需要获取参数并进行类型转换,包括添加至Service等过程
  但是SpringMVC秉承着简化代码的原则,将大部分内容转化为Java代码进行封装,大大减少了繁琐的过程
  接下来我们来介绍SpringMVC版:导入jar包?xmlversion1。0encodingUTF8?projectxmlnshttp:maven。apache。orgPOM4。0。0xmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:maven。apache。orgPOM4。0。0http:maven。apache。orgxsdmaven4。0。0。xsdmodelVersion4。0。0modelVersiongroupIdcom。itheimagroupIdspringmvc01quickstartartifactIdversion1。0SNAPSHOTversionpackagingwarpackagingdependencies!servlet坐标dependencygroupIdjavax。servletgroupIdjavax。servletapiartifactIdversion3。1。0versionscopeprovidedscopedependency!SpringMVC坐标dependencygroupIdorg。springframeworkgroupIdspringwebmvcartifactIdversion5。2。10。RELEASEversiondependencydependencies!Tomcat配置buildpluginsplugingroupIdorg。apache。tomcat。mavengroupIdtomcat7mavenpluginartifactIdversion2。1versionconfigurationport80portpathpathconfigurationpluginpluginsbuildproject创建SpringMVC控制类(等同于Servlet类)packagecom。itheima。importorg。springframework。stereotype。Cimportorg。springframework。web。bind。annotation。RequestMimportorg。springframework。web。bind。annotation。ResponseB定义表现层控制器beanControllerpublicclassUserController{设置映射路径为save,即外部访问路径RequestMapping(save)设置当前操作返回结果为指定json数据(本质上是一个字符串信息)ResponseBodypublicStringsave(){System。out。println(usersave。。。);return{info:springmvc};}设置映射路径为delete,即外部访问路径RequestMapping(delete)ResponseBodypublicStringdelete(){System。out。println(usersave。。。);return{info:springmvc};}}初始化SpringMVC环境(同Spring一样创建Config配置Java类)packagecom。itheima。importorg。springframework。context。annotation。ComponentSimportorg。springframework。context。annotation。Cspringmvc配置类,本质上还是一个spring配置类ConfigurationComponentScan(com。itheima。controller)publicclassSpringMvcConfig{}初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC技术处理的请求我们服务层的实际操作都是放置于Servlet容器中我们配置的SpringMVC和Spring环境都是用于服务层,所以我们需要把相关Config加载仅Servlet容器中packagecom。itheima。importorg。springframework。web。context。WebApplicationCimportorg。springframework。web。context。support。AnnotationConfigWebApplicationCimportorg。springframework。web。servlet。support。AbstractDispatcherServletIweb容器配置类AbstractDispatcherServletInitializer是SpringMVC为我们设置好的类,继承并实现相关方法即可publicclassServletContainersInitConfigextendsAbstractDispatcherServletInitializer{加载springmvc配置类,产生springmvc容器(本质还是spring容器)protectedWebApplicationContextcreateServletApplicationContext(){初始化WebApplicationContext对象AnnotationConfigWebApplicationContextctxnewAnnotationConfigWebApplicationContext();加载指定配置类ctx。register(SpringMvcConfig。class);}设置由springmvc控制器处理的请求映射路径protectedString〔〕getServletMappings(){returnnewString〔〕{};}加载spring配置类protectedWebApplicationContextcreateRootApplicationContext(){}}
  我们对上述新的内容进行解析:Controller名称:Controller类型:类注解位置:SpringMVC控制类定义上方作用:设定SpringMVC的核心控制器BeanRequestMapping名称:RequestMapping类型:方法注解位置:SpringMVC控制器方法定义上方作用:设置当前控制器方法请求访问路径相关属性:value(请求访问路径)ResponseBody名称:ResponseBody类型:方法注释位置:SpringMVC控制器方法定义上方作用:设置当前控制器方法响应内容为当前返回值,无需解析AbstractDispatcherServletInitializer类AbstractDispatcherServletInitializer是SpringMVC提供的快速初始化Web3。0容器的抽象类AbstractDispatcherServletInitializer提供三个接口方法供用户实现createServletApplicationContext方法用于创建Servlet容器时,加载SpringMVC对应的Bean并放入AnnotationConfigWebApplicationContext的作用范围对应整个Web容器范围,必须使用WebApplicationcontext类型
  最后我们总结一下上述操作的出现频率:一次性工作创建工程,设置服务器,加载工程导入坐标创建Web容器启动类,加载SpringMVC配置,并设置SpringMVC请求拦截路径SpringMVC核心配置类(设置配置类,扫描controller包,加载Controller控制器Bean)常态工作定义处理请求的控制类定义处理请求的操作方法,并设置映射路径(RequestMapper)与返回Json数据(ResponseBody)SpringMVC工作流程
  在分析SpringMVC工作流程前,我们需要知道服务层是由下面的框架组成的:
  启动服务器初始化过程:服务器启动,执行ServletContainersInitConfig类,初始化Web容器执行createServletApplicationContext方法,创建了WebApplicationContext对象加载SpringMvcConfig执行ComponentScan加载对应的bean加载UserController,每个RequestMapping的名称对应一个具体的方法执行getServletMappings方法,定义所有的请求都通过SpringMVC
  单次请求过程:发送请求localhostsaveWeb容器发现所有请求都经过SpirngMVC,将请求交给SpringMVC处理解析请求路径save由save匹配执行对应的方法save()执行save()检测到有ResponseBody直接将save()方法的返回值作为响应求体返回给请求方SpringMVC加载控制
  在学习SpringMVC之后,我们的Bean的范围逐渐变大:SpringMVC相关bean(表现层bean)Spring相关bean(业务层Service,功能DataSource等)
  但是我们在使用时,需要区分相关bean的导入路径:SpringMVC加载的bean对应的包均在com。itheima。controller包内Spring加载的bean却包含有多个文件夹
  因而我们给出两种方法来解决Spring的扫描问题:Spring加载的bean设定范围为com。itheima,并排除掉controller包内的beanpackagecom。itheima。importorg。springframework。context。annotation。ComponentSimportorg。springframework。context。annotation。Cimportorg。springframework。context。annotation。FilterTimportorg。springframework。stereotype。CConfigurationComponentScan注解设置扫描范围ComponentScan中包含有value,excludeFilters属性value:用于控制扫描范围excludeFilters:用于控制排除范围,需要采用ComponentScan。Filter过滤器type:设置排除规则,当前使用按照bean定义时的注解类型进行排除classes属性:设置排除的具体注解类,当前设置排除Controller定义的beanComponentScan(valuecom。itheima,excludeFiltersComponentScan。Filter(typeFilterType。ANNOTATION,classesController。class))publicclassSpringConfig{}这里做一个小补充内容:ComponentScan中除了excludeFilters,还包括有includeFiltersincludeFilters:加载指定的bean,需要指定类型(type)和具体项(classes)Spring加载的bean设定范围为精准范围,例如service包,dao包等packagecom。itheima。importorg。springframework。context。annotation。ComponentSimportorg。springframework。context。annotation。Cimportorg。springframework。context。annotation。FilterTimportorg。springframework。stereotype。CConfigurationComponentScan({com。itheima。service,com。itheima。dao})publicclassSpringConfig{}Servlet容器简化写法
  我们的Servlet容器中可以定义Spring和SpringMVC的配置文件packagecom。itheima。importorg。springframework。web。context。WebApplicationCimportorg。springframework。web。context。support。AnnotationConfigWebApplicationCimportorg。springframework。web。servlet。support。AbstractAnnotationConfigDispatcherServletIimportorg。springframework。web。servlet。support。AbstractDispatcherServletIpublicclassServletContainersInitConfigextendsAbstractDispatcherServletInitializer{配置SpringMVC配置文件protectedWebApplicationContextcreateServletApplicationContext(){AnnotationConfigWebApplicationContextctxnewAnnotationConfigWebApplicationContext();ctx。register(SpringMvcConfig。class);}配置Spring配置文件protectedWebApplicationContextcreateRootApplicationContext(){AnnotationConfigWebApplicationContextctxnewAnnotationConfigWebApplicationContext();ctx。register(SpringConfig。class);}配置拦截路径protectedString〔〕getServletMappings(){returnnewString〔〕{};}}我们可以注意到:
  Spring和SpringMVC导入方法中均采用AnnotationConfigWebApplicationContext来创建对象
  两者之间的区别仅仅是class包的不同
  Spring给了我们一种新的继承类用于简化开发:packagecom。itheima。importorg。springframework。web。context。WebApplicationCimportorg。springframework。web。context。support。AnnotationConfigWebApplicationCimportorg。springframework。web。servlet。support。AbstractAnnotationConfigDispatcherServletIimportorg。springframework。web。servlet。support。AbstractDispatcherServletIweb配置类简化开发,仅设置配置类类名即可publicclassServletContainersInitConfigextendsAbstractAnnotationConfigDispatcherServletInitializer{protectedC?〔〕getRootConfigClasses(){returnnewClass〔〕{SpringConfig。class};}protectedC?〔〕getServletConfigClasses(){returnnewClass〔〕{SpringMvcConfig。class};}protectedString〔〕getServletMappings(){returnnewString〔〕{};}}注意:
  AbstractAnnotationConfigDispatcherServletInitializer是createServletApplicationContext的继承类
  我们同样继承它的三个方法,但这次我们只需要在里面标明相关类和路径即可常用工具推荐Postman
  在我们的SpringMVC中岔开一个话题:关于我们的网页调试的复杂性
  我们在一个网页开发中,会不断的调试网页,通过各种路径反复查询或者采用不同的访问方式(GETPOST)
  如果我们采用正常的网页进行测试,无疑会出现非常麻烦的步骤
  所以我们推荐采用Postman软件,下面我们将会简单做一下介绍Postman链接
  首先为大家附上链接:下载链接:DownloadPostman(getpostman。com)文档链接:PostMan中文文档整合链接:ApipostAPI文档、设计、调试、自动化测试一体化协作平台Postman操作讲解
  在了解操作前,我们需要明白Postman的作用:用于分类存储网页请求用于发送请求进行测试
  关于安装注册的过程我们不再赘述Postman页面展示
  我们先来查看Postman的主页:
  首先我们可以看到左上角的Workspaces,这个是最大的分类空间
  我们可以看到左上角SpringMVC,这是我所创建的WorkSpaces,关于我在SpringMVC所做的网页测试部分将都在这里进行
  除此之外,我们可以看到右侧的DEMO1,以及内部的测试用例文件夹,以及项目save
  以上就是我们的Postman的基本页面Postman具体使用
  我们的Postman的具体使用流程如下:创建新的Workspaces
  选定主界面,创建对应文件夹
  创建项目(点击中间区域的加号)
  书写项目内容(GET可以更换其他类型,后面书写URL,下方key,value书写传递数据)
  下方的数据传递可以更换类型,例如更换为body体的raw来书写JSON格式
  书写后保存到相应列表并标注名称
  到这里,我们Postman的基本使用基本就结束了,到后面我们会对具体内容做具体补充SpringMVC设置请求与响应
  SpringMVC和Servlet同属于服务层的工具,那么必不可少的就是请求与响应的反馈问题
  接下来我们将一一介绍请求与响应的相关知识请求映射路径设置
  首先我们先来想一想我们之前的路径设置是否有那么一点点缺陷?Book的服务层packagecom。itheima。importorg。springframework。stereotype。Cimportorg。springframework。web。bind。annotation。RequestMimportorg。springframework。web。bind。annotation。ResponseBControllerpublicclassBookController{请求路径映射RequestMapping(save)ResponseBodypublicStringsave(){System。out。println(booksave。。。);return{module:booksave};}}User的服务层packagecom。itheima。importorg。springframework。stereotype。Cimportorg。springframework。web。bind。annotation。RequestMimportorg。springframework。web。bind。annotation。RequestPimportorg。springframework。web。bind。annotation。ResponseBControllerpublicclassUserController{请求路径映射RequestMapping(save)ResponseBodypublicStringsave(){System。out。println(usersave。。。);return{module:usersave};}请求路径映射RequestMapping(delete)ResponseBodypublicStringdelete(){System。out。println(userdelete。。。);return{module:userdelete};}}
  我们可以注意到我们的单个项目中不可能只包括有一个服务层
  但我们的请求映射路径却只是简单设计为相同的名称,就会导致我们访问该页面时,系统无法匹配
  所以我们需要给他们采用不同的映射路径,我们常有的操作是直接在前面加上一层该类的路径名:packagecom。itheima。importorg。springframework。stereotype。Cimportorg。springframework。web。bind。annotation。RequestMimportorg。springframework。web。bind。annotation。ResponseBControllerpublicclassBookController{请求路径映射RequestMapping(booksave)ResponseBodypublicStringsave(){System。out。println(booksave。。。);return{module:booksave};}}
  但当项目逐渐增多,我们多次书写路径名就有可能导致错误,所以我们采用类注解RequestMapping来解决:packagecom。itheima。importorg。springframework。stereotype。Cimportorg。springframework。web。bind。annotation。RequestMimportorg。springframework。web。bind。annotation。RequestPimportorg。springframework。web。bind。annotation。ResponseBController类上方配置的请求映射与方法上面配置的请求映射连接在一起,形成完整的请求映射路径RequestMapping(user)publicclassUserController{请求路径映射RequestMapping(save)ResponseBodypublicStringsave(){System。out。println(usersave。。。);return{module:usersave};}请求路径映射RequestMapping(delete)ResponseBodypublicStringdelete(){System。out。println(userdelete。。。);return{module:userdelete};}}
  注意:RequestMapping不仅仅可以用于方法表示映射,也可以用于整个Bean类中表示映射前缀参数传递问题
  关于参数传递我们从三个方面来讲解:传递方式传递参数类型特殊参数类型按传递方式
  我们的传递方式通常采用GET或者POST方式
  但在前面的学习中我们可以知道我们的传递方式是有不同的,我们在Postman的书写形式也是不同的
  例如我们先给出一个简单的参数传递函数packagecom。itheima。importcom。itheima。domain。Uimportorg。springframework。format。annotation。DateTimeFimportorg。springframework。stereotype。Cimportorg。springframework。web。bind。annotation。RequestBimportorg。springframework。web。bind。annotation。RequestMimportorg。springframework。web。bind。annotation。RequestPimportorg。springframework。web。bind。annotation。ResponseBimportjava。util。Aimportjava。util。Dimportjava。util。L请求参数ControllerpublicclassUserController{普通参数:请求参数与形参名称对应即可完成参数传递RequestMapping(commonParam)ResponseBodypublicStringcommonParam(Stringname,intage){System。out。println(普通参数传递namename);System。out。println(普通参数传递ageage);return{module:commonparam};}}
  我们的GET方式直接在网页后用?和来书写传递参数:
  我们的POST方式只能在下方的body中书写参数:
  然后我们需要注意到的是这里的中文同样会出现乱码行为
  这次我们选择在ServletContainersInitConfig中处理数据:下述代码基本属于我们创建项目的固定代码packagecom。itheima。importorg。springframework。web。filter。CharacterEncodingFimportorg。springframework。web。servlet。support。AbstractAnnotationConfigDispatcherServletIimportjavax。servlet。FpublicclassServletContainersInitConfigextendsAbstractAnnotationConfigDispatcherServletInitializer{protectedC?〔〕getRootConfigClasses(){returnnewClass〔0〕{SpringConfig。class};}protectedC?〔〕getServletConfigClasses(){returnnewClass〔〕{SpringMvcConfig。class};}protectedString〔〕getServletMappings(){returnnewString〔〕{};}乱码处理OverrideprotectedFilter〔〕getServletFilters(){CharacterEncodingFilter属于处理中文编码的过滤器,我们直接创建即可(一次性操作)CharacterEncodingFilterfilternewCharacterEncodingFilter();filter。setEncoding(UTF8);returnnewFilter〔〕{filter};}}按参数方式
  我们按参数来分类主要分为五种:普通参数POJO类嵌套式POJO类数组参数集合参数
  我们下面来一一介绍普通参数
  普通参数:请求参数和形参变量名相同时,自动匹配packagecom。itheima。importcom。itheima。domain。Uimportorg。springframework。format。annotation。DateTimeFimportorg。springframework。stereotype。Cimportorg。springframework。web。bind。annotation。RequestBimportorg。springframework。web。bind。annotation。RequestMimportorg。springframework。web。bind。annotation。RequestPimportorg。springframework。web。bind。annotation。ResponseBimportjava。util。Aimportjava。util。Dimportjava。util。L请求参数ControllerpublicclassUserController{普通参数:请求参数与形参名称对应即可完成参数传递RequestMapping(commonParam)ResponseBodypublicStringcommonParam(Stringname,intage){System。out。println(普通参数传递namename);System。out。println(普通参数传递ageage);return{module:commonparam};}}
  Postman操作:
  这里需要注意:当请求参数名与形参名不同时,使用RequestParam注解关联请求参数名称与形参名称之间的关系packagecom。itheima。importcom。itheima。domain。Uimportorg。springframework。format。annotation。DateTimeFimportorg。springframework。stereotype。Cimportorg。springframework。web。bind。annotation。RequestBimportorg。springframework。web。bind。annotation。RequestMimportorg。springframework。web。bind。annotation。RequestPimportorg。springframework。web。bind。annotation。ResponseBimportjava。util。Aimportjava。util。Dimportjava。util。L请求参数ControllerpublicclassUserController{普通参数:请求参数名与形参名不同时,使用RequestParam注解关联请求参数名称与形参名称之间的关系RequestMapping(commonParamDifferentName)ResponseBodypublicStringcommonParamDifferentName(RequestParam(name)StringuserName,intage){System。out。println(普通参数传递userNameuserName);System。out。println(普通参数传递ageage);return{module:commonparamdifferentname};}}
  Postman操作:
  RequestParam:绑定请求参数与处理器方法形参间的关系
  包含有两个参数
  required:是否为必传参数
  defaultValue:参数默认值POJO参数
  POJO参数:请求参数名与形参对象属性名相同,定义POJO类型形参即可接收参数packagecom。itheima。importcom。itheima。domain。Uimportorg。springframework。format。annotation。DateTimeFimportorg。springframework。stereotype。Cimportorg。springframework。web。bind。annotation。RequestBimportorg。springframework。web。bind。annotation。RequestMimportorg。springframework。web。bind。annotation。RequestPimportorg。springframework。web。bind。annotation。ResponseBimportjava。util。Aimportjava。util。Dimportjava。util。L请求参数ControllerpublicclassUserController{POJO参数:请求参数与形参对象中的属性对应即可完成参数传递RequestMapping(pojoParam)ResponseBodypublicStringpojoParam(Useruser){System。out。println(pojo参数传递useruser);return{module:pojoparam};}}
  Postman操作:
  嵌套POJO参数
  嵌套POJO参数:请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套POJO属性参数packagecom。itheima。importcom。itheima。domain。Uimportorg。springframework。format。annotation。DateTimeFimportorg。springframework。stereotype。Cimportorg。springframework。web。bind。annotation。RequestBimportorg。springframework。web。bind。annotation。RequestMimportorg。springframework。web。bind。annotation。RequestPimportorg。springframework。web。bind。annotation。ResponseBimportjava。util。Aimportjava。util。Dimportjava。util。L请求参数ControllerpublicclassUserController{嵌套POJO参数:嵌套属性按照层次结构设定名称即可完成参数传递RequestMapping(pojoContainPojoParam)ResponseBodypublicStringpojoContainPojoParam(Useruser){System。out。println(pojo嵌套pojo参数传递useruser);return{module:pojocontainpojoparam};}}
  Postman操作:
  数组参数
  数组参数:请求参数名与形参对象属性名相同且请求参数为多个,定义数组类型形参即可接收参数packagecom。itheima。importcom。itheima。domain。Uimportorg。springframework。format。annotation。DateTimeFimportorg。springframework。stereotype。Cimportorg。springframework。web。bind。annotation。RequestBimportorg。springframework。web。bind。annotation。RequestMimportorg。springframework。web。bind。annotation。RequestPimportorg。springframework。web。bind。annotation。ResponseBimportjava。util。Aimportjava。util。Dimportjava。util。L请求参数ControllerpublicclassUserController{数组参数:同名请求参数可以直接映射到对应名称的形参数组对象中RequestMapping(arrayParam)ResponseBodypublicStringarrayParam(String〔〕likes){System。out。println(数组参数传递likesArrays。toString(likes));return{module:arrayparam};}}
  Postman操作:
  集合保存普通参数
  集合保存普通参数:请求参数与形参集合对象名相同且请求参数为多个,RequestParam绑定参数关系packagecom。itheima。importcom。itheima。domain。Uimportorg。springframework。format。annotation。DateTimeFimportorg。springframework。stereotype。Cimportorg。springframework。web。bind。annotation。RequestBimportorg。springframework。web。bind。annotation。RequestMimportorg。springframework。web。bind。annotation。RequestPimportorg。springframework。web。bind。annotation。ResponseBimportjava。util。Aimportjava。util。Dimportjava。util。L请求参数ControllerpublicclassUserController{集合参数:同名请求参数可以使用RequestParam注解映射到对应名称的集合对象中作为数据RequestMapping(listParam)ResponseBodypublicStringlistParam(RequestParamListStringlikes){System。out。println(集合参数传递likeslikes);return{module:listparam};}}
  Postman参数:
  按特殊参数方式
  我们的特殊参数主要介绍两种:JSON类型日期类型
  我们下面一一介绍JSON类型
  JSON类型是我们Web开发中最常用的类型,所以这一部分算是一个小重点
  我们将一一讲解JSON类型传递的步骤:导入JSON坐标?xmlversion1。0encodingUTF8?projectxmlnshttp:maven。apache。orgPOM4。0。0xmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:maven。apache。orgPOM4。0。0http:maven。apache。orgxsdmaven4。0。0。xsdmodelVersion4。0。0modelVersiongroupIdcom。itheimagroupIdspringmvc04requestparamartifactIdversion1。0SNAPSHOTversionpackagingwarpackagingdependenciesdependencygroupIdjavax。servletgroupIdjavax。servletapiartifactIdversion3。1。0versionscopeprovidedscopedependencydependencygroupIdorg。springframeworkgroupIdspringwebmvcartifactIdversion5。2。10。RELEASEversiondependency!JSON坐标dependencygroupIdcom。fasterxml。jackson。coregroupIdjacksondatabindartifactIdversion2。9。0versiondependencydependenciesbuildpluginsplugingroupIdorg。apache。tomcat。mavengroupIdtomcat7mavenpluginartifactIdversion2。1versionconfigurationport80portpathpathconfigurationpluginpluginsbuildproject在SpringMVC配置类中添加JSON类型转换注解packagecom。itheima。importorg。springframework。context。annotation。ComponentSimportorg。springframework。context。annotation。Cimportorg。springframework。web。filter。CharacterEncodingFimportorg。springframework。web。servlet。config。annotation。EnableWebMimportjavax。servlet。Fimportjavax。servlet。annotation。WebFConfigurationComponentScan(com。itheima。controller)开启json数据类型自动转换EnableWebMvcpublicclassSpringMvcConfig{}在Controller中书写相关Web代码(注意:需要使用RequestBody表示将请求体数据传递给请求参数)packagecom。itheima。importcom。itheima。domain。Uimportorg。springframework。format。annotation。DateTimeFimportorg。springframework。stereotype。Cimportorg。springframework。web。bind。annotation。RequestBimportorg。springframework。web。bind。annotation。RequestMimportorg。springframework。web。bind。annotation。RequestPimportorg。springframework。web。bind。annotation。ResponseBimportjava。util。Aimportjava。util。Dimportjava。util。L请求参数ControllerpublicclassUserController{集合参数:json格式1。开启json数据格式的自动转换,在配置类中开启EnableWebMvc2。使用RequestBody注解将外部传递的json数组数据映射到形参的集合对象中作为数据RequestMapping(listParamForJson)ResponseBodypublicStringlistParamForJson(RequestBodyListStringlikes){System。out。println(listcommon(json)参数传递listlikes);return{module:listcommonforjsonparam};}POJO参数:json格式1。开启json数据格式的自动转换,在配置类中开启EnableWebMvc2。使用RequestBody注解将外部传递的json数据映射到形参的实体类对象中,要求属性名称一一对应RequestMapping(pojoParamForJson)ResponseBodypublicStringpojoParamForJson(RequestBodyUseruser){System。out。println(pojo(json)参数传递useruser);return{module:pojoforjsonparam};}集合参数:json格式1。开启json数据格式的自动转换,在配置类中开启EnableWebMvc2。使用RequestBody注解将外部传递的json数组数据映射到形参的保存实体类对象的集合对象中,要求属性名称一一对应RequestMapping(listPojoParamForJson)ResponseBodypublicStringlistPojoParamForJson(RequestBodyListUserlist){System。out。println(listpojo(json)参数传递listlist);return{module:listpojoforjsonparam};}}
  Postman操作:
  在上面我们有两个注解需要特别注意一下:EnableWebMvc名称:EnableWebMvc类型:配置类注解位置:SpringMVC配置类定义上方作用:开启SpringMVC多项辅助功能RequestBody名称:RequestBody类型:形参注解位置:SpringMVC控制器方法形参定义前面作用:将请求中请求体所包含的数据传递给请求参数,此注解一个处理器方法只能使用一次RequestBody和RequestParam区别
  区别RequestParam用于接收url地址传参,表单传参〔applicationxwwwformurlencoded〕RequestBody用于接收JSON数据〔applicationjson〕应用后期开发中,发送json数据为主,RequestBody应用较广如果发送非json格式数据,选用RequestParam接收请求参数日期型参数类型
  我们的日期类型数据基于系统不同格式也不相同,大致有以下几种:202210052022100510052022
  接收形参时,我们根据不同的日期格式设置不同的接收方式packagecom。itheima。importcom。itheima。domain。Uimportorg。springframework。format。annotation。DateTimeFimportorg。springframework。stereotype。Cimportorg。springframework。web。bind。annotation。RequestBimportorg。springframework。web。bind。annotation。RequestMimportorg。springframework。web。bind。annotation。RequestPimportorg。springframework。web。bind。annotation。ResponseBimportjava。util。Aimportjava。util。Dimportjava。util。L请求参数ControllerpublicclassUserController{日期参数使用DateTimeFormat注解设置日期类型数据格式,默认格式yyyyMMddRequestMapping(dataParam)ResponseBodypublicStringdataParam(Datedate,DateTimeFormat(patternyyyyMMdd)Datedate1,DateTimeFormat(patternyyyyMMddHH:mm:ss)Datedate2){System。out。println(参数传递datedate);System。out。println(参数传递date1(yyyyMMdd)date1);System。out。println(参数传递date2(yyyyMMddHH:mm:ss)date2);return{module:dataparam};}}名称:DateTimeFormat类型:形参注解位置:SpringMVC控制器方法前作用:设定日期时间型数据格式属性:pattern:日期时间格式字符串
  Postman操作:
  这里我们简单介绍一下DateTimeFormat的转换原理Converter接口:publicinterfaceConverterS,T{NullableTconvert(Svar1)}
  Converter接口属于顶层接口,由它为起源创建了许多相关的接口与类用于各种转化:请求参数年龄数据(StringInteger)日期格式转发(StringDate)
  EnableWebMvc功能之一:根据类型匹配对应的类型转换器设置响应
  在了解请求的相关知识之后,我们回到Controller代码中学习一下响应跳转响应
  在正常情况下,我们的响应给出的是当前项目的文档,相当于页面的跳转效应:packagecom。itheima。importcom。itheima。domain。Uimportorg。springframework。format。annotation。DateTimeFimportorg。springframework。stereotype。Cimportorg。springframework。web。bind。annotation。RequestMimportorg。springframework。web。bind。annotation。ResponseBimportjava。util。ArrayLimportjava。util。Dimportjava。util。LControllerpublicclassUserController{响应页面跳转页面返回值为String类型,设置返回值为页面名称,即可实现页面跳转RequestMapping(toJumpPage)publicStringtoJumpPage(){System。out。println(跳转页面);returnpage。}}信息响应
  如果我们希望得到一些信息响应,就需要采用注解解释:packagecom。itheima。importcom。itheima。domain。Uimportorg。springframework。format。annotation。DateTimeFimportorg。springframework。stereotype。Cimportorg。springframework。web。bind。annotation。RequestMimportorg。springframework。web。bind。annotation。ResponseBimportjava。util。ArrayLimportjava。util。Dimportjava。util。LControllerpublicclassUserController{响应文本数据返回值为String类型,设置返回值为任意字符串信息,即可实现返回指定字符串信息,需要依赖ResponseBody注解RequestMapping(toText)ResponseBodypublicStringtoText(){System。out。println(返回纯文本数据);}响应POJO对象返回值为实体类对象,设置返回值为实体类类型,即可实现返回对应对象的json数据,需要依赖ResponseBody注解和EnableWebMvc注解RequestMapping(toJsonPOJO)ResponseBodypublicUsertoJsonPOJO(){System。out。println(返回json对象数据);UserusernewUser();user。setName(itcast);user。setAge(15);}响应POJO集合对象返回值为集合对象,设置返回值为集合类型,即可实现返回对应集合的json数组数据,需要依赖ResponseBody注解和EnableWebMvc注解RequestMapping(toJsonList)ResponseBodypublicListUsertoJsonList(){System。out。println(返回json集合数据);Useruser1newUser();user1。setName(传智播客);user1。setAge(15);Useruser2newUser();user2。setName(黑马程序员);user2。setAge(12);ListUseruserListnewArrayListUser();userList。add(user1);userList。add(user2);returnuserL}}名称:ResponseBody类型:方法注解位置:SpringMVC控制器方法定义上方作用:设置当前控制器返回值作为响应体
  当我们使用Postman访问该链接时就会给出对应反馈,这里就不做演示了REST风格
  首先我们来简单介绍一下REST:REST(RepresentationalStateTransfer),表现形式状态转换
  我们给出正常风格和REST风格两种书写形式,我们可以明显看到REST的内容做出大规模的省略:正常风格:http:localhostusergetById?id1REST风格:http:localhostusers1
  REST风格优点:书写简化隐藏资源的访问行为,无法通过地址得知对资源的操作REST风格简介
  我们来对REST风格做出简单解释:REST风格是采用访问资源的行为动作来区别对资源进行了何种操作
  我们给出五种常见行为动作:http:localhostusers:查看全部用户信息GET(查询)http:localhostusers1:查看指定用户信息GET(查询)http:localhostusers:添加用户信息POST(新增保存)http:localhostusers:修改用户信息PUT(修改更新)http:localhostusers1:删除用户信息DELETE(删除)
  我们通常将根据REST风格进行的访问称为RESTful上述行为是约定方式,约定不是规范,是可以打破的,所以称为REST风格,而不是REST规范
  描述模块的名称通常使用负数,也就是加s的格式描述,表示此类,而非单个资源RESTful入门案例
  从本质上而言,REST只是一种规范形式,我们对于REST的风格修改仅针对于Controller
  我们下面将逐步进行RESTful的修改:设置http请求动作packagecom。itheima。importcom。itheima。domain。Bimportorg。springframework。stereotype。Cimportorg。springframework。web。bind。annotation。;ControllerpublicclassBookController{RequestMapping中包含value和method两种属性value:访问路径method:访问方法RequestMapping(valueusers,methodRequest。POST)RequestBodypublicStringsave(RequestBodyUseruser){System。out。println(usersaveuser);return{module:usersave}}}名称:RequestMapping类型:方法注解位置:SpringMVC控制器方法定义上方作用:设置当前控制器方法请求访问路径属性:value访问路径,method请求动作设置请求参数(路径变量)packagecom。itheima。importcom。itheima。domain。Bimportorg。springframework。stereotype。Cimportorg。springframework。web。bind。annotation。;ControllerpublicclassBookController{首先针对我们所需参数给出PathVariable注解,并在访问路径中采用{}占位表示所传数据简单来说就是,系统根据请求路径,得到所需数据,再带入到方法中RequestMapping(valueusers{id},methodRequestMethod。DELETE)RequestBodypublicStringdelete(PathVariableIntegerid){System。out。println(bookdelete。。。id);return{module:bookdelete};}}名称:PathVariable类型:形参注解位置:SpringMVC控制器方法形参定义前面作用:绑定路径参数与处理器方法形参间的关系,要求路径参数名与形参名一一对应
  下面我们给出所有情况案例:packagecom。itheima。importcom。itheima。domain。Uimportorg。springframework。stereotype。Cimportorg。springframework。web。bind。annotation。;ControllerpublicclassUserController{设置当前请求方法为POST,表示REST风格中的添加操作RequestMapping(valueusers,methodRequestMethod。POST)ResponseBodypublicStringsave(){System。out。println(usersave。。。);return{module:usersave};}设置当前请求方法为DELETE,表示REST风格中的删除操作PathVariable注解用于设置路径变量(路径参数),要求路径上设置对应的占位符,并且占位符名称与方法形参名称相同RequestMapping(valueusers{id},methodRequestMethod。DELETE)ResponseBodypublicStringdelete(PathVariableIntegerid){System。out。println(userdelete。。。id);return{module:userdelete};}设置当前请求方法为PUT,表示REST风格中的修改操作RequestMapping(valueusers,methodRequestMethod。PUT)ResponseBodypublicStringupdate(RequestBodyUseruser){System。out。println(userupdate。。。user);return{module:userupdate};}设置当前请求方法为GET,表示REST风格中的查询操作PathVariable注解用于设置路径变量(路径参数),要求路径上设置对应的占位符,并且占位符名称与方法形参名称相同RequestMapping(valueusers{id},methodRequestMethod。GET)ResponseBodypublicStringgetById(PathVariableIntegerid){System。out。println(usergetById。。。id);return{module:usergetById};}设置当前请求方法为GET,表示REST风格中的查询操作RequestMapping(valueusers,methodRequestMethod。GET)ResponseBodypublicStringgetAll(){System。out。println(usergetAll。。。);return{module:usergetAll};}}下述为原有代码:RequestMappingResponseBodypublicStringdelete(){System。out。println(userdelete。。。);return{module:userdelete};}RequestMappingResponseBodypublicStringupdate(){System。out。println(userupdate。。。);return{module:userupdate};}RequestMappingResponseBodypublicStringgetById(){System。out。println(usergetById。。。);return{module:usergetById};}RequestMappingResponseBodypublicStringgetAll(){System。out。println(usergetAll。。。);return{module:usergetAll};}我们在这里给出RequestBody,RequestParam,PathVariable区别
  区别:
  RequestParam用于接收url地址传参或表单传参RequestBody用于接收json数据PathVariable用于接收路径参数,使用{参数名称}描述路径参数
  应用:
  后期开发中,发送请求参数超过1个时,以json格式为主,RequestBody应用较广如果发送非json格式数据,选用RequestParam接受请求参数采用RESTful进行开发,当参数数量较少时,如1个,可以采用PathVariable接收请求路径变量,常用来传递id值REST快速开发
  我们在上一小节中会发现有许多重复性的代码:每次都填写value,method导致代码繁冗包括每次填写ResponseBody使代码繁冗RequestMapping(valueusers,methodRequestMethod。GET)ResponseBody
  所以我们可以采用一些小技巧来简化代码:将前缀地址和相关注解放于类中:packagecom。itheima。importcom。itheima。domain。Bimportorg。springframework。stereotype。Cimportorg。springframework。web。bind。annotation。;ControllerResponseBodyRestControllerRequestMapping(books)publicclassBookController{}正常情况下,我们的类本身具有Controller,并且为了省略类中的ResponseBody而直接标注在类头但Spring提供了一种新的注解RestController,相当于Controller和ResponseBody的结合,我们只需要书写这一个注解即可名称:RestController类型:类注解位置:基于SpringMVC的RESTful开发控制器类定义上方作用:设置当前控制器为RESTful风格,等同于Controller与ResponseBody两个注解组合功能采用新的地址注解代替老注解:packagecom。itheima。importcom。itheima。domain。Bimportorg。springframework。stereotype。Cimportorg。springframework。web。bind。annotation。;RestControllerRequestMapping(books)publicclassBookController{RequestMapping(methodRequestMethod。POST)使用PostMapping简化Post请求方法对应的映射配置PostMappingpublicStringsave(RequestBodyBookbook){System。out。println(booksave。。。book);return{module:booksave};}RequestMapping(value{id},methodRequestMethod。DELETE)使用DeleteMapping简化DELETE请求方法对应的映射配置DeleteMapping({id})publicStringdelete(PathVariableIntegerid){System。out。println(bookdelete。。。id);return{module:bookdelete};}RequestMapping(methodRequestMethod。PUT)使用PutMapping简化Put请求方法对应的映射配置PutMappingpublicStringupdate(RequestBodyBookbook){System。out。println(bookupdate。。。book);return{module:bookupdate};}RequestMapping(value{id},methodRequestMethod。GET)使用GetMapping简化GET请求方法对应的映射配置GetMapping({id})publicStringgetById(PathVariableIntegerid){System。out。println(bookgetById。。。id);return{module:bookgetById};}RequestMapping(methodRequestMethod。GET)使用GetMapping简化GET请求方法对应的映射配置GetMappingpublicStringgetAll(){System。out。println(bookgetAll。。。);return{module:bookgetAll};}}名称:GetMappingPostMappingPutMappingDeleteMapping类型:方法注解位置:基于SpringMVC的RESTful开发控制器方法定义上方作用:设置当前控制器方法请求访问路径与请求动作,每种对应一个请求动作,例如GetMapping对应GET请求参数:value请求访问路径结束语
  好的,关于SpringMVC的内容就介绍到这里,希望能为你带来帮助!
投诉 评论

55岁郑海霞现状?现身校园,承担新职务,入选名人堂是最好回报尽管现在可能很多人都不记得,但在中国女篮的历史上,有一个时代叫做郑海霞时代,经历过那一个时代的球迷们,无疑对郑海霞留有极为深刻的印象。在球迷们心里,郑海霞是中国女篮的黄金……重庆南川山王坪层林尽染秋色醉人说起重庆南川山王坪喀斯特国家生态公园广为人知的景观就是无人机视角下的双色林海景观:园内小公路蜿蜒曲折,其两侧的柳杉林(绿色林海)和水杉林(金色林海)泾渭分明,如同巨大的调色盘,……售价37万?iPhone13Pro系列名表定制版发布,18K俄罗斯奢侈品牌Caviar在国内小有名气,每年都会推出定制版苹果手机,通常会以纯金、珠宝、钻石等贵重材料作为基材,价格普遍在几十万元左右。根据官网消息显示,最新推出iPhone……喧软香甜的烫面小糖饼咬一口,流动的糖心,甜滋滋的!好美味伙计们好好好!今日早餐分享烫面小糖饼!即是早餐,也是甜点。食材:面粉250g、开水170ml、白糖做法:1、盆中放入面粉,倒入开水搅拌……真正的难过,是说不出口的1hr你有没有过这样的瞬间:身体一直在佯装平静地忙碌着,心却阵阵抽痛。你知道自己是个成年人了,早已丧失任性的资格,再难过,也要把该做的事做完。可无助的感觉还是……爱沙尼亚后卫东契奇打球很容易上头他会被自己的情绪影响直播吧8月27日讯在此前斯洛文尼亚和爱沙尼亚的世预赛中,斯洛文尼亚后卫东契奇和爱沙尼亚后卫科尔克里萨在场上发生了一些小冲突。赛后,克里萨在接受采访时说道:东契奇打球很容易……牛啊!终于有人把主流服务层框架SpringMVC讲明白了SpringMVC简介首先我们先来简单了解一下SpringMVC:SpringMVC是一种基于Java实现MVC模型的轻量级Web框架SpringMVC致力于服务层,同S……飞凡ER6续航620km,充电15分钟续航200KM作为新能源汽车,续航里程和充电速度决定了她的活动范围和便利程度,这也是很多消费者在购买新能源汽车时考虑更多的地方,毕竟随着气候变化和复杂的路面情况下,续航里程的缩减的在所难免的……2022年家里还有必要买电视吗?彩电以前还是所谓的三大件之一,三大件包括彩电、冰箱和洗衣机。没想到,也就过了二三十年,已经有还有必要买电视吗?这种问题出现了。但我其实相当理解题主,包括我自己,很多……呼吸哥直播回应冰心剑姬那把天肥剑姬输了就是我的问题对于LPL赛区来说,今年的世界赛成绩确实是未能尽如人意,四支出征世界赛的队伍都没有取得很好的成绩,一号种子JDG遗憾折戟于四强、二号种子TES止步十六强、三号种子EDG和四号种……散文安于当下美好,浅秋来日方长作者:子墨秋天,总是适合一个人随处走走,看看风景,感受秋天独特的风景,无需远游,远山近水已经足够让你感悟。或是,足不出户,打开窗户,在一处幽静里,感受秋风入窗,带来……一个五十女人的心路历程作为一个女人到了五十岁的年龄,真的有惶恐,有失落,有遗憾,有迷茫。惶恐的是我们正在迈向愈来愈老的路途上,回首再看前几十年的岁月真的觉得恍然如梦一场,前半生的点点滴滴仿佛还……
ampampquot你长大想当什么?ampampquotam詹姆斯若能拿到4万分,和乔丹10个得分王相比,哪一个难度更大做一个快乐的自己CBA三消息山西有意NBA级后卫,刘维伟带队首练,林书豪开启王嘉尔,继成龙后,又一位在国际爆红的中国巨星!兔乐新春游红河长街宴花山节烟花秀今年春节不愁没地去穷人与富人有过多的可比性吗?那我一天挣那么一点,我就是穷人?王者荣耀万暴流伽罗火了,普攻100暴击,铭文出装是关键高诗岩表现绝对值顶薪!三外援打单外援没优势,12人名单竞争激三伏天,建议少喝冷饮,多喝3种花茶,解暑又营养,清爽过炎夏你知道如何正确抗衰吗?美莱分享皮肤抗衰的秘诀25分6助,勇士输给湖人,进退两难!科尔给出答案,受伤的是库几回造句用几回造句大全挖野菜350字小学作文罗马皇帝尼禄男皇后是怎么回事揭秘罗马帝国荒婬皇帝稀哩哗啦。日子经常喝乌龙茶对身体的好处跟坏处有什么梦里的小天使五分钟带你了解古埃及神话故事,了解神明们的爱恨情仇(一)双子ab(双子ab女的魅力)根据规定二手房交易税有哪些远望谷董秘回复无法知悉北京延庆和张家口的高铁上是否使用了我司三侠五义是哪几个人三侠五义中的三侠是谁五义又是谁独特有个性的苏姓女孩名字精选

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找七猫云易事利