JAVA社交平台项目第一天 项目介绍和工程搭建

564 篇文章 141 订阅

第1章 - 项目介绍和工程搭建

学习目标:

  • 了解十次方项目需求;
  • 了解前后端分离开发模式
  • 理解RESTful
  • 完成项目开发环境搭建
  • 完成父工程、公共模块和文章微服务的搭建
  • 掌握mybatis plus的使用,并开发完成文章微服务中文章的增删改查功能
  • 掌握公共异常处理类的使用

1 十次方项目需求分析

1.1 项目介绍

十次方是程序员的专属社交平台,包括头条、问答、活动、交友、吐槽、招聘六大频道。

1557476206791

十次方名称的由来:2的10次方为1024,程序员都懂的。

如果你是一位技术大咖,那么赶快发布文章,增加知名度吧。

如果你是一名技术小白,那么赶快到问答频道寻求帮助的,这里高手如云哦!

如果你不想错过各种技术交流会,那么请经常关注活动频道吧。

如果你还是单身,那么赶快到交友频道找到你心仪的另一半。

如果你有太多的苦恼,那么赶快吐个槽吧。

如果你正在找工作或是想跳槽拿高薪,那么来招聘频道淘金吧。

1.2 项目需求

详见: 资源\文档\十次方需求规格说明书.docx

2 系统设计

2.1 开发模式

十次方项目采用前后端分离的开发模式

2.2 技术选型

后端:springboot + springcloud + mybatis plus + mysql5.7

前端:nodejs + NUXT + elementUI + vue

2.3 技术架构

采用前后端分离的系统架构

1557635014480

2.4 微服务模块划分

模块名称模块中文名称
tensquare_common公共模块
tensquare_base基础微服务
tensquare_article文章微服务
tensquare_friend交友微服务
tensquare_gathering活动微服务
tensquare_qa问答微服务
tensquare_recruit招聘微服务
tensquare_user用户微服务
tensquare_spit吐槽微服务
tensquare_search搜索微服务
tensquare_web前台微服务网关
tensquare_manager后台微服务网关
tensquare_eureka注册中心
tensquare_config配置中心
tensquare_sms短信微服务
tensquare_notice消息通知微服务

2.5 数据库表结构分析

采用的分库分表设计,每个微服务模块为1个独立的数据库。

tensquare_article 文章

tensquare_base 基础

tensquare_friend 交友

tensquare_gathering 活动

tensquare_qa 问答

tensquare_recruit 招聘

tensquare_user 用户

tensquare_spit 吐槽

详见 资源\文档\十次方数据库文档.xlsx

2.6 API文档

课程提供了前后端开发接口文档(采用Swagger语言进行编写),并与Nginx进行了整 合。双击Nginx执行文件启动后,在地址栏输入http://localhost:801 即可访问API文档

前后端约定的返回码列表:

状态描述返回码
成功20000
失败20001
用户名或密码错误20002
权限不足20003
远程调用失败20004
重复操作20005

3 RESTful架构说明

3.1 何为RESTful

RESTful架构是目前最流行的一种互联网软件架构

是Roy Thomas Fielding在他2000年的博士论文中提出的

是Representational State Transfer的缩写,翻译过来是”表现层状态转化”

是所有Web应用都应该遵守的架构设计指导原则

7个HTTP方法:GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS

3.2 接口规范

十次方项目使用GET、POST、PUT、DELETE四种方法

幂等性:不论你请求多少次,资源的状态是一样的。

3.2.1 GET

  • 安全且幂等
  • 获取表示
  • 变更时获取表示(缓存)

适合查询类的接口使用

3.2.2 POST

  • 不安全且不幂等
  • 使用服务端管理的(自动产生)的实例号创建资源
  • 创建子资源
  • 部分更新资源
  • 如果没有被修改,则不过更新资源(乐观锁)

适合数据提交类的接口使用

3.2.3 PUT

  • 不安全但幂等
  • 用客户端管理的实例号创建一个资源
  • 通过替换的方式更新资源
  • 如果未被修改,则更新资源(乐观锁)

适合更新数据的接口使用

3.2.4 DELETE

  • 不安全但幂等
  • 删除资源

适合删除数据的接口使用

请求返回响应码:

代码含义
200(OK)- 如果现有资源已被更改
201(created)- 如果新资源被创建
202(accepted)- 已接受处理请求但尚未完成(异步处理)
301(Moved Permanently)- 资源的URI被更新
303(See Other)- 其他(如,负载均衡)
400(bad request)- 指代坏请求
404(not found)- 资源不存在
406(not acceptable)- 服务端不支持所需表示
409(conflict)- 通用冲突
412(Precondition Failed)- 前置条件失败(如执行条件更新时的冲突)
415(unsupported media type)- 接受到的表示不受支持
500(internal server error)- 通用错误响应
503(Service Unavailable)- 服务当前无法处理请求

4 项目开发准备

4.1 开发环境

  • 虚拟系统环境 VMware Workstation
  • 虚拟机系统 CentOS 7
  • 容器 docker
  • JDK1.8
  • 数据库 mysql 5.7
  • 开发工具 idea
  • 项目构建工具 maven

所有的第三方工具如mysql等都是运行在docker容器中的

注:虚拟机的帐户名root 密码itcast

4.2 mysql建库建表

进入安装了docker的虚拟机中,按以下顺序执行命令

(1)下载镜像(此步可省略)

docker pull centos/mysql‐57‐centos7

注:docker默认从国外的镜像网站拉取镜像,速度很慢。可以使用国内的阿里云镜像加速站点提升镜像拉取速度。具体步骤可以参考文档

docker配置国内镜像加速站点.pdf

(2)创建容器

docker run -di --name=tensquare_mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root centos/mysql-57-centos7

(3)连接MYSQL ,并执行资料中的建表脚本,创建article数据库

4.3 接口测试工具postman

postman是一款强大网页调试工具

  • 能够发送任何类型的HTTP 请求 (GET,HEAD, POST,PUT。。。)
  • 附带任意数量的参数

5 项目工程搭建

5.1 父工程搭建

创建项目类型为maven的父工程

  1. 打开idea开发工具

  2. 选择菜单file-new project ,弹出窗口中左侧菜单选择Maven ,点击next按钮

    1557482311840

  3. GroupId填写com.tensquare,ArtifacetId填写tensquare_parent,点击next按钮

    1557482444471

  4. 点击Finish 完成

  5. 修改pom.xml文件,添加以下内容

        <parent>
    
            <groupId>org.springframework.boot</groupId>
    
            <artifactId>spring-boot-starter-parent</artifactId>
    
            <version>2.1.4.RELEASE</version>
    
            <relativePath/>
    
        </parent>
    
        <properties>
    
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    
            <java.version>1.8</java.version>
    
            <maven.compiler.source>1.8</maven.compiler.source>
    
            <maven.compiler.target>1.8</maven.compiler.target>
    
            <mybatisplus-spring-boot-starter.version>1.0.5</mybatisplus-spring-boot-starter.version>
    
            <mybatisplus.version>2.2.0</mybatisplus.version>
    
            <fastjson.version>1.2.39</fastjson.version>
    
            <gson.version>2.8.0</gson.version>
    
        </properties>
    
        <dependencies>
    
            <dependency>
    
                <groupId>org.springframework.boot</groupId>
    
                <artifactId>spring-boot-starter-web</artifactId>
    
            </dependency>
    
            <dependency>
    
                <groupId>org.springframework.boot</groupId>
    
                <artifactId>spring-boot-starter-test</artifactId>
    
                <scope>test</scope>
    
            </dependency>
    
        </dependencies>
    
        <repositories>
    
            <repository>
    
                <id>spring-snapshots</id>
    
                <name>Spring Snapshots</name>
    
                <url>https://repo.spring.io/snapshot</url>
    
                <snapshots>
    
                    <enabled>true</enabled>
    
                </snapshots>
    
            </repository>
    
            <repository>
    
                <id>spring-milestones</id>
    
                <name>Spring Milestones</name>
    
                <url>https://repo.spring.io/milestone</url>
    
                <snapshots>
    
                    <enabled>false</enabled>
    
                </snapshots>
    
            </repository>
    
        </repositories>
    
        <pluginRepositories>
    
            <pluginRepository>
    
                <id>spring-snapshots</id>
    
                <name>Spring Snapshots</name>
    
                <url>https://repo.spring.io/snapshot</url>
    
                <snapshots>
    
                    <enabled>true</enabled>
    
                </snapshots>
    
            </pluginRepository>
    
            <pluginRepository>
    
                <id>spring-milestones</id>
    
                <name>Spring Milestones</name>
    
                <url>https://repo.spring.io/milestone</url>
    
                <snapshots>
    
                    <enabled>false</enabled>
    
                </snapshots>
    
            </pluginRepository>
    
        </pluginRepositories>
    

5.2 搭建公共子模块

5.2.1 搭建子模块步骤

  1. 右键点击父工程tensquare_parent,选择 New -> Module 弹出窗口选择Maven ,点击next按钮

  2. ArtifacetId填写tensquare_common,点击next按钮

    1557487423299

  3. 点击finish

5.2.2 创建公共实体类和工具类

  1. 新建com.tensquare.entity包,包下创建Result类,用于controller返回结果

    public class Result {
    
        private boolean flag;//是否成功
    
        private Integer code;// 返回码
    
        private String message;//返回信息
    
        private Object data;// 返回数据
    
        public Result(boolean flag, Integer code, String message, Object data) {
    
            super();        
    
            this.flag = flag;        
    
            this.code = code;        
    
            this.message = message;        
    
            this.data = data;        
    
        }    
    
        public Result() { }
    
        public Result(boolean flag, Integer code, String message) {    
    
            super();        
    
            this.flag = flag;        
    
            this.code = code;        
    
            this.message = message;        
    
        }    
    
        public boolean isFlag() {    
    
            return flag;        
    
        }    
    
        public void setFlag(boolean flag) {    
    
            this.flag = flag;        
    
        }
    
        public Integer getCode() {    
    
            return code;        
    
        }    
    
        public void setCode(Integer code) {    
    
            this.code = code;        
    
        }
    
        public String getMessage() {    
    
            return message;        
    
        }
    
        public void setMessage(String message) {    
    
            this.message = message;        
    
        }   
    
        public Object getData() {    
    
            return data;        
    
        }    
    
        public void setData(Object data) {    
    
            this.data = data;        
    
        }    
    
    }
    
  2. 创建类PageResult ,用于返回分页结果

    public class PageResult<T>  {
    
        private Long total;
    
        private List<T> rows;
    
        public PageResult(Long  total,  List<T>  rows)  {
    
            super();
    
            this.total  =  total;
    
            this.rows  =  rows;
    
        }
    
        //getter  and  setter  ....
    
    }
    
  3. 返回码定义类

    public class StatusCode {
    
        public static final int OK=20000;//成功
    
        public static final int ERROR =20001;//失败
    
        public static final int LOGINERROR =20002;//用户名或密码错误
    
        public static final int ACCESSERROR =20003;//权限不足
    
        public static final int REMOTEERROR =20004;//远程调用失败
    
        public static final int REPERROR =20005;//重复操作
    
    }
    
  4. 分布式ID生成器

    课程中已经提供了分布式ID生成器

    资源\微服务相关\工具类\IdWorker.java

    tensquare_common工程创建util包,将IdWorker.java直接拷贝到tensquare_common工程的util包中。

不能使用数据库本身的自增功能来产生主键值,原因是生产环境为分片部署的。

使用snowflake (雪花)算法(twitter出品)生成***唯一***的主键值

1557488319373

  • 41bit的时间戳可以支持该算法使用到2082年
  • 10bit的工作机器id可以支持1024台机器
  • 序列号支持1毫秒产生4096个自增序列id
  • 整体上按照时间自增排序
  • 整个分布式系统内不会产生ID碰撞
  • 每秒能够产生26万ID左右

6 文章微服务-文章管理

6.1 模块搭建

  1. 在tensquare_parent项目下创建tensquare_article模块,创建过程参考第4.2节公共子模块的创建过程

  2. 修改tensquare_article模块的pom.xml文件,添加以下依赖

    <dependencies>
    
        <dependency>
    
            <groupId>mysql</groupId>
    
            <artifactId>mysql-connector-java</artifactId>
    
        </dependency>
    
        <dependency>
    
            <groupId>com.tensquare</groupId>
    
            <artifactId>tensquare_common</artifactId>
    
            <version>1.0-SNAPSHOT</version>
    
        </dependency>
    
    </dependencies>
    
  3. 创建com.tensquare.article包,并创建BaseApplication启动类

    package com.tensquare.article;
    
    import org.springframework.boot.SpringApplication;
    
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    import org.springframework.context.annotation.Bean;
    
    import util.IdWorker;
    
    @SpringBootApplication
    public class ArticleApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ArticleApplication.class, args);
        }
    
    
        @Bean
        public IdWorker idWorker(){
                return new IdWorker(1,1);
        }
    
    }
    
  4. 在resources文件夹下创建application.yml,并添加以下内容

    server:
      port: 9004
    spring:
      application:
        name: tensquare-article #指定服务名
      datasource:
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://192.168.200.129:3306/tensquare_article?characterEncoding=utf-8
        username: root
        password: root
    

6.2 文章管理-CRUD

6.2.1 表结构分析

tensquare_article数据库,tb_article表

文章表tb_article
字段名称字段含义字段类型备注
idID文本
columnid专栏ID文本
userid用户ID文本
title文章标题文本
content文章内容文本
image文章封面文本
createtime发表日期日期
updatetime修改日期日期
ispublic是否公开文本0:不公开
istop是否置顶文本0:不置顶
visits浏览量整型
thumbup点赞数整型
comment评论数整型
state审核状态文本0:未审核 1:已审核
channelid所属频道整型关联频道表ID
urlURL地址文本
type文章类型文本0:分享

6.2.2 集成mybatis plus

  1. mybatis plus概述

    • 是对Mybatis框架的二次封装和扩展
    • 纯正血统:完全继承原生 Mybatis 的所有特性
    • 最少依赖:仅仅依赖Mybatis以及Mybatis-Spring
    • 性能损耗小:启动即会自动注入基本CURD ,性能无损耗,直接面向对象操作
    • 自动热加载:Mapper对应的xml可以热加载,大大减少重启Web服务器时间,提升开发效率
    • 性能分析:自带Sql性能分析插件,开发测试时,能有效解决慢查询
    • 全局拦截:提供全表delete、update操作智能分析阻断
    • 避免Sql注入:内置Sql注入内容剥离器,预防Sql注入攻击
  2. 在pom.xml文件中引入相关依赖

            <!-- mybatis-plus begin -->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatisplus-spring-boot-starter</artifactId>
                <version>${mybatisplus-spring-boot-starter.version}</version>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus</artifactId>
                <version>${mybatisplus.version}</version>
            </dependency>
            <!-- mybatis-plus end -->
    
  3. 在配置文件application.yml中添加相关配置

    # Mybatis-Plus 配置
    
    mybatis-plus:
    
    #  mapper-locations: classpath:/mapper/*Mapper.xml
      #实体扫描,多个package用逗号或者分号分隔
      typeAliasesPackage: com.tensquare.article.pojo
      global-config:
        id-type: 1  #0:数据库ID自增   1:用户输入id
        db-column-underline: false
        refresh-mapper: true
        configuration:
          map-underscore-to-camel-case: true
          cache-enabled: true #配置的缓存的全局开关
          lazyLoadingEnabled: true #延时加载的开关
          multipleResultSetsEnabled: true #开启延时加载,否则按需加载属性
          log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #打印sql语句,调试用
    
  4. 修改启动类,增加Mapper扫描注解

    @SpringBootApplication
    
    //Mapper扫描注解
    @MapperScan("com.tensquare.article.dao")
    public class ArticleApplication {
        public static void main(String[] args) {
            SpringApplication.run(ArticleApplication.class, args);
        }
    
        @Bean
        public IdWorker idWorker() {
            return new IdWorker(1, 1);
        }
    }
    

6.2.3 实现查询所有文章和根据id号查询文章功能

  1. 在com.tensquare.article包下面创建pojo包,并创建Article实体类

    package com.tensquare.article.pojo;
    
    import com.baomidou.mybatisplus.annotations.TableId;
    
    import com.baomidou.mybatisplus.annotations.TableName;
    import com.baomidou.mybatisplus.enums.IdType;
    
    import java.io.Serializable;
    
    import java.util.Date;
    
    @TableName("tb_article")
    
    public class Article implements Serializable {
    
        @TableId(type = IdType.INPUT)
    
        private String id;//ID
    
        private String columnid;    //专栏ID
    
        private String userid;      //用户ID
    
        private String title;       //标题
    
        private String content;     //文章正文
    
        private String image;       //文章封面
    
        private Date createtime;    //发表日期
    
        private Date updatetime;    //修改日期
    
        private String ispublic;    //是否公开
    
        private String istop;       //是否置顶
    
        private Integer visits;     //浏览量
    
        private Integer thumbup;    //点赞数
    
        private Integer comment;    //评论数
    
        private String state;       //审核状态
    
        private String channelid;   //所属频道
    
        private String url;         //URL
    
        private String type;        //类型
    
        //getters and setters
    
    }
    
    
  2. 编写数据访问接口dao

    public interface ArticleDao extends BaseMapper<Article> {
    
    }
    
  3. 编写service

    @Service
    
    public class ArticleService {
    
        @Autowired
    
        private ArticleDao articleDao;
    
        public List<Article> findAll() {
    
            return articleDao.selectList(null);
    
        }
    
        public Article findById(String id) {
    
            return articleDao.selectById(id);
    
        }
    
    }
    
  4. 编写controller

    @RestController
    
    @RequestMapping("/article")
    
    public class ArticleController {
    
        @Autowired
    
        private ArticleService articleService;
    
        @RequestMapping(method = RequestMethod.GET)
    
        public Result findAll() {
    
            List list = articleService.findAll();
    
            return new Result(true, StatusCode.OK, "查询成功", list);
    
        }
    
        @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    
        public Result findById(@PathVariable String id) {
    
            Article Article = articleService.findById(id);
    
            return new Result(true, StatusCode.OK, "查询成功", Article);
    
        }
    
    }
    

6.2.4 添加文章、修改文章和删除文章

  1. 添加文章 ArticleController中添加代码

    //新增标签数据接口
    
    @RequestMapping(method = RequestMethod.POST)
    
    public Result add(@RequestBody Article article) {
    
        articleService.add(article);
    
        return new Result(true, StatusCode.OK, "添加成功");
    
    }
    

    ArticleService中添加代码

    @Autowired

    private IdWorker idWorker;

    public void add(Article article) {

    article.setId(idWorker.nextId() + "");
    
    articleDao.insert(article);
    

    }

    
    
    
    
  2. 修改文章

    ArticleController中添加代码

    //修改标签数据接口
    
    @RequestMapping(value = "{id}", method = RequestMethod.PUT)
    
    public Result update(@PathVariable String id, @RequestBody Article article) {
    
        article.setId(id);
    
        articleService.update(article);
    
        return new Result(true, StatusCode.OK, "修改成功");
    
    }
    

    ArticleService中添加代码

    public void update(Article article) {
    
        //根据id号更新
    
        //方法1
    
        articleDao.updateById(article);
    
        //方法2
    
        EntityWrapper wrapper = new EntityWrapper<Article>();
    
        wrapper.eq("id", article.getId());
    
        articleDao.update(article, wrapper);
    
    }
    
  3. 删除文章

    ArticleController中添加代码

    //删除文章数据接口
    
    @RequestMapping(value = "{id}", method = RequestMethod.DELETE)
    
    public Result delete(@PathVariable String id) {
    
        articleService.delete(id);
    
        return new Result(true, StatusCode.OK, "删除成功");
    
    }
    

    ArticleService中添加代码

    public void delete(String id) {
    
        articleDao.deleteById(id);
    
    }
    

6.2.5 条件查询和分页

  1. 条件查询

    使用Mybatis Plus 提供的EntityWrapper对象封装where查询条件,例如以下使用方式:

    EntityWrapper wrapper = new EntityWrapper<Article>();
    
    wrapper.eq("id", article.getId());
    
    //动态sql,例如<if test="null != field"> and field='xxx' </if>
    
    wrapper.eq(null != map.get(field), field, map.get(field));
    
  2. 分页

    • 使用 Mybatis Plus 提供的Page对象
    • 向Mybatis Plus中注入PaginationInterceptor插件
    • 新建config包,创建MybatisPlusConfig对象,添加下面的代码
    @Configuration
    
    public class MybatisPlusConfig {
    
        @Bean
    
        public PaginationInterceptor paginationInterceptor() {
    
            return new PaginationInterceptor();
    
        }
    
    }
    
  3. 完整代码

    ArticleController中添加代码

         @RequestMapping(value="/search/{page}/{size}", method = RequestMethod.POST)
    
        public Result search(@RequestBody Map map, @PathVariable int page, @PathVariable int size) {
    
            Page page1 = articleService.search(map, page, size);
    
            return new Result(true, StatusCode.OK, "查询成功", new PageResult((int) page1.getTotal(), page1.getRecords()));
    
        }
    

    ArticleService中添加代码

    public Page search(Map map, int page, int size) {
    
        EntityWrapper wrapper = new EntityWrapper<Article>();
    
        Set<String> fieldSet = map.keySet();
    
        for(String field : fieldSet) {
    
            //wrapper.eq(field, map.get(field));
    
            wrapper.eq(null != map.get(field), field, map.get(field));
    
        }
    
        Page page1 = new Page(page, size);
    
        List list = articleDao.selectPage(page1, wrapper);
    
        page1.setRecords(list);
    
        return page1;
    
    }
    

6.3 公共异常处理类

为了使代码容易维护,减少冗余,我们创建一个类集中处理异常

在com.tensquare.user.controller包下创建公共异常处理类BaseExceptionHandler,并添加代码

@ControllerAdvice
public class BaseExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Result error(Exception e) {
        e.printStackTrace();
        return new Result(false, StatusCode.ERROR, e.getMessage());
    }
}

ArticleController中添加测试代码

@RequestMapping(value="/exception", method = RequestMethod.GET)
public Result exception() throws Exception {
    throw new Exception("测试统一异常处理");
}

6.4 跨域处理

  1. 何谓跨域

    浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域 。

    十次方项目是采用前后端分离开发的,也是前后端分离部署的,必然会存在跨域问题。

  2. 如何解决跨域

    只需要在controller类上添加注解@CrossOrigin即可!

e}", method = RequestMethod.POST)

   public Result search(@RequestBody Map map, @PathVariable int page, @PathVariable int size) {

       Page page1 = articleService.search(map, page, size);

       return new Result(true, StatusCode.OK, "查询成功", new PageResult((int) page1.getTotal(), page1.getRecords()));

   }

ArticleService中添加代码

public Page search(Map map, int page, int size) {

   EntityWrapper wrapper = new EntityWrapper<Article>();

   Set<String> fieldSet = map.keySet();

   for(String field : fieldSet) {

       //wrapper.eq(field, map.get(field));

       wrapper.eq(null != map.get(field), field, map.get(field));

   }

   Page page1 = new Page(page, size);

   List list = articleDao.selectPage(page1, wrapper);

   page1.setRecords(list);

   return page1;

}




## 6.3 公共异常处理类

为了使代码容易维护,减少冗余,我们创建一个类集中处理异常

在com.tensquare.user.controller包下创建公共异常处理类BaseExceptionHandler,并添加代码

@ControllerAdvice
public class BaseExceptionHandler {

@ExceptionHandler(value = Exception.class)
@ResponseBody
public Result error(Exception e) {
    e.printStackTrace();
    return new Result(false, StatusCode.ERROR, e.getMessage());
}

}


ArticleController中添加测试代码

@RequestMapping(value=“/exception”, method = RequestMethod.GET)
public Result exception() throws Exception {
throw new Exception(“测试统一异常处理”);
}


 

## 6.4 跨域处理

1. 何谓**跨域**

   浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域 。

   十次方项目是采用前后端分离开发的,也是前后端分离部署的,必然会存在跨域问题。

2. 如何解决跨域

   只需要在controller类上添加注解`@CrossOrigin`即可!

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

办公模板库 素材蛙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值