什么是前后端分离开发?
前后端分离开发,就是在项目开发过程中,对于前端的代码专门由前端的开发人员开发,后端代码由后端人员负责,这样可以做到分工明确、各司其职,进而提高开发效率,前后端代码并行开发,加快项目的开发进度。目前前后端分离被各大公司使用,成为项目开发的主流开发方式。
前后端分离开发后,工程结构也会发生变化,即前后端代码不会混在同一个maven工程中,而是分为前端工程和后端工程。
- 后端:负责处理、存储数据。
- 前端:负责显示数据。
- 后端工程——>打包部署到tomcat。
- 前端工程——>打包部署到nginx。
前端和后端开发人员通过 接口 进行数据的交换。
开发流程
前后端分离开发时面临一个问题,就是前端人员和后端人员如何进行配合(请求路径、参数传递、请求方式、后端如何响应等)来共同完成一个任务呢?
接口(API接口):就是一个http的请求地址,主要就是去定义:请求路径、请求方式、请求参数、响应数据等内容。
- 后端编写和维护接口文档,在 API 变化时更新接口文档
- 后端根据接口文档进行接口开发
- 前端根据接口文档进行开发 + Mock平台
- 开发完成后联调和提交测试
推荐几个接口规范工具:postman、eolinker
前后端仅仅通过异步接口(AJAX/JSONP)来编程,前后端都各自有自己的开发流程,构建工具,测试集合,关注点分离,前后端变得相对独立并解耦合。
Swagger
Swagger是什么?
Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务的接口文档。
目前的项目基本都是前后端分离,后端为前端提供接口的同时,还需同时提供接口的说明文档。但我们的代码总是会根据实际情况来实时更新,这个时候有可能会忘记更新接口的说明文档,造成一些不必要的问题。
用人话说,swagger就是帮你写接口说明文档的。更具体地,可以看下面的图片,swagger官方建议使用下面的红字部分,这篇博客主要是记录如何,使用swagger自动生成Api文档的,所以只介绍swagger-ui,其他的…以后我用到会再整理。
文章来源:https://www.toymoban.com/news/detail-456053.html
基本使用
knife4j是java mvc框架集成swagger生成api文档的增强解决方案。文章来源地址https://www.toymoban.com/news/detail-456053.html
- 导入坐标
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
- 配置WebMvcConfig类
public class WebMvcConfig extends WebMvcConfigurationSupport {
/**
* 设置静态资源映射。
*
* @param registry
*/
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
log.info("开始进行静态资源映射...");
// addResourceHandler("/backend/**"):拦截请求信息,addResourceLocations("classpath:/backend/"):文件真实地址。
registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/backend/");
registry.addResourceHandler("/front/**").addResourceLocations("classpath:/front/");
}
/**
* 扩展mvc框架的消息转换器。
*
* @param converters
*/
@Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
log.info("加入全局消息转换器...");
// 创建消息转换器对象,
MappingJackson2HttpMessageConverter messageConverter=new MappingJackson2HttpMessageConverter();
// 设置对象转换器,底层使用Jackson将java对象转为json。
messageConverter.setObjectMapper(new JacksonObjectMapper());
// 将上面的消息转换器添加到mvc框架的转换器集合中。放在集合的第一位,会先使用我们加入的全局消息转换器
converters.add( 0,messageConverter);
}
@Bean
public Docket createRestApi() {
// 文档类型
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.jie.reggie.controller"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("瑞吉外卖")
.version("1.0")
.description("瑞吉外卖接口文档")
.build();
}
}
- 配置LoginCheckFilter类
/**
* @author 小杰 检查用户是否已经登录的过滤器。
*/
@Slf4j
@WebFilter(filterName = "loginCheckFilter", urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
// 专门用来进行路径比较的。路径匹配器,支持通配符。
public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws ServletException, IOException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
// 1.获取本次请求的uri
String requestURI = httpServletRequest.getRequestURI();
log.info("获取到的uri:{}", requestURI);
// 定义所有不处理的请求路径。
String[] urls =
new String[]{
"/backend/**",
"/front/**",
"/employee/login",
"/employee/logout",
"/common/**",
"/user/login",
"/user/sendMsg",
"/doc.html",
"/webjars/**",
"/swagger-resources",
"/v2/api-docs"
};
// 2、判断本次请求是否需要处理,
boolean check = check(urls, requestURI);
// - 如果不需要处理,就直接放行,
if (check) {
log.info("请求不需要处理:{}", requestURI);
chain.doFilter(httpServletRequest, httpServletResponse);
return;
}
// 3.判断登录状态,
// 后台员工登录- 如果已登录,就直接放行
if (httpServletRequest.getSession().getAttribute("employee") != null) {
log.info("用户已登录,登录的id为: {}", httpServletRequest.getSession().getAttribute("employee"));
// 把id保存到当前ThreadLocal线程中。
Long empId = (Long) httpServletRequest.getSession().getAttribute("employee");
BaseContext.setCurrentId(empId);
// 放行。
chain.doFilter(httpServletRequest, httpServletResponse);
return;
}
// 用户登录- 如果已登录,就直接放行
if (httpServletRequest.getSession().getAttribute("user") != null) {
log.info("用户已登录,登录的id为: {}", httpServletRequest.getSession().getAttribute("user"));
// 把id保存到当前ThreadLocal线程中。
Long userId = (Long) httpServletRequest.getSession().getAttribute("user");
BaseContext.setCurrentId(userId);
// 放行。
chain.doFilter(httpServletRequest, httpServletResponse);
return;
}
// 如果未登录,则返回未登录结果.通过输出流方式向客户端响应数据。
httpServletResponse.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
log.info("用户未登录。。。");
return;
}
/**
* 进行路径匹配,检查本次请求是否需要匹配。
*
* @param requestURI 待匹配的uri
* @param urls 所有不处理的请求路径数组。。
* @return 匹配成功返回true,否则返回false。
*/
public boolean check(String[] urls, String requestURI) {
for (String url : urls) {
if (PATH_MATCHER.match(url, requestURI)) {
return true;
}
}
return false;
}
}
参考
- 超详细的前后端分离开发
- swagger详解
到了这里,关于前后端分离开发的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!