Qui是一套网页框架,效果不错,不过刚刚接触,难度还是非常大的!完全是新手,这不,到前10分钟才完成一个简单的用户登录。
之前说的JFinal这里要补充一下:玩了这么久,底层的东西虽然都不知道,但是基本会用吧,自认为。。呵呵。
工作环境:myeclipse9,tomcat7,mysql,Navicat。嗯就是这些了吧。
在myeclipse中新建一个web project。新建若干包,这个若干好像比较欠打,不过的确挺多包的。。
包名类里面的类名,可以从Java文件中体现出来,就不多说了。
第一个文件:
package com.my.config;
import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.wall.WallFilter;
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.ext.interceptor.SessionInViewInterceptor;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.plugin.druid.DruidStatViewHandler;
import com.jfinal.render.ViewType;
import com.my.controller.MainController;
import com.my.model.User;
import com.my.util.UrlHistoryHandler;
public class MyBaseConfig extends JFinalConfig {
@Override
public void configConstant(Constants me) {
// TODO Auto-generated method stub
//加载全局配置文件
loadPropertyFile("config.properties"); //加载配置文件
me.setDevMode(getPropertyToBoolean("dev_model"));//从配置文件中获取dev_model参数,此处为true
me.setEncoding(getProperty("encoding")); //从配置文件中获取encoding编码方式,并设置。此处为utf-8
me.setViewType( ViewType.FREE_MARKER); //设置视图类型为FreeMaker
}
@Override
public void configHandler(Handlers me) { //handler方法
me.add(new ContextPathHandler("path"));//加入路径
me.add(new DruidStatViewHandler(getProperty("consle")));//数据监控的路径
me.add(new UrlHistoryHandler());
}
@Override
public void configInterceptor(Interceptors me) {
me.add(new SessionInViewInterceptor());
}
@Override
public void configPlugin(Plugins me) {
DruidPlugin druidPlugin = new DruidPlugin(getProperty("jdbcUrl"),
getProperty("user"), getProperty("password"));
WallFilter wallFilter = new WallFilter();//这个的作用?过滤器?
wallFilter.setDbType(getProperty("db_type"));//数据库类型此处为mysql
druidPlugin.addFilter(wallFilter);
druidPlugin.addFilter(new StatFilter());
me.add(druidPlugin);
ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin);
me.add(arp);
arp.addMapping("user","User_Id",User.class);//参数表:表名,主键,类
arp.setShowSql(true);
}
@Override
public void configRoute(Routes me) {
// TODO Auto-generated method stub
me.add("/", MainController.class);//设置路由
}
}
第一个文件:
package com.my.controller;
import com.jfinal.aop.ClearInterceptor;
import com.jfinal.core.Controller;
import com.my.service.UserService;
import com.my.domain.ReturnJsonObject;
import com.my.model.User;
import com.my.util.GlobalUtils;
public class MainController extends Controller {
UserService userService = new UserService();
@ClearInterceptor //清除清除上一级别(Controller级)的拦截器
public void index(){
/*
* 索引方法,跳转到登录
*/
// render("/_doc/system/login/login.html");//当viewType设置成jsp时还要访问HTML,则用此。
render("/system/login/login.html");
}
@ClearInterceptor
public void login(){
if(getSessionAttr("user")!=null){
/*
* 登录成功,进入系统
*/
render("/system/layout_html/main.html");
}else{
/*
* 登录失败,重新进入登录页面
*/
render("/system/login/login.html");
}
}
@ClearInterceptor
public void checklogin() throws Exception{
ReturnJsonObject rjo = new ReturnJsonObject();
//获得帐号密码清除多余空格
String userName = getRequest().getParameter("username").trim();//.trim()去掉前后多余的空格
String password = getRequest().getParameter("password").trim();
User user = userService.queryForUser(userName, password);
if(user!=null){ //如果user不为空的话,则说明该用户存在。
setSessionAttr("user", user);
rjo.setCode(GlobalUtils.OPERATOR_SUCCESS);
}else{
rjo.setCode(GlobalUtils.OPERATOR_ERROR);
rjo.setMessage("帐号或者密码错误");
}
renderJson(rjo);
/*
* 将 user 对象转换成 json 数据并渲染
* Json是什么玩意?JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。
*/
}
}
第三个文件:
package com.my.domain;
/**
* 返回的JSON对象失败成功
*
*/
public class ReturnJsonObject {
/**
* 操作成功或失败标识
*/
private String code;
/**
* 操作描述信息
*/
private String message;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
package com.my.interceptor;
import com.jfinal.aop.Interceptor;
import com.jfinal.core.ActionInvocation;
public class LoginCheckInterceptor implements Interceptor{
public void intercept(ActionInvocation ai) {
if(ai.getController().getSession().getAttribute("user")!=null){
ai.invoke();
}
else{
ai.getController().setAttr("errorMsg","");
ai.getController().setAttr("errorMsg","请先登录!!");
ai.getController().render("/system/login/login.html");
}
}
}
第五个文件:
package com.my.model;
import com.jfinal.ext.plugin.tablebind.TableBind;
import com.jfinal.plugin.activerecord.Model;
import com.my.model.User;
@TableBind(tableName="user",pkName="User_Id")
public class User extends Model <User> {
public static final User dao = new User();
}
第六个文件:
package com.my.service;
import com.my.model.User;
public class UserService {
/**
* 根据用户名和密码查询用户
* @param userName
* @param password
* @return
*/
public User queryForUser(String userName, String password){
String sqlStr = "select * " +
" from user " +
" where User_Name=? " +
" and User_Password=? ";
User user = User.dao.findFirst(sqlStr, new Object[]{userName,password});
return user;
}
}
还有一个配置文件:放在WEB-INF下
config.properties
dev_model = true
encoding = UTF-8
db_type = mysql
jdbcUrl= jdbc:mysql://localhost:3306/nimei
consle = /_admin/consle
user = nimei
password = nimei
这里有些敏感信息,我都改成nimei了,这是个人习惯勿喷。
还要把数据库部分做好,说一下如何使用Navicat MySQL导入.sql文件。
打开连接,右键相应数据库,在左侧导航栏里选择你要导入的数据库,右击它,选“运行批次任务文件”,然后选择文件。
接下来就是Qui中部分了
可以找到login.html页面。代码需要改动一些部分,如下:
<link href="${path}/system/login/skin/style.css" rel="stylesheet"
type="text/css" id="skin" />
<script type="text/javascript" src="${path}/libs/js/jquery.js"></script>
<script type="text/javascript" src="${path}/libs/js/login.js"></script>
<script type="text/javascript"
src="${path}/libs/js/method/center-plugin.js"></script>
function login() {
var errorMsg = "";
var userName = document.getElementById("username");
var password = document.getElementById("password");
if (!userName.value) {
errorMsg += " 用户名不能为空!";
}
if (!password.value) {
errorMsg += " 密码不能为空!";
}
if (errorMsg != "") {
$(".login_info").html(errorMsg);
$(".login_info").show();
} else {
$(".login_info").show();
$(".login_info").html(" 正在登录中...");
//登录处理
$.post("${path}/checklogin", {
"username" : userName.value,
"password" : password.value
}, function(result) {//result没有声明?为何也能用?已经包含了!
if (result.code == "error") {
$(".login_info").html(result.message);
return false;
} else if (result.code == "success") {
$(".login_info").html("登陆成功,正在跳转到主界面");
window.location="${path}/login";//进入主页面。通过controller中的login方法
}
}, "json");
}
}
这里看重点就好,不要复制粘贴了,显然直接是用不了的。另外登录成功后的页面也要将js的路径设对,按照这种方法改就行,但是只是能用,显然代码还有待提高。
这里有一条语句活活折腾了我10个小时,window.location="${path}/login";没错就是这句。不过真的看起来挺简单的,但是里面的问题很多。前面说的所有东西路由都是在“/qui”下进行的,在这一句上我还是想这么干,但是在JFinal下不管怎么干,经过一次render后,后面的render总是不行。如果把这句直接改成登录成功的页面,个人总是感觉不安全,因为在浏览器中查看源代码找到成功页面的地址后直接输入,就可以成功(除非在HTML中做检查)。所以我还是提交给controller类去处理。
这里有个小技巧:当你发现,出现网页中一些js代码不正确时,可以在浏览器中查看源代码,检查路径是不是对的。
如果上面的代码报错的话,可能你包含的jar不够,我数了一下,我包含的jar,共18个。。自己真是有点吓到了,新手嘛。。。
遇到的问题还是挺多的,稍微整理了一下:
遇到问题:在myeclipse9的情况下使用tomcat7,昨晚还可以运行的web project现在出现404,但是http://localhost:8080可以访问,而且访问的页面是tomcat7的页面,而且以前通过
myeclipse8.5和tomcat6添加得web project依然可以可以访问。
尝试解决方法:1,关闭myeclipse9中的tomcat7,到tomcat7的安装目录中启动tomcat7。
访问8080,tomcat7运行正常。
访问以前添加的web project,运行正常。
访问新添加的web project还是不能运行。
2,重启计算机。
问题情况一致。
3,在该环境下重新导入一份新的工程test_5555,并将config.properties中的URL更改为:jdbc:mysql://localhost:3306/nimei;注意:mysql数据库中有这个数据库。
运行正常。
4,在myeclipse9中将出现问题的web project重新加载进tomcat7。
运行正常,问题解决。
5,不服!将tomcat7重启,观察是否问题再次出现。
运行正常,问题解决。
问题总结:可能是某些误操作,导致问题出现,也有可能是开发环境某一个部分的bug。
遇到的问题还有render系列问题,这里先不整理了。
嗯,就这样。