• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

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

原作者: [db:作者] 来自: 网络 收藏 邀请

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>	 

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap