2 Star 4 Fork 1

yixiyun_tech / kuafu

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

KuaFu MVC 开发框架

介绍

夸父 Java Web MVC开发框架,提供极简快速开发。

框架要求

  • JDK11 推荐AdoptOpenJDK
  • Mysql数据库 (目前Sql组件还没适配其他数据库,后面会继续完善)

安装教程

  1. 新建一个maven项目

  2. pom.xml中引入框架jar包

    <dependency>
     <groupId>tech.yixiyun.framework</groupId>
     <artifactId>kuafu-mvc</artifactId>
     <version>0.0.7</version>
     <type>jar</type>
    </dependency>
  3. pom.xml中还需要配置下build

    <build>
    		<resources>
    			<resource>
    				<directory>src/main/resources</directory>
    				<includes>
    					<include>**/*.*</include>
    				</includes>
    
    			</resource>
    		</resources>
    
    		<plugins>
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-compiler-plugin</artifactId>
    				<version>3.8.1</version>
    				<configuration>
    					<source>你的jdk版本,不低于11</source>
    					<target>你的jdk版本,不低于11</target>
    					<encoding>UTF-8</encoding>
    					<compilerArgument>-parameters</compilerArgument>
    				</configuration>
    			</plugin>
    		
    		</plugins>
    	</build>
  4. 创建一个类,写一个main方法,启动项目

    public class Main {
        public static void main(String[] args) {
            TomcatStarter.start();
        }
    }

快速开始

  1. 创建一个Controller类

    import tech.yixiyun.framework.kuafu.controller.BaseController;
    import tech.yixiyun.framework.kuafu.view.View;
    
    /**
     * 演示Demo
     * @author Yixiyun
     * @version 1.0
     * @date 2021-05-16 15:00
     */
    public class DemoController extends BaseController {
    
    
        public View add(){
            return json("name", "zhangsan", "age", 14);
        }
    
    }
     重启下应用,访问 localhost:80/demo/add,就会看到浏览器显示一个json结构的数据了
  2. 按照正常的web项目结构,在webapp文件夹下,创建一个hello.jsp 文件

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
    	<title>Demo</title>
    </head>
    <body>
     Hello Kuafu
    </body>
    </html>
    
  3. 到DemoController中写一个新方法

     public View hello() {
          return jsp("hello");
      }
     重新下应用,访问 localhost:80/demo/hello,就会发现页面被打开了
  4. 框架会自动识别Controller组件,识别的依据就是类上或父类身上是否有@Controller注解。识别为Controller组件后,框架会继续分析它的方法,只要方法是public修饰的,并且返回类型是View的,框架就会自动生成路由映射

    路由对应的url生成规则是:

    1. 如果方法上有@Route注解,就以注解的值作为url
    2. 否则就以 “/基础路径 / 方法名” 作为url。基础路径由@Controller注解决定,BaseController类上有一个默认的@Controller("(a)(!Controller)") (这是一个特殊语法,更多说明请查看@Controller注解的注释),代表类名去掉"Controller"单词后,剩下字符串的第一个字符小写。所以DemoController因为继承了BaseController,它的基础路径就是 "demo"。它的 add方法映射的路由url 就是 "/demo/add",浏览器访问“/demo/add”就会由这个方法处理
  5. 在刚写的hello方法上加一个@Route("/")

    @Route("/")
    public View hello() {
        return jsp("hello");
    }
     现在重启下应用,访问 localhost:80/,就会发现,hello页面被打开了 (注意webapp目录下不要存在index.jsp、index.html等欢迎页)
  6. 在 DemoController 类上加一个 @Controller("abc")

    @Controller("abc")
    public class DemoController extends BaseController {
      ...
    }
     访问 localhost:80/abc/add,就会发现页面显示json数据了
  7. BaseController 提供了很多方便的的方法,例如

    • json(key,value, key,value...) 生成一个json结果的响应,json结果根据传入的键值对生成。
    • json(data) 由传入的一个对象生成json响应
    • jsonSuccess(data) 生成一个{state: SUCCESS, data: data}结构的json响应
    • jsonFail(msg) 生成一个 {state: ERROR, msg: msg}结构的json响应
    • jsp(path) 跳到一个jsp页面,只需要传入jsp在webapp文件夹中的相对路径,可以忽略 .jsp后缀
    • dispatch(path) 转向到一个地址
    • redirect(path) 重定向到一个地址
    • text(content) 返回一个普通文本响应
    • ftl(path) 跳到一个freemarker页面
    • setAttr(key,value) 向request中绑定数据
    • image(byte[]) 返回一个图片
    • download(filename, byte[]) 返回一个文件下载流
    • getRequest() 获取请求对象
    • getResponse() 获取响应对象
    • getSession() 获取session对象
  8. 写一个Service 业务类

    /**
     * 演示Service
     * @author Yixiyun
     * @version 1.0
     * @date 2021-05-15 13:22
     */
    public class DemoService extends BaseService {
    
    
        public void add() {
            LOGGER.info("执行了add方法");
        }
    
    }
  9. 任何类身上有@Service注解,或者父类身上有@Service注解,就会被识别为Service组件。

    注意这里我们使用了LOGGER 日志工具类,它基于log4j2实现,做了优化,无需每个类声明一个静态变量,都用它提供的静态方法记录即可。在框架的默认配置中,它只显示info以上级别的信息,并且输出记录到控制台以及日志文件中。后面会讲到如何修改配置

  10. 在DemoController中注入DemoService实例

    /**
     * 演示Demo
     * @author Yixiyun
     * @version 1.0
     * @date 2021-05-16 15:00
     
    @Controller("abc")
    */
    public class DemoController extends BaseController {
    
        
        private DemoService demoService;
        
        public View add() {
            //在这里调用一下demoService的方法
            demoService.add();
            return json("name", "zhangsan", "age", 14);
        }
    
        ...
    
    }
  11. 重新在浏览器访问下 demo/add,就会发现控制台打印了日志

  12. 只要是框架组件,就会自动识别为Bean,并自动注入,并默认以单例模式实例化。

    如果其他类想被纳入Bean管理,只需要类身上加上@Bean注解,注解可以控制实例化方式和是否懒加载。之后就可以通过BeanContext获取实例了。它也会被其他Bean类自动执行依赖注入。

  13. 接下来开始熟悉配置相关的,我们首先尝试修改一下tomcat的启动端口

    1. 在resources文件夹下新建一个名为 app-config.json 的文件

    2. 然后在文件中,按照 json 的写法写上

      {
        "system": {
          "server": {
            "port":8080
          }
        }
      }
    3. 重启应用,就会发现控制台提示

      ******** ^^^ 应用启动成功 ^^^ 启动地址:http://localhost:8080/ ********

  14. 对于一个项目来说,一般会有两个配置文件,一个是生产环境的,一个是开发环境的。刚才那个 app-config.json 正常来说对应的就是生产环境配置文件,当然你也可以两个环境下都用它。那么如果你想为开发环境另弄一个配置文件怎么办呢?只需要新建一个 app-config-dev.json 配置文件就行了,项目打包时,注意把它移除。一旦框架检测到有 app-config-dev.json,就会优先加载它,忽略 app-config.json. 接下来你我们尝试配置一个开发环境的配置文件,在这个配置里,我们干两个事,一个是tomcat端口改为9090,另一个是将日志的记录级别改为DEBUG,并且让日志不输出到文件,只在控制台打印。

    {
      "system": {
        "server": {
          "port":8080
        },
        "run": {
          "logger": {
            "configuration": { 
    					"loggers": {
    						"logger": [{
    							"name": "kuafuLogger",
    							"level": "debug",
    							"additivity": "false",
    							"AppenderRef": [
    
    								{"ref": "dev_console"}
    							]
    
    						}]
    					}
    				}
            
          }
        }
      }
    }
  15. 你可能会觉得这个日志的配置怎么这么麻烦,这个是log4j2 日志框架官方提供的 json 配置方式,框架本身提供的预配置 其实已经不需要怎么改了,如果就是有特别需要,请自行查阅 log4j2 官方文档进行自定义配置,但一定要注意 ** logger的name 一定不要改名字,除非你不想用框架提供的LOGGER工具类 **

  16. 回到配置文件上,你可能会有疑问,配置为什么要这么写,规则是什么?其实很简单,框架提供了一个预配置 default-config.json 文件,你只需要按照预配置的 json结构,在你的配置文件中去重写你想改变的配置项即可。框架会用 你的配置去覆盖 预配置。下面是default-config.json 的内容

    {
    	"system": {
    		//server相关配置
    		"server": {
    			"port": 80,
    			"contextPath": "/",
    			"connectionTimeout": "60000", //接收到请求后,等待处理的超时时间
    			"listen": "*", //如果服务器有多个网卡,而应用只需要监听某一个网卡的请求,就在这里配置上网卡的hostname或者ip。*代表服务器所有网卡
    			"compress": "off", //是否对文本进行压缩,三个值可用,on、off、force(强制)
    			"protocol": "HTTP/1.1", //暂时支持 HTTP/1.1 、AJP/1.3两种协议 HTTP/2目前未看到明显性能提升,且要求较多
    			"errorPages": { //错误页面,一般只对嵌入式服务器有效
    				"500": "/500.ftl", //发生500时显示的页面
    				"404": "/404.ftl" //发生404时显示的页面
    			}
    		},
    		//启动阶段
    		"boot": {
    
    			"tomcat": { //针对Tomcat内嵌服务器的启动阶段的一些配置
    				"scanJars": false,  //tomcat启动时是否扫描所有jar包,用于TLD和web-fragment扫描,这会增加启动时间
    				"uriEncoding": "UTF-8",
    				"minThread": 10, //tomcat处理请求的最少线程数
    				"maxThread": 200, //tomcat处理请求的并发线程数,超过的请求会被放入等待队列中
    				"maxWaitCount": 100 //最多可等待的请求数,超过后会拒绝请求
    
    			},
    			"preHandler": "" //前置处理器,在启动工作开始前执行的工作
    		},
    		//运行阶段
    		"run": {
    			//开发模式还是生产模式
    			"mode": "dev",
    			//是否启用热加载,需要配合jrebel使用
    			"hotdeploy": false,
    			//是否启用应用监控,用于实时查看服务器和应用的运行状态
    			"monitor": {
    				"enable": true
    			},
    			//请求相关
    			"request": {
    				//是否支持跨域
    				"cors": true,
    				//可以请求的资源路径
    				"resources": {
    					//只有匹配这些规则的请求,才会被框架处理,否则交由Servlet容器处理,语法同Filter的url-pattern语法
    					"include": ["/*"],
    					//在include的基础上,匹配这些规则的请求,将跳过拦截器处理,直接请求。语法同Filter的url-pattern语法
    					"exclude": ["*.ico"]
    				},
    				"session": {
    					"manager": "tech.yixiyun.framework.kuafu.controller.session.ServletSessionManager" //用于获取Session实例的类,需要实现ISessionManager接口
    				},
    				"upload": {
    					"singleMaxSize": 51200, //上传的单文件最大大小,单位K,默认50M
    					"totalMaxSize": 51200, //上传时单次请求最大大小,单位K,默认50M
    					"savePath": "/upload/{date:yyyyMMdd}/{uuid}.{suffix}", //上传文件的默认保存位置,以webroot位置为基准
    					"notAllowSuffix": [ //不允许上传的文件类型
    						//不允许上传的文件类型
    						".exe",
    						".bat",
    						".sh",
    						".dll",
    						".jsp",
    						".php",
    						".jar",
    						".class",
    						".js",
    						".asp",
    						".jspx",
    						".html",
    						".htm",
    						".shtml",
    						".ftl",
    						".py"
    					]
    				}
    			},
    			//模板相关
    			"template": {
    				"freemarker": { //freemarker模板,
    					"config": { //配置项参考文档:https://freemarker.apache.org/docs/api/freemarker/template/Configuration.html#setSetting-java.lang.String-java.lang.String-
    						"ContentType": "text/html; charset=UTF-8",
    						"TemplatePath": "[/,classpath:templates/]",
    						"locale": "zh_CN",
    						"template_exception_handler": "rethrow",
    						"date_format": "yyyy-MM-dd",
    						"time_format": "HH:mm",
    						"datetime_format": "yyyy-MM-dd HH:mm",
    						"template_update_delay": "2000",//单位毫秒,默认5000,开发环境设置低一点,生产环境建议设高
    						"default_encoding": "UTF-8",
    						"number_format": "0.###",
    						"incompatible_improvements": "2.3.30"
    
    					}
    				}
    			},
    			//响应相关
    			"response": {
    
    			},
    			//数据库相关
    			"db": {
    				//事务相关
    				"transaction": {
    					//自动开启事务的方法名前缀
    					"autoOpenPrefix": ["add","modify","del","update","do","save", "create", "alter", "insert"],
    					//默认的事务隔离级别,参考TransactionLevel枚举类中的定义
    					"defaultLevel": "REPEATABLE_READ",
    					//事务执行超时警告,一旦一个事务执行时间超过设定的毫秒值,就打印警告语句
    					"timeoutWarning": 1000
    				}
    			},
    			//日志相关
    			"logger": {
    				"default": "kuafuLogger", //默认使用的记录器
    				"configuration": { //配置参考log4j官网,链接http://logging.apache.org/log4j/2.x/manual/configuration.html#JSON
    					"status": "error",
    					"name": "kuafu",
    					"appenders": {
    						"appender": [
    							{
    								"type": "Console",
    								"name": "console",
    								"PatternLayout": {
    									"pattern": "%-d{MM-dd HH:mm:ss} [%p]-[%C{1}.%M()]: %m %n"
    								}
    							},
    							{ //开发环境用的打印,可以显示颜色
    								"type": "Console",
    								"name": "dev_console",
    								"PatternLayout": {
    									"pattern": "%-d{MM-dd HH:mm:ss} [%highlight{%-5level}{INFO=Magenta, TRACE=White, DEBUG=Blue}]-[%highlight{%C{1}.%M()}{INFO=Magenta, TRACE=White, DEBUG=Blue}]: %highlight{%m%n}{INFO=Magenta, TRACE=White, DEBUG=Blue}"
    								}
    							},
    							{
    								"type": "RollingFile",
    								"name": "file",
    								"fileName": "logs/run.log", //日志文件保存路径
    								"filePattern" : "logs/%d{MM-dd}_%i.log.gz", //分割后的命名规则
    								"PatternLayout": {
    									"pattern": "%-d{MM-dd HH:mm:ss} [%p]-[%C{1}.%M()]: %m %n"
    								},
    								"Policies": {
    									"CronTriggeringPolicy": {
    										"schedule": "0 0 0 * * ? *", //日志每天零点分割一次
    										"evaluateOnStartup": true
    									},
    									"SizeBasedTriggeringPolicy": { "size": "60M" } //单个日志文件超过60M也分割一次
    								},
    								"DefaultRolloverStrategy": {
    									"max": 10 //所有的日志文件最多保留10
    								}
    
    							}
    						]
    					},
    					"loggers": {
    						"logger": [{
    							"name": "kuafuLogger",
    							"level": "info",
    							"additivity": "false",
    							"AppenderRef": [ //默认会向这两个地方写入,上线后,可以不向console写入
    								{
    									"ref": "console"
    								},
    								{
    									"ref": "file"
    								}
    							]
    						}],
    						"root": {
    							"level": "info",
    							"AppenderRef": {
    								"ref": "console"
    							}
    						}
    					}
    				}
    			}
    		},
    		"stop": {
    			//系统停止运行阶段
    		}
    	}
    }
    
    
  17. 你应该会注意到,框架依赖的配置都写在了 system 配置项下,为了和你的项目相关的配置区分开,极力建议你,不要把你的 项目相关的配置写在 system 下,而应该另外建一个 键,例如 app 或者 project

    {
      "system": {
        //这里都是框架依赖的配置项
      },
      "app": {
        //这里写与你项目相关的配置,例如数据库配置、缓存配置等等
      }
    }
  18. 为了方便你从配置文件中读取配置,这里提供了一个AppConfig工具类,它可以根据 key (大部分配置项的key路径我们都在ConfigKey中定义了) 从 所有生效的配置文件中提取配置数据,并转成对应结构,例如

    List<String> prefixs = AppConfig.getAsStringList("system.run.db.autoOpenPrefix");
    Integer port = AppConfig.getAsInt("system.server.port");
    HashMap<String, String> errorMap = AppConfig.getAsStringMap(ConfigKey.SERVER_ERRORPAGES);
  19. 接下来我们创建一个实体类

    package tech.yixiyun.demo.user;
    
    import tech.yixiyun.framework.kuafu.domain.BaseDomain;
    
    import java.util.Date;
    
    /**
     * 用户实体类
     *
     * @author Yixiyun
     * @version 1.0
     * @date 2021-05-17 14:20
     */
    public class User extends BaseDomain {
        //唯一标识
        private Integer id;
        //姓名
        private String name;
        //爱好
        private String favors[];
        //性别,true代表男,false代表女
        private Boolean gender;
        //出生年月日
        private java.sql.Date birthday;
        //记录的创建时间
        private Date createTime;
        
        //getter setter 这里我就不写了,你一定要写上
    
    }
    
  20. 创建完,我们来看一下Controller方法如何自动解析和转换请求参数。回到 hello.jsp 中,我们构建一个表单。

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
    	<title>Demo</title>
    	<style>
    		form {
    			display: flex;
    			flex-direction: column;
    		}
    	</style>
    </head>
    <body>
    <form action="/demo/add" method="post">
    	<label >
    		姓名:
    		<input type="text" name="user.name" />
    	</label>
    	<label >
    		爱好:
    		<input type="checkbox" name="user.favors" value="游泳">游泳
    		<input type="checkbox" name="user.favors" value="健身">健身
    		<input type="checkbox" name="user.favors" value="写代码">写代码
    	</label>
    	<label >
    		性别:
    		<input type="radio" name="user.gender" value="1">
    		<input type="radio" name="user.gender" value="0">
    	</label>
    	<label >
    		出生年月:
    		<input type="date" name="user.birthday" />
    	</label>
    	<label >
    		创建时间:
    		<input type="datetime-local" name="user.createTime" />
    	</label>
    	<button type="submit">提交</button>
    </form>
    </body>
    </html>
    
  21. 可以看出,这个表单最终会提交到 demo/add 这个地址,所以回到 DemoController 的add方法,我们改动一下,把接收到的user对象返回给浏览器

    public class DemoController extends BaseController {
    
        private DemoService demoService;
    
        public View add(User user) {
            demoService.add();
            return json(user);
        }
    
        public View hello() {
            return jsp("hello");
        }
    
    }
  22. 现在可以尝试访问 /demo/hello 打开表单页,然后输入一些信息,点击提交看一下效果了,正常来说你应该能看到一个json结构的字符串,里面正是你提交的数据。如果失败了,请检查下pom.xml 中编译插件是否配置上了 -parameters

  23. 框架会自动解析请求参数,根据请求参数名和方法参数名进行匹对处理。同时,**框架会根据请求的Content-Type,自动判断该如何转化参数,所以即使使用 axios 等库,以application-json形式发起请求,无需任何注解,框架也可正常解析请求参数 **

  24. 接下来我们尝试把数据存储到数据库中,首先我们注册一个数据源,框架提供了阿里的Druid数据源支持,所以这里以注册Druid数据源为例:

    1. 在maven中添加druid依赖和mysql依赖

      <dependency> <!-- 数据库连接池 -->
          <groupId>com.alibaba</groupId>
          <artifactId>druid</artifactId>
          <version>${druid.version}</version>
      </dependency>
      <dependency><!-- mysql-connector-java -->
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>${mysql.version}</version>
      </dependency>
      		
    2. 在app-config-dev.json 配置文件中添加数据源配置

      {
          "app": {
              "datasource": { //数据源配置,注意值都是string类型,不能用其他类型,具体配置项参考 https://github.com/alibaba/druid/wiki/DruidDataSource%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E5%88%97%E8%A1%A8
      			"name": "main", //数据源标识
      			"url": "jdbc:mysql://你的数据库连接?useSSL=false&autoReconnect=true&zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=Asia/Shanghai",
      			"username": "数据库用户名",
      			"password": "数据库密码",
      			"keepAlive": "true"
      		}
          }
      }
    3. 写一个IDataSourceProvider实现类

      public class DataSourceProvider implements IDataSourceProvider {
          @Override
          public DataSourceDefinition[] get() {
              DataSourceDefinition[] definitions = {new DruidDataSourceDefinition("app.datasource")};
              return definitions;
          }
      }
  25. 完成以上步骤,数据源就完成注册了。接着我们来根据Domain类,自动生成表结构,打开DemoController类,写一个方法

    /**
      * 根据Domain类生成或者更新表结构
      * @return
      */
    public View generateTable() {
        DbKit.createOrAlterAllSingleTable();
        return jsonSuccess();
    }

    然后我们重启系统,通过浏览器访问 /demo/generateTable,返回{state:"SUCCESS"} 就代表执行成功,打开数据库我们应该就可以看到创建成功的表了。

  26. 接着我们尝试向数据库添加一条数据,回到DemoService 中的add方法,我们将它改动一下:

    public void add(User user) {
        LOGGER.info("执行了add方法");
        insertOne(user);
    }

    然后改一下DemoController的add方法

    public View add(User user) {
        demoService.add(user);
        return json(user);
    }

    然后我们访问一下 /demo/hello,在页面填写一些数据,点击提交试试效果吧

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.

简介

夸父 Java MVC开发框架,提供极简快速开发。 展开 收起
Java 等 2 种语言
Apache-2.0
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
Java
1
https://gitee.com/yixiyun-tech/kuafu.git
git@gitee.com:yixiyun-tech/kuafu.git
yixiyun-tech
kuafu
kuafu
master

搜索帮助