3 Star 1 Fork 1

不爱那么多I只爱一点点 / agile-mvc

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
Apache-2.0
logo

agile-mvc

CircleCI Maven Central License


Agile-Framework 系列脚手架致力于帮助开发人员从繁重的代码当中解脱出来,致力于”用最简单的代码勾画出最美的艺术“这一不变的理念。Spring-Agile提供Web开发一站式解决方案。此项目包含Web开发相关的各种必要组件及辅助工具集,方便开发者通过 Agile 编程模型轻松使用这些组件来开发单体应用及分布式应用。 agile-mvc作为agileframework系列框架最初的发展根基,不断开枝散叶,目前已成功衍生出十几个独立、特色化功能开发组件,cloud.agileframework 值得您的期待。

参考文档 请查看 WIKI正在编写中 。

主要功能

  • 几乎为零的代码入侵 agile-mvc组件几乎做到了零规范要求,甚至无感知的开发效果,除声明@AgileService注解(Agile服务层托管)、@Mapping注解(地址映射,也可省略)几乎不需要在我们的代码中出现特殊的Agile代码痕迹,保证了用最原生的java方法,去实现传统mvc三层的所有能力。

  • 抽象化控制层 从传统mvc三层模式中,agile-mvc最突出的特点是提供了抽象控制器MainController ,解决了参数判断、请求跳转、视图组装三部分的功能。省略了大部分控制层代码的冗余,达到一个原生JAVA方法,实现一个API服务的目的。同时由于 0代码入侵的设计理念,也保留了复杂业务逻辑场景下对自定义控制器及服务层复用的支持。所以该功能大大降低了Web项目开发的代码量,以及让其学习成本降至最低,基本达到了 会写java方法,就会编写规范化API的效果。

  • 自动化API地址映射 在spring-mvc中往往需要大量应用诸如RequestMapping、GetMapping之类的地址映射注释,agile-mvc则提供了对@AgileService服务默认的(类名+方法名+模糊化)地址映射规则,所以在非Restful风格api设计的项目当中,甚至可以省略了所有地址映射声明。同时agile-mvc提供了 @Mapping注解,通过Agile内置的AgileMappingHandlerMapping实现在传统Service层中实现@RequestMapping的效果。使用方式无任何差别,确保开发人员零学习成本。

  • 强大的参数解析器 参数解析器由agile系列套件common-util提供参数解析,为spring-mvc扩展了超乎想象的参数解析能力,注入逗号分隔字符串转集合、下划线属性json转pojo对象、多层对象嵌套、不同类型集合数据参数识别、字符串时间语句分析、文件上传、文件输入流等等能力。 将开发人员对参数的复杂类型转换直接省略掉,进一步缩减非业务代码量。

  • 可定制化统一响应模板 agile-mvc提供可自定义响应模板入口,在不同项目中可以定义个性化的统一响应格式,响应头、体信息均可定制。

  • 集成agile-validate参数验证控件: 借助agile系列套件agile-validate方法参数验证组件,实现对springmvc原生控制层方法、@AgileService服务层方法的参数验证注解解析,弥补原生springmvc在参数验证注解方面能力的不足,其中包括了自定义逻辑的业务参数验证的支持。

  • 自动化配置文件掃描 借助common-util的PropertiesUtil工具实现对环境内的任意配置文件扫描,避免了硬编码方式指定配置文件,并在功能初始化阶段以由低到高的优先级对扫描到的配置文件进行打印。该功能解开了在多模块开发过程中配置文件规范的限制,确保模块的扩展过程可携带默认配置。 且配置扫描原则为外层>内层 同层按照命名顺序排列优先级。

  • 统一异常处理 对全局任何异常均做了统一拦截、格式化响应、日志打印

  • 异常、国际化响应报文关联 所有异常均支持国际化配置文件关联,当拦截到异常时,优先获取国际化配置,组装响应报文,以此种方式省略了开发人员对异常情况的处理。可以在程序任何位置直接将业务错误提示以java throw的方式直接返回给前端。

  • 全局异步请求 AgileService代理服务全部使用异步请求处理,开发人员只需编写原生JAVA方法实现异步请求,过期时间灵活可配

  • CORS跨域 内置Cors过滤器,解决前端跨域访问问题。


快速入门

开始你的第一个项目是非常容易的。 简单样例工程地址:https://gitee.com/agile-framework/agile-mvc-demo

步骤 1: 下载包

您可以从[最新稳定版本]下载包(https://github.com/mydeathtrial/agile-mvc/releases). 该包已上传至maven中央仓库,可在pom中直接声明引用

以最新版本agile-mvc-2.1.0.M5.jar为例。

步骤 2: 添加maven依赖

<!--声明中央仓库-->
<repositories>
    <repository>
        <id>cent</id>
        <url>https://repo1.maven.org/maven2/</url>
    </repository>
</repositories>

        <!--声明组件依赖-->
<dependency>
<groupId>cloud.agileframework</groupId>
<artifactId>agile-mvc</artifactId>
<version>2.1.0.M5</version>
</dependency>

步骤 3: 开箱即用

声明agile-mvc依赖后,组件通过spring-boot-starter方式自动加载生效,无需额外配置。组件额外配置,启动后控制台会出现Agile启动标识:


_____/\\\\\\\\\________/\\\\\\\\\\\\__/\\\\\\\\\\\__/\\\______________/\\\\\\\\\\\\\\\_ 
 ___/\\\///////\\\____/\\\//////////__\/////\\\///__\/\\\_____________\/\\\///////////__
  __/\\\_______\/\\\__/\\\_________________\/\\\_____\/\\\_____________\/\\\_____________
   _\/\\\_______\/\\\_\/\\\____/\\\\\\\_____\/\\\_____\/\\\_____________\/\\\\\\\\\\\_____
    _\/\\\\\\\\\\\\\\\_\/\\\___\/////\\\_____\/\\\_____\/\\\_____________\/\\\///////______
     _\/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_____\/\\\_____________\/\\\_____________
      _\/\\\_______\/\\\_\/\\\_______\/\\\_____\/\\\_____\/\\\_____________\/\\\_____________
       _\/\\\_______\/\\\_\//\\\\\\\\\\\\/___/\\\\\\\\\\\_\/\\\\\\\\\\\\\\\_\/\\\\\\\\\\\\\\\_
        _\///________\///___\////////////____\///////////__\///////////////__\///////////////__

 :: 敏捷开发框架 Agile Framework ::  (version:1.0)

警告:2.0.0版本中由于首次于中央仓库发包,忙中出错,默认配置文件加载功能存在设计不足,默认的配置文件加载仅扫描以springboot应用类所在包为根目录 开始扫描,所以自定义包名情况下未能包含框架默认配置包cloud.agileframework.conf,导致默认配置未能加载。所以中央仓库2.0.0版本 使用过程中需增加springmvc对静态资源访问的默认配置,防止静态资源HandlerMapping优先拦截请求,后续版本中去掉了的静态资源的默认配置与限制,修复了该问题:

spring:
  messages:
    basename: '**/message'
  mvc:
    static-path-pattern: /static/**
  resources:
    static-locations: classpath:static/

步骤 4: 声明AgileService代理服务

AgileService代理服务是对传统Service层的功能增强,为传统Service层扩展了直接通过抽象控制器暴漏服务的能力,提高参数验证 控制跳转、组装视图部分的复用程度。并保留传统Service层的能力。以改造前后对比的方式举例:

//传统Service层
@Service
public class MyService {
    public Object myBusinessMethod(String param){
        //业务编码及持久层能力调用...
    }
}

//AgileService代理服务,该注解声明类,仍会被在ComponentScan扫描范围内加载到spring容器中
@AgileService
public class MyService {
    //该方法默认生成API http://host:port/api/MyService/myBusinessMethod
    //该映射地址可以通过@Mapping注解覆盖定义,其用法步骤5中讲解
    //该方法入参将由抽象控制器直接提供请求参数解析装配,并提供@Validation注解校验
    //该方法默认提供spring事务包裹
    //该方法return返回数据,将自动被抽象控制器包装、格式化成统一响应视图,直接返回前端
    public Object myBusinessMethod(String param){
        //业务编码及持久层能力调用...
    }
}

效果对比

传统Service层:仅提供控制层调用能力

AgileService代理服务:1、提供控制层调用能力;2、提供客户端API调用能力;3、参数验证能力;4、默认事务;5、自动包装、格式化成统一响应视图;

步骤 5: AgileService代理服务API地址映射

组件为AgileService代理服务public方法提供了默认的API地址映射方案,也可以通过其他注解进行覆盖、禁用、更改,如

//AgileService代理服务
@AgileService
public class MyService {
    //禁止暴露,该注解也可直接应用于类注解,应用于类注解时,组件将不对声明类内部任何public方法提供能力扩展
    @NotAPI
    public Object myBusinessMethod(String param){
        //业务编码及持久层能力调用...
    }
    
    //限制访问方法,默认不限制请求访问方法,可以通过该注解限定访问方法种类
    @ApiMethod({RequestMethod.POST,RequestMethod.GET})
    public Object myBusinessMethod(String param){
        //业务编码及持久层能力调用...
    }

    //覆盖默认地址映射,当声明@Mapping注解后,组件将不提供给该方法默认地址映射方案
    //该注解使用方法同@RequestMapping完全一致,支持声明地址传参、多地址映射、访问方法等等内容
    @Mapping(path = "/test2/{id}")
    public Object myBusinessMethod(String id){
        //业务编码及持久层能力调用...
    }
}

警告:默认情况下组件会拦截除静态资源以外的所有请求路径,所以需要静态资源地址头应该与正常的API地址区分开,默认使用/static/** 作为静态资源访问头。 更改配置方式如下:

spring:
  mvc:
    static-path-pattern: /static/**

步骤 6: 参数解析

组件为控制层AgileService代理服务提供统一的参数解析能力,该参数解析方案弥补了spring-mvc中对复杂参数方面解析能力的不足 参数解析分声明式直调式两种,声明式优点是无代码入侵,直调式 优点则是更加灵活。

  • 声明式 入参
//body入参为例
{
    "id":111,
    "param":"第二个参数",
    "pojo":{
        "attr1":1,
        "attr2":2
    },
    "collect":[
        {
            "attr1":1,
            "attr2":2
        },
        {
            "attr1":1,
            "attr2":2
        }
    ]
}

声明解析

//AgileService代理服务
@AgileService
public class MyService {
    //参数解析过程将依据方法参数名,如下方法的id、param、pojo为key值,于入参集合中提取后做类型转换并填充
    //其中多层嵌套参数提取,需要通过参数命名中使用下划线区分参数层级,如pojo下的attr1参数,需要使用pojo_attr1命名
    //拍平取参,支持将任意层级参数进行集合拍平处理,如collect_attr1参数
    @Mapping(path = "/test2/{id:[\\d]+}")
    public Object myBusinessMethod(int id,
                            String param,
                            YourPojo pojo,
                            int pojo_attr1,
                            List<Integer> collect_attr1){
        //业务编码及持久层能力调用...
    }
}

直调解析(可于请求线程内任意位置调用AgileParam)

public class MyService {

    public Object myBusinessMethod() {
        Integer id = AgileParam.getInParam("id", Integer.class);
        String param = AgileParam.getInParam("param", String.class);
        YourPojo pojo = AgileParam.getInParam("param", YourPojo.class);
        Integer attr1 = AgileParam.getInParam("pojo.attr1", Integer.class);
        List<Integer> attr1s = AgileParam.getInParam("collect.attr1", new TypeReference<List<Integer>>() {
        });
    }
}

文件上传参数

public class MyService {
    //file为前端传递的文件key值
    public Object myBusinessMethod(MultipartFile file){
    }

    //直接以流方式声明
    public Object myBusinessMethod(InputStream file){
    }

    //多文件
    public Object myBusinessMethod(MultipartFile[] file){
    }

    //可以是MultipartFile的任意集合类型
    public Object myBusinessMethod(Set<MultipartFile> file){
    }
}

警告:

  1. AgileService代理服务中,未增加对原生springmvc中的参数类注解如@PathVariabale@RequestHeader@Validated 等等一类的注解解析。后续会根据 用户反馈考虑增加该部分能力。
  2. AgileParam与请求线程绑定,无法跨线程访问,多线程场景需要先提取参数再自行使用
  3. TypeReference由common-util提供,包为cloud.agileframework.common.util.clazz ,使用时一般为匿名内部类方式,具体方式请参照common-util组件
  4. @Mapping注解是由Agile提供,cloud.agileframework.mvc.annotation.Mapping

步骤 7: 参数验证

该参数验证适用于传统控制层AgileService代理服务,API方式访问时会调用参数验证注解,实现请求拦截。 注解支持声明业务代码方式参数验证,例:

@Validate(value = "file", nullable = false)
@Validate(value = "id", customBusiness = {MyValidate.class})
@Mapping(path = "/test/{id}")
public Object test(int id,MultipartFile[]file){
        //业务代码
        }

//自定义业务验证
public static class MyValidate implements ValidateCustomBusiness {

    //此处params为id值,当验证失败后需要自行组装错误信息List<ValidateMsg>,当错误信息为空集合时,认为参数准确,不进行拦截
    @Override
    public List<ValidateMsg> validate(Object params) {
        return null;
    }
} 

响应报文

{
    "head": {
        "ip": "192.168.101.42",
        "code": "100002",
        "msg": "参数错误",
        "status": "OK"
    },
    "result": [
        {
            "message": "不允许为空值",
            "state": false,
            "item": "file",
            "itemValue": null
        }
    ]
}

步骤 8: 统一响应视图

默认统一响应视图分为头(head)体(result)两部分组成,组件对全局异常以及超范围请求均做了拦截, 并且将最终的拦截结果与国际化配置结合组装成统一响应视图

{
    "head": {
        "ip": "172.29.128.1",
        "code": "100000",
        "msg": "操作失败",
        "status": "INTERNAL_SERVER_ERROR"
    },
    "result": null
}

定制化响应报文

  1. 声明继承于cloud.agileframework.mvc.base.AbstractResponseFormat的模板类
  2. 将其注入到spring容器当中
@Component
public class CommonResponseFormate extends AbstractResponseFormat {
    @Override
    public Map<String, Object> buildResponseData(Head head, Object result) {
        //head为组件整理后的响应头部信息
        //result为响应体信息
        //自行定制返回结果状态为Map格式返回,该Map将作为ModelAndView中的Model组装成视图写入response
        return null;
    }
}

为保证原有控制层的灵活性,以及控制层不存在相互调用的限制,所以统一视图处理器针对控制层AgileService代理服务 有所不同。AgileService代理服务中方法的 return部分将被包裹成响应报文中的result部分返回,头部信息则由是否捕获异常或是否手动设置决定。此处分控制层AgileService代理服务 两种情况举例:

  • 控制层
@Controller
public class MyController{
    @RequestMapping("/test")
    public ModelAndView test(String a) {
        //业务代码...
        //设置响应头head
        AgileReturn.setHead(RETURN.SUCCESS);
        //设置响应体result
        AgileReturn.add("a",a);
        //构建返回视图
        return AgileReturn.build();
    }
}
  • AgileService代理服务

@AgileService
public class MyService {
    //任何return结果都将组装成result部分
    //头部信息则会根据是否捕获Exception异常界定head内部信息,未捕获情况下均使用正常success头
    public Object myBusinessMethod(String param) {
        //业务编码及持久层能力调用...
        return xx;
    }

    //手动设置响应头,返回类型设为RETURN,该方式存在代码入侵,尽在该方法不存在复用情况下使用为好
    public RETURN myBusinessMethod(String param) {
        //业务代码...

        //构建返回视图
        return RETURN.SUCCESS;
    }

    //利用国际化构造响应头head,更多RETURN用法请参照wiki
    public RETURN myBusinessMethod(String param) {
        //业务代码...

        //构建返回视图
        return RETURN.byMessage("国际化key", "国际化参数1", "国际化参数2...");
    }

    //手动设置响应体result
    public void myBusinessMethod(String param) {
        //业务代码...
        //设置响应体result
        AgileReturn.add("a", param);
    }

    //通过异常声明响应头
    //统一一场拦截器捕捉到异常后,会根据异常类引用名去国际化配置文件中获取响应文与响应编码信息,可阅读步骤11统一异常处理
    public void myBusinessMethod(String param) throws YourException {
        //业务代码...
        //设置响应体result
        AgileReturn.add("a", param);
        throw new YourException();
    }
}

步骤 9: 自动配置

借助agile系列套件common-util中PropertiesUtil的配置加载能力,实现在工程启动阶段自动扫描应用类所在包下以及编译路径下配置文件。 避免杂乱的配置文件位置声明。

  • 重点:配置文件加载优先级从编译路径开始计算,层级越深,优先级越低,同层级则按照配置文件名顺序排列 。application配置文件保留最高优先级,优先级越高约被最后加载,覆盖低优先级配置 覆盖方式为内容覆盖,而不是文件覆盖,所以不同内容且文件名相同的配置文件,内容不会存在覆盖关系,仅对相同key值的配置项进行覆盖。项目在启动阶段会于控制台按照由低到高的优先级顺序打印加 载到的配置文件。例如
连接到目标VM, 地址: ''127.0.0.1:56967',传输: '套接字'', 传输: '{1}'
/D:/workspace-agile/agile/target/classes/cloud/agileframework/message.properties
/D:/workspace-agile/agile/target/classes/cloud/agileframework/message_en.properties
/D:/workspace-agile/agile/target/classes/cloud/agileframework/message_zh.properties
/D:/workspace-agile/agile/target/classes/META-INF/additional-spring-configuration-metadata.json
/D:/workspace-agile/agile/target/classes/META-INF/spring-configuration-metadata.json
/D:/workspace-agile/agile/target/classes/META-INF/spring.factories
/D:/workspace-agile/agile/target/classes/static/favicon.ico
/framework/application-agile.yml
/framework/application-alibaba.yml
/framework/application-cache.yml
/framework/application-datasource.yml
/framework/application-druid.yml
/framework/application-ehcache.yml
/framework/application-es.yml
/framework/application-jpa.yml
/framework/application-kafka.yml
/framework/application-kaptcha.yml
/framework/application-log.yml
/framework/application-mvc.yml
/framework/application-redis.yml
/framework/bootstrap.yml
/framework/message.properties
/framework/message_en.properties
/framework/message_zh.properties
/D:/workspace-agile/agile/target/classes/application-agile.yml

配置加载过程不依赖spring,加载后会回填至spring容器,后续PropertiesUtil配置参数提取则优先使用spring容器中有效的environment, 所以该加载过程不影响微服务情况下动态配置管理的使用

步骤 10: 国际化配置

借助Agile套件spring-util工具包中的MessageUtil,为spring的国际化配置文件扫描增加了Ant风格配置文件路径在家支持,并兼容原生配置方式。 原生spring中不支持spring.messages.basename不支持*匹配,agile为其扩展了该功能,并 保留对英文逗号, 的多basename拆分。以message.properties作为国际化配置文件举例,该配置情况下组件将加载任意多层级路径下的message_x_x.properties 作为国际化配置文件,避免了多模块开发场景中复杂的配置文件路径声明。

spring:
  messages:
    encoding: UTF-8
    basename: '**/message'

步骤 11: 统一异常处理

组件通过@ControllerAdvice与HandlerExceptionResolver实现统一异常处理,会将捕获到的任何异常 加工为响应视图,开发者可以针对不同的异常类,定义不同的国际化响应信息。以自定义异常类com.agile.YourException 为例配置方式如下:

com.agile.YourException=100017:无效用户名或密码,请重新登录

其中key部分为异常引用名,value部分为响应码+:+响应文。最终生成的响应头信息如下:

{
    "head": {
        "ip": "192.168.101.42",
        "code": "100017",
        "msg": "无效用户名或密码,请重新登录",
        "status": "INTERNAL_SERVER_ERROR"
    },
    "result": null
}

其中的status部分会根据响应码的首位数字区分响应状态,默认2开头响应码与为配置国际化的异常为服务器异常, 会使用HttpStatus.INTERNAL_SERVER_ERROR 并打印error日志,其余异常均视为后端正常业务异常,使用HttpStatus.OK 并且不打印error日志

龙江银行 输入图片说明 输入图片说明 输入图片说明 输入图片说明

Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

简介

Spring-Agile提供Web开发一站式解决方案 展开 收起
Apache-2.0
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
Java
1
https://gitee.com/agile-framework/agile-mvc.git
git@gitee.com:agile-framework/agile-mvc.git
agile-framework
agile-mvc
agile-mvc
master

搜索帮助