首页>>后端>>java->springmvc前后端分离?

springmvc前后端分离?

时间:2023-12-01 本站 点击:0

对于前后端分离项目,还适合使用springmvc吗

不知道你说的前后端分离

是指前后端有关系分开来开发

还是洞唤指前后端没有关系

如果是前后端有关系分开开发

Spring MVC适合使用

如迟培果前后端没有码颤唯关系

可以考虑使用其它技术或方式实现

Spring MVC 面试总结

SpringMVC的核心就是DispatcherServlet,DispatcherServlet实质也是一个HttpServlet,继承 了FrameworkServlet,实现 ApplicationContextAware 接口,继承 HttpServletBean 抽象类 , 负责初始化 Spring Servlet WebApplicationContext 容器,同时该类覆写了 doGet、doPost 等方法,并将所有类型的请求委托给 doService 方法去处理,doService 是一个抽象方法,需要子类实现,DispatcherServlet负责初始化 Spring MVC 的各个组件,以及处理客户端的请求,协调各个组件工作

WebApplicationContext 是实现 ApplicationContext 接口的子类,专门为 WEB 应用准备的

它允许从相对于 Web 根目录的路径中加载配置文件,完成初始化 Spring MVC 组件的工作。

从 WebApplicationContext 中,可以获取 ServletContext 引用,整个 Web 应用上下文对象将作为属性放置在 ServletContext 中,以便 Web 应用环境可以访问 Spring 上下文。

ContextLoaderListener 继承 ContextLoader 类,实现 Servlet 容器启动和关闭时,分别初始化和销核悄毁 WebApplicationContext 容器,WebApplicationContext 有两处

 Servlet 3.0 新增的一个接口ServletContainerInitializer ,配合@HandlesTypes 注解来指定希望被处理的类,容器在启动时使用 JAR 服务 的时候会通过SPI机制发现 ServletContainerInitializer 的实现类,并且容器将 WEB-INF/lib 目录下 JAR 包中的类都交给该类的 onStartup() 方法处理,实现的 onStartup 方法中可以向 ServletContext 对象(Servlet 上改毕下文)添加之前在 web.xml 中配置的 Filter和 Servlet,这样一来就可以去除 web.xml 文件了  

SpringMVC的实现类 SpringServletContainerInitializer  就是实现了ServletContainerInitializer接口,负责初始化web环境,SpringServletContainerInitializer把所有的初始化任务委托给WebApplicationInitializer这个接口的实现类,其中AbstractDispatcherServletInitializer便是创建DispatcherServlet 的关键类

SpringBoot 是通过 org.springframework.boot.web.embedded.tomcat.TomcatStarter 这个类进行初始化流程的,TomcatStarter同样也是实现了ServletContainerInitializer接口,通过构造方法传入的ServletContextInitializer去初始化Web环境,其中ServletWebServerApplicationContext 负责 加载Filter、Servlet、Listener

ServletWebServerApplicationContext 的 onRefresh() 方法触发配置了一个匿名的 ServletContextInitializer

这个匿改歼渣名的 ServletContextInitializer 的 onStartup 方法会去容器中搜索到了所有的 RegisterBean 并按照顺序加载到 ServletContext 中

这个匿名的 ServletContextInitializer 最终传递给 TomcatStarter,由 TomcatStarter 的 onStartup 方法去触发 ServletContextInitializer 的 onStartup 方法,最终完成装配

     注册方式一: Servlet3.0 注解(@WebServlet,@WebFilter,@WebListener) +@ServletComponentScan , 在启动类上面添加 @ServletComponentScan 注解去扫描到这些注解

      注册方式二: RegistrationBean,比如 ServletRegistrationBean 和 FilterRegistrationBean 都继成 RegistrationBean,它是 SpringBoot 中广泛应用的一个注册类,负责把 Servlet,Filter,Listener 给容器化,使它们被 Spring 托管,并且完成自身对 Web 容器的注册

用户的浏览器发送一个请求,这个请求经过互联网到达了我们的服务器。Servlet 容器首先接待了这个请求,并将该请求委托给 DispatcherServlet 进行处理。

1.  DispatcherServlet 主要通过 dispatch 这个方法去处理整个流程,这个流程他会先去通过 HandlerMapping 的getHandler方法得到一个HandlerExecutionChain对象

HandlerMapping 就是一个接口,里面就只有一个方法就叫getHandler,他有很多实现类,但是大体主要通过两种方式获得Handler 一种是 AbstracHandlerMethodMapping  和 AbstractUrlHandlerMapping ,一个是基于 Method 进行匹配的,比如@RequestMapping注解,一个是基于 URL 进行匹配,我们平常用的最多的还是RequestMappingHandlerMapping,这个就是 AbstracHandlerMethodMapping  的子类

HandlerExecutionChain 这个对象就是包含了拦截器和处理器对象,这个处理器对象是object类型的,对象比如说,我们平常通过在方法上标记@RequestMapping注解,然后呢他这个对象就是HandlerMethod 类型, 这个 HandlerMethod封装了很多属性,在访问请求方法的时候可以方便的访问到方法、方法参数、方法上的注解、所属类等并且对方法参数封装处理,也可以方便的访问到方法参数的注解等信息。拦截器呢,就是实现了HandlerInterceptor接口的类,就是在执行方法之前和执行方法之后进行一些处理

2.  拿到这个 HandlerExecutionChain 对象之后呢,还要找一个HandlerAdapter 适配器,他通过遍历 HandlerAdapter 组件,判断是否支持处理该 handler 处理器,支持则返回该 HandlerAdapter 组件,这个HandlerAdapter组件负责处理执行整个流程,参数的解析,方法的执行,返回值的处理,都是在他里面完成的,

像我们平时用的最多的还是RequestMappingHandlerAdapter类,他就是执行 HandlerMethod 类型的处理器,也就是通过 @RequestMapping 等注解标注的方法

3. 然后呢通过执行HandlerAdapter的handle方法,会给我们返回一个ModelAndView 对象,这个呢就是数据和视图地址,然后呢就会调用processDispatchResult这个方法去解析视图,这里面他会通过render这个方法进行页面渲染逻辑,这里面就会交给viewResolvers去处理,但是我们平常开发都是标注了ResponseBody注解,所以在HandlerAdapter这里面会将我们返回的结果直接将数据通过HttpServletResponse.write写进去,最后直接返回

  Spring MVC的拦截器的实现了HandlerInterceptor接口 , 里面主要有三个方法 preHandle,postHandle,afterCompletion,分别是前置处理,后置处理和已完成处理

  这个HandlerInterceptor呢,他会在在HanderMapping的子类 AbstractHandlerMapping 中的 getHandler 方法中去获取,一般是在获取完handler处理器后然后会去和HandlerInterceptor去组装成 HandlerExecutionChain 对象,

HandlerInterceptor拦截器呢会在AbstractHandlerMapping  initApplicationContext ()方法中初始化完成的,因为这个方法是重写了父类 ApplicationObjectSupport 的initApplicationContext()ApplicationObjectSupport最上层的接口ApplicationContextAware中的 setApplicationContext ,所以他会在初始化该ben的时候调用setApplicationContext这个方法,然后这个方法将 interceptors 初始化成 HandlerInterceptor 类型,添加到  adaptedInterceptors 中

HandlerMapping 组件,请求的 处理器匹配器 ,负责为请求找到合适的 HandlerExecutionChain 处理器执行链,包含处理器(handler)和拦截器们(interceptors),下面先说 AbstractHandlerMapping

AbstractHandlerMapping 抽象类,一个基类,实现了“为请求找到合适的 HandlerExecutionChain 处理器执行链”对应的的骨架逻辑,而暴露 getHandlerInternal() 抽象方法,交由子类实现。

AbstractUrlHandlerMapping

AbstractHandlerMethodMapping

            因为其中处理器的实现有多种,例如通过实现 Controller 接口、HttpRequestHandler 接口,或者使用 @RequestMapping 注解将方法作为一个处理器等。Spring MVC 就无法直接执行这个处理器,所以这里需要一个处理器适配器,由它去执行处理器, HandlerAdapter 接口也就三个方法,一个是判断是否支持该处理器的,一个是执行处理器返回ModelAndView的,还有一个是返回请求的最新更新时间的

HttpRequestHandlerAdapter :执行实现了 HttpRequestHandler 接口的处理器

SimpleControllerHandlerAdapter :执行实现了 Controller 接口的处理器

SimpleServletHandlerAdapter :执行实现了 Servlet 接口的处理器

RequestMappingHandlerAdapter : 执行 HandlerMethod 类型的处理器,也就是通过 @RequestMapping 等注解标注的方法,主要说说RequestMappingHandlerAdapter的执行流程:

1. 会先创建ServletInvocableHandlerMethod并且设置一些属性,这个是对HandlerMethod 处理器的封装,然后通过这个对象的invokeAndHandle方法去执行

2  然后需要通过 HandlerMethodArgumentResolver 对象进行参数解析

3  在通过反射执行对应的 Method 方法对象

4   最后通过 HandlerMethodReturnValueHandler 对象对执行结果进行处理,设置到 response 响应中,生成对应的 ModelAndView 对象

ServletInvocableHandlerMethod  封装 HandlerMethod 处理器对象,它还包含 HandlerMethodArgumentResolver 参数解析器和 HandlerMethodReturnValueHandler 返回值处理器等组件

参数解析器,先说说他是怎么处理的吧, 在ServletInvocableHandlerMethod解析参数会先用到一个HandlerMethodArgumentResolverComposite对象,这也是一个实现HandlerMethodArgumentResolver接口的对象,他呢是一个组合对象,里面就包含了很多的参数解析器,他会遍历所有的参数解析器去调用supportsParameter这个方法去看是否支持解析该参数,如果支持呢他就会返回这个参数解析器,不支持就会给返回一个IllegalStateException的异常,然后呢就会调用resolveArgument去解析这个参数,像解析参数处理器的就非常多了,常见的有:

 RequestParamMethodArgumentResolver: 基于 @RequestParam 注解的 也可以不带

 PathVariableMethodArgumentResolver  : 基于 @PathVariable 注解的

ServletModelAttributeMethodProcessor :基于ModelAttribute注解的,处理实体类,也可以不带

 RequestResponseBodyMethodProcessor: 基于@RequestBody注解的

在转换的过程中呢还有个参数转换器,比如啊我们从浏览器发过来的请求都是text类型的,所以必须要把这这些类型转换成我们的目标类型,比如Date,Number啊这些类型,都需要通过转换器去完成,WebDataBinder 利用它里面的 Converters 将请求数据转成指定的数据类型。再次封装到JavaBean中,拿到这些处理好的值,直接通过反射调用我们写好的方法获得拿到需要返回的值就好了

  HandlerMethodReturnValueHandler 返回值处理器将返回结果设置到响应中,或者设置相应的 Model 和 View 用于后续的视图渲染。这个接口也就两个方法,一个是判断是否支持该返回类型的,还有一个就是处理返回值的

RequestResponseBodyMethodProcessor :  负责处理@ResponseBody注解的返回值,现在前后端分离,后端基本是提供 Restful API,最常用的就是他,RequestResponseBodyMethodProcessor中还有个最重要的就是MessageConverters内容协商,利用 MessageConverters将返回的数据 写为json,他 =会根据请求头Accept去看浏览器接收什么样的数据类型,在根据MessageConverters实现类的MediaType这个类去和你匹配看自己能支持那些内容类型的数据,那你浏览器需要json就会得到MappingJackson2HttpMessageConverter这个对象,然后把对象转成json写到response中

ViewNameMethodReturnValueHandler : 适用于前后端未分离,Controller 返回视图名的场景,例如 JSP、thymeleaf模板引擎就用这个

处理器异常解析器,将处理器执行请求时发生的异常,解析成对应的 ModelAndView 结果,大致就是通过@ControllerAdvice+@ExceptionHandler注解处理全局异常,底层就是HandlerExceptionResolver 接口支持的,其中一个实现类 ExceptionHandlerExceptionResolver 会在初始化的时候去扫描 扫描 @ControllerAdvice 注解的 Bean 们然后找到有 @ExceptionHandler 注解的方法,则添加到 exceptionHandlerAdviceCache 中,执行的时候他里面也有参数解析器和返回值处理器,处理完了之后也会返回ModelAndView对象

视图解析器,根据视图名和国际化,获得最终的视图 View 对象。Spring MVC 执行完处理器后生成一个 ModelAndView 对象,如果该对象不为 null 并且有对应的 viewName,那么就需要通过 ViewResolver 根据 viewName 解析出对应的 View 对象

MultipartResolver 组件,内容类型( Content-Type )为 multipart/* 的请求的解析器,主要解析文件上传的请求。例如,MultipartResolver 会将 HttpServletRequest 封装成 MultipartHttpServletRequest 对象,

 DispatcherServlet  

Spring MVC 的核心组件,是请求的入口,负责协调各个组件工作

MultipartResolver

  内容类型( Content-Type )为 multipart/* 的请求的解析器,例如解析处理文件上传的请求,便于获取参数信息以及上传的文件

HandlerMapping

  请求的处理器匹配器,负责为请求找到合适的 HandlerExecutionChain 处理器执行链,包含处理器(handler)和拦截器们(interceptors)

HandlerAdapter

 处理器的适配器。因为处理器 handler 的类型是 Object 类型,需要有一个调用者来实现 handler 是怎么被执行。Spring 中的处理器的实现多变,比如用户处理器可以实现 Controller 接口、HttpRequestHandler 接口,也可以用 @RequestMapping 注解将方法作为一个处理器等,这就导致 Spring MVC 无法直接执行这个处理器。所以这里需要一个处理器适配器,由它去执行处理器

HandlerExceptionResolver

 处理器异常解析器,将处理器( handler )执行时发生的异常,解析( 转换 )成对应的 ModelAndView 结果

RequestToViewNameTranslator

视图名称转换器,用于解析出请求的默认视图名

LocaleResolver

本地化(国际化)解析器,提供国际化支持

ThemeResolver

 主题解析器,提供可设置应用整体样式风格的支持

ViewResolver

视图解析器,根据视图名和国际化,获得最终的视图 View 对象

FlashMapManager

FlashMap 管理器,负责重定向时,保存参数至临时存储(默认 Session)

@Controller 注解有什么用?

@Controller 注解标记一个类为 Spring Web MVC 控制器 Controller。Spring MVC 会将扫描到该注解的类,然后扫描这个类下面带有 @RequestMapping 注解的方法,根据注解信息,为这个方法生成一个对应的 处理器 对象,在上面的 HandlerMapping 和 HandlerAdapter组件中讲到过。

当然,除了添加 @Controller 注解这种方式以外,你还可以实现 Spring MVC 提供的 Controller 或者 HttpRequestHandler 接口,对应的实现类也会被作为一个 处理器 对象

@RequestMapping 注解有什么用?

@RequestMapping 注解,在上面已经讲过了,配置 处理器 的 HTTP 请求方法,URI等信息,这样才能将请求和方法进行映射。这个注解可以作用于类上面,也可以作用于方法上面,在类上面一般是配置这个 控制器 的 URI 前缀

@RestController 和 @Controller 有什么区别?

@RestController 注解,在 @Controller 基础上,增加了 @ResponseBody 注解,更加适合目前前后端分离的架构下,提供 Restful API ,返回例如 JSON 数据格式。当然,返回什么样的数据格式,根据客户端的 ACCEPT 请求头来决定。

@RequestMapping 和 @GetMapping 注解的不同之处在哪里?

@RequestMapping:可注解在类和方法上;@GetMapping 仅可注册在方法上

@RequestMapping:可进行 GET、POST、PUT、DELETE 等请求方法;@GetMapping 是 @RequestMapping 的 GET 请求方法的特例,目的是为了提高清晰度。

@RequestParam 和 @PathVariable 两个注解的区别

两个注解都用于方法参数,获取参数值的方式不同,@RequestParam 注解的参数从请求携带的参数中获取,而 @PathVariable 注解从请求的 URI 中获取

返回 JSON 格式使用什么注解?

可以使用 @ResponseBody 注解,或者使用包含 @ResponseBody 注解的 @RestController 注解。

当然,还是需要配合相应的支持 JSON 格式化的 HttpMessageConverter 实现类。例如,Spring MVC 默认使用 MappingJackson2HttpMessageConverter

ServletRegistrationBean 和 FilterRegistrationBean 都继成 RegistrationBean,它是 SpringBoot 中广泛应用的一个注册类,负责把 Servlet,Filter,Listener 给容器化,使它们被 Spring 托管,并且完成自身对 Web 容器的注册

Web项目开发为何要走前后端分离模式?

把前端与后端独立起来去开发,放在两个不同的服务器,需要独立部署,两个不唯睁同的工程,两个不同的代码库,不同的开发人员,前后端工程师需要约定交互接口,实现同步开发,开发结束后需要进行独立部署,前端通过接口来调用调用后端的API,前端只需要关注页面的样式与动态数据的解析和渲染,而后端专注于具体业务逻辑。具体好处有以下几点:

1.彻底解放前端

前端不再需要向后台提供模板或是后台在前端html中嵌入后台代

2.提高工作效率,分工更加明确

前后端分离的工作流程可以使前端只关注前端的事,后台只关心后台的活,两者开发可以同时进行,在后台还没有时间提供接口的时候,前端可以先将数据写死或者调用本地的json文件即可,页面的增加和路由的修改也不必再去麻烦后台,开发更加灵活。

3.局部性能提升

通过前端路由的配置,我们可以实现页面的按需加载,无需一开始加载首页便加载网站的所有的资源,服务器也不再需要解析前端页面,在页面交互及用户体验上有所提升。

4.降低维护成本

通过目前主流的前端MVC框架,我们可以非常快速的定位及发现问题的所在,客户端的问题不再需要后台人员参与及调试,代码重构及可维护性增强。

5.实现高内聚低耦合,减少后端(应用)服务器的并发/负载压力。

6.即使后端服务暂时超时或者宕机了,前端页面也会正常访问,但无法提供数据。

7.可以使后台能更好的追求高并发,高可用,高性能;使前端能更好的追求页面表现、速度流畅、兼容性、用户体验等。

我理解的前后端分离,前端是需要起服务器的,减少学习成本,可以用node,前端也要有域名的

如果是半分离, 那么前端提供js文件(css等)这个我也做过,前后端都用node就不说了,如果是两种语言,

如果一个工程文件下开发,webpack下直接打包进后台语言的静态目录下。

如果是两个工程,那么前端只提供生成的js(css)文件,git pull后台项目,扔进静态目录,这样又涉及到版本控制的问题,一般我会生滚册成一个配置文件,直接读取的,内容是xxx.hash.js这种文件名,然后document.wirte动态写入js/css

前端起服务器就不需要动态引入了,直接html插件生成文件,更好的控制版本

半分离 还有一个问题,例如首页同构,如果更改xxx.blade.php文件,这就又动了php文件,大山宏甚至包括nginx反向代理啊,ssl这种缓存啊,都比较麻烦,你要是改了点啥,自己的ok了,后台的崩了,那就挺操蛋了,大公司有专门的运维还好,小公司真的是一团糟

后台我们采取全分离,nginx前端管理,至于升级nginx版本,http2,反向代理,https证书,都是前端自己弄,毕竟小公司,每个人水平都不一致,自己负责自己的比较好

但是这个跨域又要稍微处理一下,至今我这边后台还是*,我也没法说什么

阿里云这么便宜,如果把成本浪费在人力上,会变得很贵

一个人的精力有限,前后端分离有助于我们更专注我们所要注重的技术点,俗话说:“术业有专攻”。

比如我们后端,前后端分离有助于我们把注意力放在java基础,设计模式,jvm原理,spring+springmvc原理及源码,linux,mysql事务隔离与锁机制,mongodb,http/tcp,多线程,分布式架构(dubbo,dubbox,spring cloud),弹性计算架构,微服务架构(springboot+zookeeper+docker+jenkins),java性能优化,以及相关的项目管理等等。

而前端也可以集中精力在前端的展示上。

总的来说,前后端分离利大于弊。这也是越来越少用jsp的原因。

补充两点

1.每次请求的数据量变小,也意味着更少的响应时间。

2.也不是每个应用用前后端分离都是最合适的,要根据应用规模,工期综合判断。

Spring MVC 的跨域解决方案

一句话:同一个ip、同一个网络协议、同一个端口,三者都满足就是同一个域,否则就是跨域。

基于两个方面:

a. web应用本身是部署在不同的服务器上

b.基于开发的角度 --- 前后端分离

web应用本身是部署在不同的服务器上,对应的域名也就有所不同

比如百度。

主域名:

二级域名:, ,

需要在不同的域之间,通过ajax方尘核式互相请求,码颤是非常常见的需求。

Spring 4中增加了对jsonp的原生支持,只需要ControllerAdvice就可以开启,方法如下:

首先新建一个Advice类,我们叫做“JsonpAdvice”,然后在里面定义接收jsonp请求的参数key:

@ControllerAdvice("cn.isy.web.sso.web")指定作用的包名

supper("callback")指定的是url中callback:

注意:

我们还可以重写AbstractJsonpResponseBodyAdvice中的feforeBodyWriteInternal方法:

做到实现url携带callback就返回jsonp格式,没有就返回正常格式

img

controller中

controller中的代码正常编写就OK,不用修改任何东西。

只要保证在cn.isy.web.sso.web包下即可!

jquery ajax

注意:必须使用jsonp的方式提交请求!

有关cors的介绍可以去详细看一下,这里就不作重复了:

CORS详解

跨资源迟兄败共享CORS详解

主要配置

使用注解CrossOrigin

在controller类上添加CrossOrigin注解表示当前类中的所有入口函数都

可以实现跨域。也可以指定某个conroller中具体的方法。

img

了解一下这个注解的内容:

img

jquery ajax的写法

注意:这里不用使用jsonp的方式请求普通的ajax即可!,因为浏览器自己可以去做!

CORS全局配置

自己试了试没有成功!

资料

解释cors的原理不错

让自己变得更优秀才可以有更多资源

搜索微信号(ID:芋道源码),可以获得各种 Java 源码解析。

并且,回复【书籍】后,可以领取笔者推荐的各种 Java 从入门到架构的书籍。

SpringMVC前后端分离交互传参详细教程-

温故而知新,本文为一时兴起写出,如有错误还请指正

本文后台基于SpringBoot2.5.6编写,前端基于Vue2 + axios和微信小程序JS版分别编写进行联调测试,用于理解前后端分离式开发的交互流程,如果没用过axios可以点我看之前的帖子

如果你没有学过SpringBoot也不要紧,把他看做成SpringMVC即可,写法完全一致(其实我不说你也发现不了)

本文主要讲前后端交互流程,力求帮助新人快速入门前后端分离式开发,不会讲关于数胡环境搭建部分的内容

在文章开头快速的过一遍SpringMVC接收参数的几种方式,一定要记住这几种方式,看不懂或不理解都没关系,后续会结合前端代码过一遍,这里就不过多解释了,直接上代码

细心的人应该留意到了,最后使用变量接收参数的时候只接收了 username 这一个值,并没有接收 password ,作为扩展在这里解释一下, 不看也可以,看了不理解也没关系,知道这个事儿就够了,以后接触多了就理解了

如果请求参数放在了请求体中,只有参数列表第一个变量能接收到值,这里需要站在Servlet的角度来看:

可以看到请求体内容是存到了 InputStream 输入流对象中,想要知道请求体中的内容是什么必须读流中的数据,读取到数据后会将值给第一个变量,而流中的数据读取一次之后就没了,当第二个变量读流时发现流已经被关闭了,自然就接收不到

SpringMVC回顾到此为止,只需要记住那三种方式即可,在前后端交互之前先在Controller中写个测试接口

这个接口对应的是GET类型的请求,这里直接在浏览器地址栏访问测试一下:

这里推荐一个Chrome浏览器的插件 JSONView ,它可以对浏览器显示的JSON数据进行格式化显示,推荐的同时也提个醒,安装需谨慎,如果JSON数据量太大的话页面会很卡

之前已经写好一个GET请求的测试接口了,这里就在前端写代码访问一下试试看

代码已经写完了,接下来打开页面试一下能不能调通:州凳

可以看到请求代码报错了,查看报错信息找到重点关键词 CORS ,表示该请求属于 跨域请求

什么是跨域请求?跨域请求主要体现在跨域两个字上,当发起请求的客户端和接收请求的服务端他们的【协议、域名、端口号】有任意一项不一致的情况都属于跨域请求,拿刚刚访问的地址举例,VUE页面运行在9000端口上,后台接口运行在8080端口上,端口号没有对上所以该请求为跨域请求

如果在调试的时候仔细一点就会发现,虽然前端提示请求报错了,但是后端还是接收到请求了,那为什么会报错呢?是因为后端返回数据后,浏览器接收到响应结果发现该请求跨域,然后给我们提示错误信息,也就是说问题在浏览器这里

怎样才能让浏览器允许该请求呢?我们需要在后端动点手脚,在返回结果的时候设置允许前端访问即可

首先配置一个过滤器,配置过滤器有很多种实现的方法,我这里是实现Filter接口

过滤器创建完成了,回来看前端提示的报错信息为 Access-Control-Allow-Origin ,意思是允许访问的地址中并不包含当前VUE的地址,那么我们就在响应结果时将VUE的地址追加上

添加完成后重启项目后台就会发现请求已经成功并且拿到了返回值

再次册毕旅进行测试,将后台的GetMapping修改为PostMapping,修改前端请求代码后重新发起请求进行测试

可以看到POST请求还是提示跨域请求,对应的错误信息则是 Access-Control-Allow-Headers ,也就是说请求头中包含了不被允许的信息,这里图省事儿用 * 通配符把所有请求头都放行

这样处理之后,请求就可以正常访问啦

路径占位参数,就是将参数作为请求路径的一部分,例如你现在正在看的这篇博客使用的就是路径占位传参

这种传参方法很简单,就不细讲了,可以效仿他这种方法写个测试案例

这里需要注意区分【路径占位传参】和【路径传参】两个概念,不要记混

什么是路径传参?发起一个请求 ;b=2 ,在路径 ? 后面的都属于路径传参,路径传参就是将参数以明文方式拼接在请求地址后面

路径传参使用【正常接收参数】中的实例代码即可接收到值

除了自己手动拼接请求参数之外,axios在config中提供了params属性,也可以实现该功能

表单类型参数,就是通过form表单提交的参数,通常用在例如HTML、JSP页面的form标签上,但如果是前后端分离的话就不能使用form表单提交了,这里可以手动创建表单对象进行传值

需要注意,GET请求一般只用于路径传参,其他类型传参需要使用POST或其他类型的请求

表单类型参数也是【正常接收参数】中的实例代码接收值

小程序删除了FormData对象,不能发起表单类型参数的请求,如果非要写的话可以试着使用 wx.uploadFile 实现,这里就不尝试了

请求体传参,是在发起请求时将参数放在请求体中

表单类型参数需要使用上面【请求体接收参数】中的实例代码接收值

axios如果发起的为POST类型请求,默认会将参数放在请求体中,这里直接写即可

小程序代码也是一样的,当发起的时POST类型的请求时,默认会把参数放在请求体中

在实际开发中大概率不用写前端代码,只负责编写后台接口,但怎样才能知道前端请求是什么类型参数?

关于这点可以通过浏览器开发者工具的【网络】面板可以看出来,网络面板打开时会录制网页发起的所有请求

路径占位传参就不解释了,没啥好说的,这里介绍一下路径传参、表单传参和请求体传参

编写好路径传参的请求代码后切换到网络面板,点击发起请求:

编写好请求体传参的请求代码后切换到网络面板,点击发起请求:

编写好表单类型传参的请求代码后切换到网络面板,点击发起请求:

掌握了前后端交互的流程就可以正常开发网站了,这里推荐后端返回一套规定好的模板数据,否则某些情况可能会比较难处理,例如这个查询用户列表的接口:

该接口乍一看没毛病,拿到用户列表数据后返回给前端用于渲染,合情合理,可是如果后端业务逻辑有BUG可能会导致前端接收到的结果为空,这种情况下前端就需要判断,如果接收到的值为空,就提示请求出错,问题貌似已经解决,但是如果表中本来就没有任何数据的话有应该怎么处理

上述的就是最常见的一种比较头疼的情况,所以针对这种情况最好指定一套标准的返回模板进行处理

根据刚刚的举例来看,返回结果中应该有一个标识来判断该请求是否执行成功,如果执行失败的话还应该返回失败原因,响应给前端的数据会被转换为JSON数据,使用Map集合来返回最合适不过了

在后台接口编写完成后,一般情况下我们都需要进行测试,GET请求还好,浏览器直接就访问呢了,如果是POST请求还要去写前端代码就很烦,这里介绍一款接口调试工具ApiPost

你可能没听过ApiPost,但是你大概率听说过Postman,他们的用法几乎一致,且ApiPost是国人开发的免费的接口调试工具,界面中文很友好

这里也可以看出来,form表单传参其实也算在了请求体里面,只不过使用的是 multipart/form-data 类型的参数而已,而之前提到的请求体传参对应的就是 application/json


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