前言
其实我是做Android的,当时想自己写一个服务端,于是抽时间就学习了以下JavaEE的 Hibernate框架和Struts框架,不得不承认的是,站在巨人的肩膀上的确可以看得更远,有助于自己的水平提高。
首先我们先介绍以下hibernate和Struts的主要是做什么的,以便于讲解,Hibernate是javaEE访问数据库的持久化方案,无需写SQL语句即可进行对数据的访问,但是一点需要配置很多参数。Struts2是代替Servlet的解决方案,其根本的原理是通过filter过滤器进行的封装,支持拦截器,标签库等功能,功能强大,但是听说有些漏洞,目前用的不是很多。
我的思路其实比较简单,通过Android的网络请求,来访问web项目 ,Struts2 接受请求,调用Hibernate框架进行判断,在数据库中是否存在这个用户,如果存在返回true 否则返回false ,其中Android和strut2之间的数据传递使用的JSON传递的。我使用的开发环境是Android+IDEA好了,进入正题。
创建JavaEE项目
创建一个新的项目
勾选上所要使用的框架,选择在线下载
给项目起个名称并指定项目存放的位置。点击完成即可
好了到此为止,一个javaweb项目就算创建完成了。
项目结构
其中lib 是所依赖的jar包,在创建项目的时候回自动下载所需要的jar包,但是下载的jar包不全,所以待会还要补充。src 目录是java代码的文件夹,web是web应用的根目录,其中包含一个web.xml配置文件和WEB-INF文件夹,我们需要在WEB-INF文件夹中创建一个lib文件夹,然后把待会需要导入到lib的所有的jar包都复制到这个文件夹中,这样做的目的是为了防止在开发中报找不到类的异常。
这就是所有的jar包,我使用的数据库是SQL server2008 所以驱动jar包是sqljdbc ,大家可以根据自己的数据库进行下载所使用的jar包。将以上的jar包复制到WEB-INF文件夹下的lib中右键添加为库。
ok,准备工作已经差不多了,现在就开始写代码。
首先,我们需要知道struts2是如何使用的,现在就来告诉大家如何简单的配置Struts2 ,首先我们知道,struts2的原理是filter筛选器封装的框架,所以我们先要在web目录的Web.xml文件来声明。如果不声明,struts2框架相当于没有导入到自己的项目中去,
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<filter>
<!--声明filter的名称-->
<filter-name>struts2</filter-name>
<!--加载的类,核心类-->
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<!--filter拦截属性名称-->
<filter-name>struts2</filter-name>
<!--拦截所有的请求-->
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
然后,我们继续配置struts2的配置文件。配置文件的位置在项目的src目录下,找到这个配置文件打开。
这个是约束,类似于java的导入包。不然找不到所引用的属性。
<struts>
<!--设置国际化,作用解决乱码-->
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
<!--创建包,继承 struts2默认和struts2 json ,命名空间为。hello-->
<package name="login" extends="struts-default,json-default" namespace="/hello">
</package>
</struts>
先创建一个包,这个包有3个属性必须指定
- name属性,这个属性是一个标识符,方便查找这个包以及下面的Action。
- extends属性:学过java的都知道这个属性是继承的意思,struts2需要继承Struts2框架默认提供的属性,后面的json-default是我后来加上的,为了方便处理返回json数据。这个属性还需要配置一个属性,待会说。
- namespace属性:顾名思义,这个属性是一样命名空间,长话短说,也就是访问的url。
Ok,目前,已经成功了一半了,下面来创建Action。
Action
首先说明一下,struts2 访问是通过Action来实现的,你可以包action理解为一个Servlet。他的主要作用就是来接受请求的,struts2通过映射来处理Action的。
创建一个包,包里包含2个java类。
package login;
import model.User;
import utils.HibernateUtils;
import utils.JsonUtils;
import com.opensymphony.xwork2.ActionSupport;
//模型驱动的方式获取请求参数
public class LoginAction extends ActionSupport{
public boolean isRequest() {
return request;
}
public void setRequest(boolean request) {
this.request = request;
}
public boolean request;
/**
* 原因: json的插件和gson 冲突
* @return
* @throws Exception
*/
@Override
public String execute() throws Exception {
//解析返回user对象
User user= JsonUtils.JsonFomrt(JsonUtils.getRequestDate());
System.out.println(user.getUser()+" "+user.getPassword());
boolean s=HibernateUtils.exist(user);
System.out.println(s);
// 通过映射result返回结果
if(s){
request=true;
}else {
request=false;
}
System.out.println(request);
return SUCCESS;
}
}
当客户端的请求发送到服务器时,struts进行拦截,根据不同的url,访问不同的Action 上面的Action时登入的Action,它的作用就是当接受到客户端传递的参数是进行处理。其中execute方法就是处理的方法。因为客户端传递的是json数据,所以需要封装处理json数据。User 是封装的请求对象参数 JsonUtils是封装的解析json的方法,下面的是hibernate访问数据库的操作,hibernate访问数据库的操作等会再说。
User对象的代码:
package model;
public class User {
private int Sid;
private String user ;
private String password;
public int getSid() {
return Sid;
}
public void setSid(int sid) {
Sid = sid;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
下面是解析JSON的工具类
package utils;
import model.User;
import com.google.gson.Gson;
import org.apache.struts2.ServletActionContext;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
public class JsonUtils {
/**
* 解析Json 返回对象Login
* @param Json
* @return
*/
public static User JsonFomrt(String Json){
// 创建Gson对象
Gson gson=new Gson();
// 通过gson对象将json字符串解析为User对象
User user=gson.fromJson(Json,User.class);
// 返回这个对象
return user;
}
/**
* 获取客户端的输入流转换为json数据
*/
public static String getRequestDate(){
// 获取请求参数对象
HttpServletRequest httpServletRequest= ServletActionContext.getRequest();
// 创建StringBuffer
StringBuffer buffer=new StringBuffer();
try{
String json="";
// 读取
BufferedReader reader=httpServletRequest.getReader();
while((json=reader.readLine())!=null){
// 写入
buffer.append(json);
}
// 返回
return buffer.toString();
}catch (Exception e){
}
return null;
}
上面的Action已经创建完成,但是这样的action还是无法使用,因为他还没有在Action中进行配置,下面我们对所创建Action进行配置。在Struts2.xml文件中进行配置,添加以下代码:
<!--访问的Action名称,这个name属性是通过url访问的资源的,class 具体是哪个类进行相关的处理-->
<action name="loginAction" class="login.LoginAction">
<!--访问的结果,type防护结果类型,name:这个name属性是execute返回的值如果是这个值就返回以下结果-->
<result type="json" name="success">
<!--可以设置返回结果类型而不是将整个action返回-->
<param name="root">
request
</param>
</result>
</action>
<action name="registerAction" class="login.RegisterAction" >
<result type="json" name="success">
<!--可以设置返回结果类型而不是将整个action返回-->
<param name="root">
request
</param>
</result>
</action>
</package>
上面的配置就算是基本完成了Struts2的参数处理,但是可能会有人问,为什么我的struts-json-default 报红?有错误,下面我们就来处理下这个问题。
把这个添加上去就可以了,很神奇,问题解决了,哈哈。上面的是Struts2的基本配置以及请求参数接受处理,到目前为止,算是解决了。下面我们来讲一下Hibernate框架的使用。
Hibernate框架
前面已经介绍了Struts2的使用以及配置,但是只接受参数还是不够的,我们还要通过动态的数据库访问进行注册查询,所有需要使用到Hibernate数据库持久化框架先来介绍下这个框架怎么使用。
在第一步的时候我们已经把所有要使用的包全部导入到了lib目录中。现在还需要创建两个配置文件。配置文件的路径是在src目录下的。
先来介绍下这两个配置文件 cfg的时Hibernate框架的配置文件,需要的参数会在里面标明,hbm是数据库映射对象和Hibernate的配置文件。何为持久化?简单来说就是从数据库中加载一行记录,用这一行记录生成一个java对象,这个java对象的值就是取自数据库,动态操作这个对象可以进行对数据库的更新,删除,添加等操作。在处理对象的过程中我们不需要手写SQL语句,这就是Hibernate框架的强大。
hibernate.cfg.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<!--hibernate的主配置文件-->
<hibernate-configuration >
<session-factory>
<!--设置数据库连接基本信息-->
<!--连接用户名称-->
<property name="connection.username">sa</property>
<!--连接密码-->
<property name="connection.password">123</property>
<!--连接驱动-->
<property name="connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
<!--设置url-->
<property name="connection.url">jdbc:sqlserver://localhost:1433;DatabaseName=MyProject</property>
<!--配置hibernate的基本信息-->
<!--hibernate所使用的数据库方言-->
<property name="dialect">org.hibernate.dialect.SQLServer2008Dialect</property>
<!--执行时是否在控制台打印sql-->
<property name="show_sql">true</property>
<!--是否对SQL进行格式化-->
<property name="format_sql">true</property>
<!--指定是否自动生成数据库表-->
<property name="hbm2ddl.auto">update</property>
<!--添加实体关系映射文件,这个文件需要放在src目录下-->
<mapping resource="hibernate.hbm.xml"></mapping>
</session-factory>
</hibernate-configuration>
可能有的小伙伴对数据库方言不理解,我解释一下,我们所使用的数据库虽然都是用的SQL语句,但是每一个数据库之间还是会有些语句的差异的,例如Oracle和MySQL,sql Server2008 具体到细节上还是会有些差异的我们指定这个属性,相当于指定数据库查询是所使用的SQL语句。
下面来说下Hibernate.hbm.xml文件
<hibernate-mapping>
<class name="model.User" table="Userer">
<!--配置主键映射-->
<!--name:实体类属性名 ,column:数据表的字段名称 type:数据类型-->
<!--配置主键映射-->
<!--name:实体类属性名 ,column:数据表的字段名称 type:数据类型-->
<id name="sid" type="java.lang.Integer">
<!--对应的数据表-->
<column name="sid"></column>
<!--设置主键的生成方式,递增,每添加一条路径sid的值会递增所以不会重复-->
<generator class="identity"></generator>
</id>
<!--指定对象与表的映射-->
<property name="password" type="java.lang.String">
<column name="password"></column>
</property>
<property name="user" type="java.lang.String">
<column name="user_name"></column>
</property>
</class>
</hibernate-mapping>
我们创建的user对象是和这个表对应的,ok,hibernate配置完成。
前面我们已经将了struts接受参数,下面我们来写具体处理数据和访问数据库的代码。
回到Action:
@Override
public String execute() throws Exception {
//解析返回user对象
User user= JsonUtils.JsonFomrt(JsonUtils.getRequestDate());
// 输出请求参数的值
System.out.println(user.getUser()+" "+user.getPassword());
// 通过访问数据库查询这个用户是否存在,存在返回true 否则返回false
boolean s=HibernateUtils.exist(user);
// 打印返回结果
System.out.println(s);
// 返回结果进行判断
if(s){
request=true;
}else {
request=false;
}
// result是要返回客户端的。在struts2配置文件中已经解释了
System.out.println(request);
return SUCCESS;
}
Hibernate处理工具类进行数据库访问的代码:
public class HibernateUtils {
/**
* 初始化
* @return
*/
public static Session init(){
// 获取设置对象
Configuration configuration=new Configuration();
// 对象加载配置文件
configuration.configure();
// 获取Session工厂类
SessionFactory factory=configuration.buildSessionFactory();
// 获取一个session
Session session= factory.openSession();
// 返回Session
return session;
}
/**
* 向数据库中添加一条记录
* @param user
*/
public static void add(User user){
// 获取Session
Session session= HibernateUtils.init();
// 获取事物
Transaction tx=session.beginTransaction();
// 保存对象
session.save(user);
// 提交事物
tx.commit();
// 关闭Session
session.close();
// 关闭session工厂
session.getSessionFactory().close();
}
/**
* 查询数据库
* @param user
* @return
*/
public static boolean exist(User user){
Session session=HibernateUtils.init();
Transaction transaction=session.beginTransaction();
// Hibernate的HQL语句查询指定的值,:为占位符
Query query=session.createQuery("from User as U where U.user=:user and U.password=:pass");
// 设置占位符的值
query.setParameter("user",user.getUser());
query.setParameter("pass",user.getPassword());
List<User> users=query.list();
// 判断集合是否有数据
if (users.size()!=0){
for (User a: users) {
System.out.println(a.getUser()+" "+a.getPassword());
}
// 如果存在返回true
transaction.commit();
session.close();
session.getSessionFactory().close();
return true;
}else {
// 否则返回false
transaction.commit();
session.close();
session.getSessionFactory().close();
return false;
}
}
到此为止,我们已经完成了服务端的请求处理以及访问数据库的操作,上面说的是注册的代码,原理同上面:
public class RegisterAction extends ActionSupport {
public boolean isRequest() {
return request;
}
public void setRequest(boolean request) {
this.request = request;
}
public boolean request;
//添加
@Override
public String execute() throws Exception {
User user= JsonUtils.JsonFomrt(JsonUtils.getRequestDate());
System.out.println(user.getUser()+" "+user.getPassword());
boolean s=HibernateUtils.exist(user);
System.out.println(s);
if (s){
request=false;
}else {
request=true;
HibernateUtils.add(user);
}
return SUCCESS;
}
}
到目前为止我们的服务端已经全部写完,谢谢大家的观看。有不足的地方还请多多指教。下次更新写Android端请求过程,以及实现登入的效果。