【JAVAEE】用最快最酸爽最簡單的方式開發Android介面
之前有個哥們給我一個SSM(Spring+SpringMVC+MyBatis)框架的工程,讓我研究研究android介面的快速開發,得知這個很爽的SSM框架後,我開始研究這個工程,後來實驗了半天,作為一個EE小白得到的感受是:
- SSM裡面的配置很多;
- 雖然已經是很簡單很快速的幾個方法幾個介面就KO介面了,但是配置還是很複雜
於是,放棄了.....但是個人認為,對於一些比較大型的專案,可以試用SSM框架來實現介面。好了,下面我來介紹一種十分酸爽的EE框架,對於EE小白來說真的是不錯的東西,配置上面起碼很少,幾乎達到0配置,實現上面也很簡單,對於資料庫的連線上也已經進行了封裝,這個框架就是JFinal,不得不說這框架太牛逼了。
本文適合的物件:
l 對Java EE有一定了解的小白
l 熟悉tomcat伺服器的
l 熟悉mysql資料庫以及sql語句的
什麼是Jfinal框架?
引用下官方的介紹:
JFinal 是基於 Java 語言的極速 WEB + ORM 框架,其核心設計目標是開發迅速、程式碼量少、學習簡單、功能強大、輕量級、易擴充套件、Restful。在擁有Java語言所有優勢的同時再擁有ruby、python、php等動態語言的開發效率!為您節約更多時間,去陪戀人、家人和朋友 :)
Jfinal的特點有什麼?
l MVC架構,設計精巧,使用簡單
l 遵循COC原則,零配置,無xml
l 獨創Db + Record模式,靈活便利
l ActiveRecord支援,使資料庫開發極致快速
l 自動載入修改後的java檔案,開發過程中無需重啟web server
l AOP支援,攔截器配置靈活,功能強大
l Plugin體系結構,擴充套件性強
l 多檢視支援,支援FreeMarker、JSP、Velocity
l 強大的Validator後端校驗功能
l 功能齊全,擁有struts2的絕大部分功能
l 體積小僅339K,且無第三方依賴
Jfinal的官方網站:
開始實踐
說了那麼多,我們開始實踐下這個框架,來驗證下是有多爽,下面會以使用者登入這個簡單的例子來展現如何試用Jfinal框架,使用的請求方式為GET。
準備工作:
1.編寫資料庫,來支撐後臺
這裡我使用的是MySql資料庫,視覺化工具用的是Navicat
這裡我建立了一個叫做coderbase的資料庫,建立時候注意編碼格式一律設定為UFT-8
建立一個使用者表tb_user
欄位如下:
欄位 |
型別 |
含義 |
id |
int |
id自動遞增 |
username |
varchar |
使用者名稱 |
password |
varchar |
密碼 |
nickname |
varchar |
暱稱 |
sex |
int |
性別 |
usertype |
int |
使用者許可權型別 |
|
varchar |
郵箱 |
mobile |
char |
手機號 |
score |
int |
使用者積分 |
token |
varchar |
Token驗證 |
base |
varchar |
備用欄位 |
base |
varchar |
備用欄位 |
base |
varchar |
備用欄位 |
貼下我的sql
DROP TABLE IF EXISTS `tb_user`;
CREATE TABLE `tb_user` (
`id` int(40) NOT NULL AUTO_INCREMENT COMMENT '使用者ID',
`username` varchar(100) CHARACTER SET utf8 DEFAULT NULL COMMENT '使用者名稱',
`password` varchar(100) CHARACTER SET utf8 DEFAULT NULL,
`nickname` varchar(100) CHARACTER SET utf8 DEFAULT NULL COMMENT '暱稱',
`sex` int(2) DEFAULT NULL,
`usertype` int(10) DEFAULT NULL COMMENT '使用者型別',
`email` varchar(50) CHARACTER SET utf8 DEFAULT NULL,
`mobile` char(11) CHARACTER SET utf8 DEFAULT NULL,
`score` int(255) DEFAULT NULL,
`base` varchar(100) CHARACTER SET utf8 DEFAULT NULL,
`base2` varchar(100) CHARACTER SET utf8 DEFAULT NULL,
`base3` varchar(100) CHARACTER SET utf8 DEFAULT NULL,
`base4` varchar(100) CHARACTER SET utf8 DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
插入測試資料
<span style="font-family:SimSun;">INSERT INTO `tb_user` VALUES ('1', '張三', '123', '三', '1', '1', '[email protected]', '1812345678', '12', null, null, null, null);
INSERT INTO `tb_user` VALUES ('2', '2', '2', '2', '2', '2', '2', '2', '2', null, null, null, null);</span>
2.設定tomcat編碼
編輯下你的tomcat目錄下conf/server.xml,新增編碼如果沒有,注意自己新增下
<!-- A "Connector" represents an endpoint by which requests are received
and responses are returned. Documentation at :
Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
Java AJP Connector: /docs/config/ajp.html
APR (HTTP/AJP) Connector: /docs/apr.html
Define a non-SSL HTTP/1.1 Connector on port 8080
-->
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
<strong>URIEncoding="UTF-8"</strong>
redirectPort="8443" />
3.建立新工程,並新增需要的JAR包
新建web工程(Dynamic Web project)
所需的jar包如下,注意貼上到WebContent/WEB-INF/lib下:
- commons-beanutils-1.7.0.jar
- commons-collections-3.1.jar
- commons-lang-2.3.jar
- commons-logging.jar
- druid-1.0.5.jar
- ezmorph-1.0.6.jar
- fastjson-1.1.25.jar
- jfinal-2.2-bin-with-src.jar
- json-lib-2.1.jar
- mchange-commons-java-0.2.3.4.jar
- mysql-connector-java-5.1.6-bin.jar
- servlet-api.jar
上述jar下載地址:
有了這些就可以開始敲程式碼了。
1.建立入口類MyAppConfig
新建config包,並新建MyAppConfig類且繼承JFinalConfig
<span style="font-family:SimSun;">import com.jfinal.config.Constants;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors;
import com.jfinal.config.JFinalConfig;
import com.jfinal.config.Plugins;
import com.jfinal.config.Routes;
public class MyAppConfig extends JFinalConfig{
@Override
public void configConstant(Constants me) {
// TODO Auto-generated method stub
}
@Override
public void configRoute(Routes me) {
// TODO Auto-generated method stub
}
@Override
public void configPlugin(Plugins me) {
// TODO Auto-generated method stub
}
@Override
public void configInterceptor(Interceptors me) {
// TODO Auto-generated method stub
}
@Override
public void configHandler(Handlers me) {
// TODO Auto-generated method stub
}
}
</span>
其中:
public void configConstant(Constants me)
用於設定全域性的設定如編碼等
public void configRoute(Routes me)
用於設定路由地址,訪問地址
public void configPlugin(Plugins plugins)
用於配置一些外掛,如連線資料的外掛
public void configInterceptor(Interceptors me)
用於配置攔截器
public void configHandler(Handlers me)
用於配置全域性攔截器
基本配置如下:
<span style="font-family:SimSun;">import com.jfinal.config.Constants;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors;
import com.jfinal.config.JFinalConfig;
import com.jfinal.config.Plugins;
import com.jfinal.config.Routes;
import com.jfinal.ext.handler.ContextPathHandler;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.render.ViewType;
import com.myapp.controller.LoginController;
import com.myapp.controller.RegisterController;
import com.myapp.module.User;
/**
* 配置類
*
* @author zhang
*
*/
public class MyAppConfig extends JFinalConfig {
@Override
public void configConstant(Constants me) {
// 設定為開發模式
me.setDevMode(true);
// 設定編碼為UTF-8
me.setEncoding("utf-8");
// 設定View型別為JSP
me.setViewType(ViewType.JSP);
}
@Override
public void configRoute(Routes me) {
}
@Override
public void configPlugin(Plugins plugins) {
}
@Override
public void configInterceptor(Interceptors me) {
}
@Override
public void configHandler(Handlers me) {
me.add(new ContextPathHandler("basePath"));
}
}</span>
配置web.xml檔案,路徑在WebContent/WEB-INF/,注意如果沒有web.xml新建一個,配置如下:
<span style="font-family:SimSun;"><?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<!-- 配置專案名稱 -->
<display-name>API</display-name>
<!-- 配置預設首頁 -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- 過濾器 -->
<filter>
<filter-name>jfinal</filter-name>
<filter-class>com.jfinal.core.JFinalFilter</filter-class>
<init-param>
<param-name>configClass</param-name>
<param-value>com.myapp.config.MyAppConfig</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>jfinal</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 過濾器配置完畢 -->
</web-app></span>
配置log4j日誌系統,新建log4j.properties:
<span style="font-family:SimSun;">log4j.rootLogger=INFO, stdout, file
log4j.appender.stdout.Target=System.out
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%n%-d{yyyy-MM-dd HH:mm:ss}%n[%p]-[Thread: %t]-[%C.%M()]: %m%n
# Output to the File
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=./web.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%n%-d{yyyy-MM-dd HH:mm:ss}%n[%p]-[Thread: %t]-[%C.%M()]: %m%n
# Druid
log4j.logger.druid.sql=warn,stdout
log4j.logger.druid.sql.DataSource=warn,stdout
log4j.logger.druid.sql.Connection=warn,stdout
log4j.logger.druid.sql.Statement=debug,stdout
log4j.logger.druid.sql.ResultSet=warn,stdout
</span>
配置JDBC,新建Config.properties,並加入以下內容,注意修改:
<span style="font-family:SimSun;">driver =com.mysql.jdbc.Driver
jdbcUrl=jdbc:mysql://你的資料庫地址:3306/資料庫名字?characterEncoding=utf-8
user=root //使用者名稱
password=123456 //密碼
initialSize=1
minIdle=1
maxActivee=20</span>
除此之外,還需要在MyAppConfig.java檔案中對JDBC進行配置,配置的程式碼需要放在configPlugin方法中,有兩個外掛可以快速連線資料庫,分別為C3P0,還有Druid,個人比較傾向於使用Druid,以Druid為例來進行JDBC連線配置,配置的程式碼如下:
// 配置JDBC連線
PropKit.use("Config.properties");
final String URL = PropKit.get("jdbcUrl");
final String USERNAME = PropKit.get("user");
final String PASSWORD = PropKit.get("password");
final Integer INITIALSIZE = PropKit.getInt("initialSize");
final Integer MIDIDLE = PropKit.getInt("minIdle");
final Integer MAXACTIVEE = PropKit.getInt("maxActivee");
// Druid外掛
DruidPlugin druidPlugin = new DruidPlugin(URL, USERNAME, PASSWORD);
druidPlugin.set(INITIALSIZE, MIDIDLE, MAXACTIVEE);
druidPlugin.setFilters("stat,wall");
plugins.add(druidPlugin);
ActiveRecordPlugin activeRecordPlugin = new ActiveRecordPlugin(druidPlugin);
plugins.add(activeRecordPlugin);
下一步進行分包
l 新建一個controller包,用於存放主要邏輯
l 新建一個module包,用於存放實體類
l 新建一個service包,用於存放資料庫的操作
l 新建一個utils包,用於存放工具類
2.編寫介面
以登入為例子來展示如何編寫介面:
1.加入路由配置
l 首先新建LoginController.java檔案在Controller包中,並實現com.jfinal.core.Controller類;
l 在MyAppConfig中的configRoute方法中加入路由配置,me.add("/", LoginController.class);第一個引數制定的值訪問時候的一個分類一樣的東西,例如你寫成/login和/時候訪問時候就會變成如下形式:
http://localhost:8080/專案名稱/login/......(/login)
http://localhost:8080/專案名稱/......(/)
第二個引數指的是哪個類來實現這個邏輯。
3.實現LoginController類
例如你要實現登入的動作,可以新建一個方法,訪問時候直接訪問該方法即可,例如我新建的方法名字叫做LoginAction,所以我在訪問時候就可以這樣來呼叫這個登入動作:
http://localhost:8080/專案名稱/LoginAction
所以這是方法名稱的含義;其次就是獲取get請求引數的方法為
this.getPara(String param)方法,裡面的引數就是get請求時候的引數,當用戶登入成功或失敗時候,需要使用this.renderJson(Object obj)方法來實現json資料的反饋,其中User userModule = LoginService.getUserInfo(user, pwd);這一句的意思我們拿到後面來說,LoginController的具體程式碼如下:
package com.myapp.controller;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.core.Controller;
import com.myapp.module.User;
import com.myapp.service.LoginService;
/**
* 登入動作
* http://localhost:8080/API/login/LoginAction?username=zhangsan&password=123
*
* @author zhang
*
*/
public class LoginController extends Controller {
/**
* 登入動作
*/
public void LoginAction() {
String user = this.getPara("username");
String pwd = this.getPara("password");
User userModule = LoginService.getUserInfo(user, pwd);
JSONObject object = new JSONObject();// 外層json
JSONObject infos = new JSONObject();// 成功以後的使用者資訊
JSONArray data = new JSONArray();// 承載使用者資訊的array
if (userModule == null) {// 使用者名稱或密碼錯誤
object.put("errorCode", 0);
object.put("msg", "使用者名稱或密碼錯誤");
object.put("data", data);
this.renderJson(object);
} else if (userModule != null && !userModule.get("password").equals(pwd)) {// 密碼錯誤,請核對
object.put("errorCode", 0);
object.put("msg", "密碼錯誤,請核對");
object.put("data", data);
this.renderJson(object);
} else {// 登入成功,返回成功登入資訊
object.put("errorCode", 1);
object.put("msg", "登入成功");
// 使用者資訊
infos.put("username", userModule.get("username"));
infos.put("nickname", userModule.get("nickname"));
infos.put("sex", userModule.getInt("sex"));
infos.put("usertype", userModule.getInt("usertype"));
infos.put("nickname", userModule.get("nickname"));
infos.put("mobile", userModule.get("mobile"));
infos.put("score", userModule.getInt("score"));
infos.put("token", LoginService.insertTOKEN(user));
// 新增值data陣列中
data.add(infos);
object.put("data", data);
this.renderJson(object);
}
}
}
4.實現實體類
Jfinal在實體類上面我覺得應該是最爽的了,首先在module類中新建一個User.java類,並繼承Model,在泛型中加入User類本身,這樣一個實體類就寫好了,至於為什麼要繼承Model這個類,應該做過開發的同學很清楚,實體類中一般會有資料庫表對應的欄位或getset方法,但是在Jfinal中完全可以不寫這些東西,在MyAppConfig類中設定表對映關係即可實現getset方法,而且這個過程是自動實現的!下面給出User類的實現程式碼:
package com.myapp.module;
import com.jfinal.plugin.activerecord.Model;
/**
* 使用者表
* @author zhang
*
*/
@SuppressWarnings("serial")
public class User extends Model<User>{
}
編寫好User以後來實現下對映關係,到MyAppconfig的configPlugin方法中在新增外掛之前的這句話上面(plugins.add(activeRecordPlugin);),新增對映關係
activeRecordPlugin.addMapping("tb_user","id", User.class);
這三個引數分別是,表名,主鍵,以及對應的實體類是哪一個,這樣實體類就配置好了。
5.實現LoginService邏輯
在上面說到
User userModule = LoginService.getUserInfo(user, pwd)
這句話,這句話的意思是需要獲取到指定使用者名稱密碼的使用者的使用者資訊,如果存在的話,就會返回資料庫表中的資訊;如果不存在的話就會返回空null給User,所以後面的判斷都是根據的這個實體類來實現的,首先需要判斷資料庫中這個使用者資訊是否存在,存在的話再返回給User來使用,所以來看下LoginService.getUserInfo該類下的該方法是如何實現的;
首先新建一個LoginService在service包下,並建立getUserInfo方法,具體程式碼以及說明如下:
package com.myapp.service;
import com.jfinal.plugin.activerecord.Db;
import com.myapp.module.User;
import com.myapp.utils.TokenUtil;
/**
* 登入的動作
*
*/
public class LoginService {
/**
* 獲取使用者資訊
*
* @return
*/
public static User getUserInfo(String username, String pwd) {
String sql = "SELECT * FROM tb_user WHERE username=?";// sql語句中?可以防止sql注入,多引數多?
User user = new User().findFirst(sql, username);// 使用findFirst來實現指定查詢,並且查詢到的資料會以反射的形式來給User實體類
return user;// 返回User實體類
}
/**
* 插入token驗證
*
* @return
*/
public static String insertTOKEN(String username) {
String key = TokenUtil.generalKey();
String sql = " UPDATE tb_user SET token=? WHERE username=?";
Db.update(sql, key, username);//不關聯任何實體類的方法,其中有增刪改查方法,可以自己來實現下看看
return key;
}
}
到次,就編寫完畢了,可以執行下試試看了,執行結果如下:
專案Demo下載地址:
推薦的文章,可以一起深入學習: