SaaS(Software-as-a-service)的意思是软件即服务。简单说就是在线系统服务,即软件服务商提供的软件在线服务。
SaaS软件就适用对象而言,可以划分为针对个人的与针对企业的
面向个人的SaaS产品:在线文档,账务管理,文件管理,日程计划、照片管理、联系人管理,等等云类型的服务
面向企业的SaaS产品主要包括:CRM(客户关系管理)、ERP(企业资源计划管理)、线上视频或者与群组通话 会议、HRM(人力资源管理)、OA(办公系统)、外勤管理、财务管理、审批管理等。
降低企业成本:按需购买,即租即用,无需关注软件的开发维护
软件更新迭代快速:和传统软件相比,由于SaaS部署在云端,使得软件的更新迭代速度加快
支持远程办公:将数据存储到云后,用户即可通过任何连接到Internet的计算机或移动设备访问其信息
SaaS-HRM是基于saas模式的人力资源管理系统。他不同于传统的人力资源软件应用,使用者只需打开浏览器即可管理上百人的薪酬、绩效、社保、入职离职。
原型分析的理念是指在获取一组基本需求之后,快速地构造出一个能够反映用户需求的初始系统原型。让用户看到 未来系统的概貌,以 便判断哪些功能是符合要求的,哪些方面还需要改进,然后不断地对这些需求进一步补充、细 化和修改。依次类推,反复进行,直到用户满意为止并由此开发出完整 的系统。
简单的说,原型分析法就是在最短的时间内,以最直观的方式获取用户最真实的需求
Unified Modeling Language (UML)又称统一建模语言或标准建模语言,是始于1997年一个OMG标准,它是一 个支持模型化和软件系统开发的图形化语言,为软件开发的所有阶段提供模型化和可视化支持,包括由需求分析到 规格,到构造和配置。 面向对象的分析与设计(OOA&D,OOAD)方法的发展在80年代末至90年代中出现了一个高 潮,UML是这个高潮的产物。它不仅统一了Booch、Rumbaugh和Jacobson的表示方法,而且对其作了进一步的 发展,并最终统一为大众所接受的标准建模语言。UML中包含很多图形(用例图,类图,状态图等等),其中用例图是最能体现系统结构的图形。
用例图(use case)主要用来描述用户与用例之间的关联关系。说明的是谁要使用系统,以及他们使用该系统可以做些什么。一个用例图包含了多个模型元素,如系统、参与者和用例,并且显示这些元素之间的各种关系,如泛化、关联和依赖。它展示了一个外部用户能够观察到的系统功能模型图。
Power Designer 是Sybase公司的CASE工具集,使用它可以方便地对管理信息系统进行分析设计,他几乎包括了数 据库模型设计的全过程。利用Power Designer可以制作数据流程图、概念数据模型、物理数据模型,还可以为数 据仓库制作结构模型,也能对团队设计模型进行控制。
SaaS-IHRM系统采用前后端分离的开发方式。
后端给前端提供数据,前端负责HTML渲染(可以在服务器渲染,也可以在浏览器渲染)和用户交互,双方通过文档的形式规范接口内容。
创建父工程ihrm_parent并添加相关依赖
<packaging>pompackaging>
<name>ihrm_parentname>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.0.5.RELEASEversion>
<relativePath/>
parent>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
<java.version>1.8java.version>
<fastjson.version>1.2.47fastjson.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-loggingartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>${fastjson.version}version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.16.16version>
dependency>
<dependency>
<groupId>org.apache.shirogroupId>
<artifactId>shiro-springartifactId>
<version>1.3.2version>
dependency>
<dependency>
<groupId>org.apache.shirogroupId>
<artifactId>shiro-coreartifactId>
<version>1.3.2version>
dependency>
<dependency>
<groupId>org.crazycakegroupId>
<artifactId>shiro-redisartifactId>
<version>3.0.0version>
dependency>
dependencies>
<repositories>
<repository>
<id>spring-snapshotsid>
<name>Spring Snapshotsname>
<url>https://repo.spring.io/snapshoturl>
<snapshots>
<enabled>trueenabled>
snapshots>
repository>
<repository>
<id>spring-milestonesid>
<name>Spring Milestonesname>
<url>https://repo.spring.io/milestoneurl>
<snapshots>
<enabled>falseenabled>
snapshots>
repository>
repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshotsid>
<name>Spring Snapshotsname>
<url>https://repo.spring.io/snapshoturl>
<snapshots>
<enabled>trueenabled>
snapshots>
pluginRepository>
<pluginRepository>
<id>spring-milestonesid>
<name>Spring Milestonesname>
<url>https://repo.spring.io/milestoneurl>
<snapshots>
<enabled>falseenabled>
snapshots>
pluginRepository>
pluginRepositories>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>3.1version>
<configuration>
<source>${java.version}source>
<target>${java.version}target>
configuration>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-surefire-pluginartifactId>
<version>2.12.4version>
<configuration>
<skipTests>trueskipTests>
configuration>
plugin>
plugins>
build>
(1)新建com.ihrm.common.entity包,包下创建类Result,用于控制器类返回结果
package com.ihrm.common.entity;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 数据响应对象
* {
* success :是否成功
* code :返回码
* message :返回信息
* //返回数据
* data: :{
*
* }
* }
*/
@Data
@NoArgsConstructor
public class Result {
private boolean success;//是否成功
private Integer code;// 返回码
private String message;//返回信息
private Object data;// 返回数据
public Result(ResultCode code) {
this.success = code.success;
this.code = code.code;
this.message = code.message;
}
public Result(ResultCode code,Object data) {
this.success = code.success;
this.code = code.code;
this.message = code.message;
this.data = data;
}
public Result(Integer code,String message,boolean success) {
this.code = code;
this.message = message;
this.success = success;
}
public static Result SUCCESS(){
return new Result(ResultCode.SUCCESS);
}
public static Result ERROR(){
return new Result(ResultCode.SERVER_ERROR);
}
public static Result FAIL(){
return new Result(ResultCode.FAIL);
}
}
(2)创建类PageResult ,用于返回分页结果
package com.ihrm.common.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* 分页
* {
* “success”:“成功”,
* “code”:10000
* “message”:“ok”,
* ”data“:{
* total://总条数
* rows ://数据列表
* }
* }
*
*
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageResult<T> {
private Long total;
private List<T> rows;
}
package com.ihrm.common.entity;
/**
* 公共的返回码
* 返回码code:
* 成功:10000
* 失败:10001
* 未登录:10002
* 未授权:10003
* 抛出异常:99999
*/
public enum ResultCode {
SUCCESS(true,10000,"操作成功!"),
//---系统错误返回码-----
FAIL(false,10001,"操作失败"),
UNAUTHENTICATED(false,10002,"您还未登录"),
UNAUTHORISE(false,10003,"权限不足"),
SERVER_ERROR(false,99999,"抱歉,系统繁忙,请稍后重试!"),
//---用户操作返回码 2xxxx----
MOBILEORPASSWORDERROR(false,20001,"用户名或密码错误");
//---企业操作返回码 3xxxx----
//---权限操作返回码----
//---其他操作返回码----
//操作是否成功
boolean success;
//操作代码
int code;
//提示信息
String message;
ResultCode(boolean success,int code, String message){
this.success = success;
this.code = code;
this.message = message;
}
public boolean success() {
return success;
}
public int code() {
return code;
}
public String message() {
return message;
}
}
目前微服务架构盛行,在分布式系统中的操作中都会有一些全局性ID的需求,所以我们不能使用数据库本身的自增 功能来产生主键值,只能由程序来生成唯一的主键值。我们采用的是开源的twitter( 非官方中文惯称:推特.是国外的一个网站,是一个社交网络及微博客服务) 的snowflake (雪花)算法。
雪花算法代码如下:
package com.ihrm.common.utils;
import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.net.NetworkInterface;
//雪花算法代码实现
public class IdWorker {
// 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动)
private final static long twepoch = 1288834974657L;
// 机器标识位数
private final static long workerIdBits = 5L;
// 数据中心标识位数
private final static long datacenterIdBits = 5L;
// 机器ID最大值
private final static long maxWorkerId = -1L ^ (-1L << workerIdBits);
// 数据中心ID最大值
private final static long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
// 毫秒内自增位
private final static long sequenceBits = 12L;
// 机器ID偏左移12位
private final static long workerIdShift = sequenceBits;
// 数据中心ID左移17位
private final static long datacenterIdShift = sequenceBits + workerIdBits;
// 时间毫秒左移22位
private final static long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
private final static long sequenceMask = -1L ^ (-1L << sequenceBits);
/* 上次生产id时间戳 */
private static long lastTimestamp = -1L;
// 0,并发控制
private long sequence = 0L;
private final long workerId;
// 数据标识id部分
private final long datacenterId;
public IdWorker(){
this.datacenterId = getDatacenterId(maxDatacenterId);
this.workerId = getMaxWorkerId(datacenterId, maxWorkerId);
}
/**
* @param workerId
* 工作机器ID
* @param datacenterId
* 序列号
*/
public IdWorker(long workerId, long datacenterId) {
if (workerId > maxWorkerId || workerId < 0) {
throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
}
if (datacenterId > maxDatacenterId || datacenterId < 0) {
throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
}
this.workerId = workerId;
this.datacenterId = datacenterId;
}
/**
* 获取下一个ID
*
* @return
*/
public synchronized long nextId() {
long timestamp = timeGen();
if (timestamp < lastTimestamp) {
throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
}
if (lastTimestamp == timestamp) {
// 当前毫秒内,则+1
sequence = (sequence + 1) & sequenceMask;
if (sequence == 0) {
// 当前毫秒内计数满了,则等待下一秒
timestamp = tilNextMillis(lastTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = timestamp;
// ID偏移组合生成最终的ID,并返回ID
long nextId = ((timestamp - twepoch) << timestampLeftShift)
| (datacenterId << datacenterIdShift)
| (workerId << workerIdShift) | sequence;
return nextId;
}
private long tilNextMillis(final long lastTimestamp) {
long timestamp = this.timeGen();
while (timestamp <= lastTimestamp) {
timestamp = this.timeGen();
}
return timestamp;
}
private long timeGen() {
return System.currentTimeMillis();
}
/**
*
* 获取 maxWorkerId
*
*/
protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) {
StringBuffer mpid = new StringBuffer();
mpid.append(datacenterId);
String name = ManagementFactory.getRuntimeMXBean().getName();
if (!name.isEmpty()) {
/*
* GET jvmPid
*/
mpid.append(name.split("@")[0]);
}
/*
* MAC + PID 的 hashcode 获取16个低位
*/
return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1);
}
/**
*
* 数据标识id部分
*
*/
protected static long getDatacenterId(long maxDatacenterId) {
long id = 0L;
try {
InetAddress ip = InetAddress.getLocalHost();
NetworkInterface network = NetworkInterface.getByInetAddress(ip);
if (network == null) {
id = 1L;
} else {
byte[] mac = network.getHardwareAddress();
id = ((0x000000FF & (long) mac[mac.length - 1])
| (0x0000FF00 & (((long) mac[mac.length - 2]) << 8))) >> 6;
id = id % (maxDatacenterId + 1);
}
} catch (Exception e) {
System.out.println(" getDatacenterId: " + e.getMessage());
}
return id;
}
}
1、创建公共子模块ihrm_common_model
2、引入相关依赖
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-jpaartifactId>
dependency>
<dependency>
<groupId>com.ihrmgroupId>
<artifactId>ihrm_commonartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
dependencies>
(1)搭建企业微服务模块ihrm_company, 并且引入相关依赖
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-jpaartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
dependency>
<dependency>
<groupId>com.ihrmgroupId>
<artifactId>ihrm_commonartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
<dependency>
<groupId>com.ihrmgroupId>
<artifactId>ihrm_common_modelartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
dependencies>
(2)添加配置文件application.yml
#服务配置
server:
port: 9001
#spring配置
spring:
#1.应用配置
application:
name: ihrm-company #指定服务名
#2.数据库连接池
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/ihrm?useUnicode=true&characterEncoding=utf8
username: root
password: 12345678
#3.JPA
jpa:
database: MySQL
show-sql: true
open-in-view: true
(3)配置启动类
package com.ihrm.company;
import com.ihrm.common.utils.IdWorker;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.Bean;
//1.配置springboot的包扫描
@SpringBootApplication(scanBasePackages = "com.ihrm")
//2.配置jpa注解的扫描
@EntityScan(value="com.ihrm.domain.company")
public class CompanyApplication {
/**
* 启动方法
*/
public static void main(String[] args) {
SpringApplication.run(CompanyApplication.class,args);
}
@Bean
public IdWorker idWorker() {
return new IdWorker();
}
}
CREATE TABLE `co_company` (
`id` varchar(40) NOT NULL COMMENT 'ID',
`name` varchar(255) NOT NULL COMMENT '公司名称',
`manager_id` varchar(255) NOT NULL COMMENT '企业登录账号ID',
`version` varchar(255) DEFAULT NULL COMMENT '当前版本',
`renewal_date` datetime DEFAULT NULL COMMENT '续期时间', `expiration_date` datetime DEFAULT NULL COMMENT '到期时间', `company_area` varchar(255) DEFAULT NULL COMMENT '公司地区', `company_address` text COMMENT '公司地址',
`business_license_id` varchar(255) DEFAULT NULL COMMENT '营业执照-图片ID', `legal_representative` varchar(255) DEFAULT NULL COMMENT '法人代表', `company_phone` varchar(255) DEFAULT NULL COMMENT '公司电话',
`mailbox` varchar(255) DEFAULT NULL COMMENT '邮箱',
`company_size` varchar(255) DEFAULT NULL COMMENT '公司规模',
`industry` varchar(255) DEFAULT NULL COMMENT '所属行业',
`remarks` text COMMENT '备注',
`audit_state` varchar(255) DEFAULT NULL COMMENT '审核状态',
`state` tinyint(2) NOT NULL DEFAULT '1' COMMENT '状态',
`balance` double NOT NULL COMMENT '当前余额',
`create_time` datetime NOT NULL COMMENT '创建时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
1、实体类
package com.ihrm.domain.company;
import lombok.*;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
import java.util.Date;
/**
* 实体类代码:
* 属性
* 构造方法
* getter,setter方法
*
* lombok 插件 : 使用注解的形式替换getter setter,构造方法
* 如何使用插件
* 1.安装插件(在工程中引入响应的插件坐标即可)
*
org.projectlombok
lombok
1.16.16
* 2.使用注解配置
* 配置到实体类上
* @setter : setter方法
* @getter :getter方法
* @NoArgsConstructor 无参构造
* @AllArgsConstructor 满参构造
* @Data : setter,getter,构造方法
*
* 使用jpa操作数据
* 配置实体类和数据库表的映射关系:jpa注解
* 1.实体类和表的映射关系
* 2.字段和属性的映射关系
* i。主键属性的映射
* ii。普通属性的映射
*/
@Entity
@Table(name = "co_company")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Company implements Serializable {
private static final long serialVersionUID = 594829320797158219L;
//ID
@Id
private String id;
/**
* 公司名称
*/
private String name;
/**
* 企业登录账号ID
*/
private String managerId;
/**
* 当前版本
*/
private String version;
/**
* 续期时间
*/
private Date renewalDate;
/**
* 到期时间
*/
private Date expirationDate;
/**
* 公司地区
*/
private String companyArea;
/**
* 公司地址
*/
private String companyAddress;
/**
* 营业执照-图片ID
*/
private String businessLicenseId;
/**
* 法人代表
*/
private String legalRepresentative;
/**
* 公司电话
*/
private String companyPhone;
/**
* 邮箱
*/
private String mailbox;
/**
* 公司规模
*/
private String companySize;
/**
* 所属行业
*/
private String industry;
/**
* 备注
*/
private String remarks;
/**
* 审核状态
*/
private String auditState;
/**
* 状态
*/
private Integer state;
/**
* 当前余额
*/
private Double balance;
/**
* 创建时间
*/
private Date createTime;
}
2、DAO层
package com.ihrm.company.dao;
import com.ihrm.domain.company.Company;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
/**
* 自定义dao接口继承
* JpaRepository<实体类,主键>
* JpaSpecificationExecutor<实体类>
*/
public interface CompanyDao extends JpaRepository<Company,String> ,JpaSpecificationExecutor<Company> {
}
JpaRepository提供了基本的增删改查 ,JpaSpecificationExecutor用于做复杂的条件查询
3、Service层
package com.ihrm.company.service;
import com.ihrm.common.utils.IdWorker;
import com.ihrm.company.dao.CompanyDao;
import com.ihrm.domain.company.Company;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CompanyService {
@Autowired
private CompanyDao companyDao;
@Autowired
private IdWorker idWorker;
/**
* 保存企业
* 1.配置idwork到工程
* 2.在service中注入idwork
* 3.通过idwork生成id
* 4.保存企业
*/
public void add(Company company) {
//基本属性的设置
String id = idWorker.nextId()+"";
company.setId(id);
//默认的状态
company.setAuditState("0");//0:未审核,1:已审核
company.setState(1); //0.未激活,1:已激活
companyDao.save(company);
}
/**
* 更新企业
* 1.参数:Company
* 2.根据id查询企业对象
* 3.设置修改的属性
* 4.调用dao完成更新
*/
public void update(Company company) {
Company temp = companyDao.findById(company.getId()).get();
temp.setName(company.getName());
temp.setCompanyPhone(company.getCompanyPhone());
companyDao.save(temp);
}
/**
* 删除企业
*/
public void deleteById(String id) {
companyDao.deleteById(id);
}
/**
* 根据id查询企业
*/
public Company findById(String id) {
return companyDao.findById(id).get();
}
/**
* 查询企业列表
*/
public List<Company> findAll() {
return companyDao.findAll();
}
}
4、Controller层
package com.ihrm.company.controller;
import com.ihrm.common.entity.Result;
import com.ihrm.common.entity.ResultCode;
import com.ihrm.common.exception.CommonException;
import com.ihrm.company.service.CompanyService;
import com.ihrm.domain.company.Company;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
//解决跨域问题
@CrossOrigin
@RestController
@RequestMapping(value="/company")
public class CompanyController {
@Autowired
private CompanyService companyService;
//保存企业
@RequestMapping(value="",method = RequestMethod.POST)
public Result save(@RequestBody Company company) {
//业务操作
companyService.add(company);
return new Result(ResultCode.SUCCESS);
}
//根据id更新企业
/**
* 1.方法
* 2.请求参数
* 3.响应
*/
@RequestMapping(value = "/{id}",method = RequestMethod.PUT)
public Result update(@PathVariable(value="id") String id, @RequestBody Company company ) {
//业务操作
company.setId(id);
companyService.update(company);
return new Result(ResultCode.SUCCESS);
}
//根据id删除企业
@RequestMapping(value="/{id}",method = RequestMethod.DELETE)
public Result delete(@PathVariable(value="id") String id) {
companyService.deleteById(id);
return new Result(ResultCode.SUCCESS);
}
//根据id查询企业
@RequestMapping(value="/{id}",method = RequestMethod.GET)
public Result findById(@PathVariable(value="id") String id) throws CommonException {
Company company = companyService.findById(id);
Result result = new Result(ResultCode.SUCCESS);
result.setData(company);
return result;
}
//查询全部企业列表
@RequestMapping(value="",method = RequestMethod.GET)
public Result findAll() {
List<Company> list = companyService.findAll();
Result result = new Result(ResultCode.SUCCESS);
result.setData(list);
return result;
}
}
为了使我们的代码更容易维护,同时给用户最好的用户体验,有必要对系统中可能出现的异常进行处理。Spring提供了@ControllerAdvice注解和@ExceptionHandler可以很好的在控制层对异常进行统一处理
1、创建自定义异常
package com.ihrm.common.exception;
import com.ihrm.common.entity.ResultCode;
import lombok.Getter;
/**
* 自定义异常
*/
@Getter
public class CommonException extends Exception {
private ResultCode resultCode;
public CommonException(ResultCode resultCode) {
this.resultCode = resultCode;
}
}
2、配置公共异常处理
package com.ihrm.common.handler;
import com.ihrm.common.entity.Result;
import com.ihrm.common.entity.ResultCode;
import com.ihrm.common.exception.CommonException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 自定义的公共异常处理器
* 1.声明异常处理器
* 2.对异常统一处理
*/
@ControllerAdvice
public class BaseExceptionHandler {
@ExceptionHandler(value = Exception.class)
@ResponseBody
public Result error(HttpServletRequest request, HttpServletResponse response,Exception e) {
e.printStackTrace();
if(e.getClass() == CommonException.class) {
//类型转型
CommonException ce = (CommonException) e;
Result result = new Result(ce.getResultCode());
return result;
}else{
Result result = new Result(ResultCode.SERVER_ERROR);
return result;
}
}
}
跨域是什么?浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域 。我们是采用前后端分离进行开发的,因此也是前后端分离部署的,必然会存在跨域问题。 那么如何解决跨域?很简单,只需要在Controller类上添加注解@CrossOrigin 即可!这个注解其实是CORS的实现。 CORS(Cross-Origin Resource Sharing, 跨源资源共享)是W3C出的一个标准,其思想是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是成功,还是失败。因此,要想实现CORS进行跨域,需要服务器进行一些设置,同时前端也需要做一些配置和分析。