前后端分离开发

什么是前后端分离开发?

前后端分离开发,就是在项目开发过程中,对于前端的代码专门由前端的开发人员开发,后端代码由后端人员负责,这样可以做到分工明确、各司其职,进而提高开发效率,前后端代码并行开发,加快项目的开发进度。目前前后端分离被各大公司使用,成为项目开发的主流开发方式。
前后端分离开发后,工程结构也会发生变化,即前后端代码不会混在同一个maven工程中,而是分为前端工程和后端工程。

  • 后端:负责处理、存储数据。
  • 前端:负责显示数据。
  • 后端工程——>打包部署到tomcat。
  • 前端工程——>打包部署到nginx。
    前端和后端开发人员通过 接口 进行数据的交换。
    在这里插入图片描述

开发流程

前后端分离开发时面临一个问题,就是前端人员和后端人员如何进行配合(请求路径、参数传递、请求方式、后端如何响应等)来共同完成一个任务呢?
接口(API接口):就是一个http的请求地址,主要就是去定义:请求路径、请求方式、请求参数、响应数据等内容。

  • 后端编写和维护接口文档,在 API 变化时更新接口文档
  • 后端根据接口文档进行接口开发
  • 前端根据接口文档进行开发 + Mock平台
  • 开发完成后联调和提交测试

推荐几个接口规范工具:postman、eolinker

前后端仅仅通过异步接口(AJAX/JSONP)来编程,前后端都各自有自己的开发流程,构建工具,测试集合,关注点分离,前后端变得相对独立并解耦合。
在这里插入图片描述

Swagger

Swagger是什么?

Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务的接口文档。

目前的项目基本都是前后端分离,后端为前端提供接口的同时,还需同时提供接口的说明文档。但我们的代码总是会根据实际情况来实时更新,这个时候有可能会忘记更新接口的说明文档,造成一些不必要的问题。

用人话说,swagger就是帮你写接口说明文档的。更具体地,可以看下面的图片,swagger官方建议使用下面的红字部分,这篇博客主要是记录如何,使用swagger自动生成Api文档的,所以只介绍swagger-ui,其他的…以后我用到会再整理。
在这里插入图片描述

基本使用

knife4j是java mvc框架集成swagger生成api文档的增强解决方案。

  • 导入坐标
<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;
    }
}

参考

  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值