将数据保存到 xml 中,从 xml 将数据取出来
使用 mina 启动控制台
phonebook--->src--->main--->scala--->
com--->sglnetwork--->phonebook--->
Item.scala 中的代码:
package com.sglnetwork.phonebook.model
import scala.xml._
trait Attrs {
def attrs: Map[String, Any] /* 这个方法可以不用具体实现 */
def toXml = { /* 这个方法主要用 于将字符串转换为 xml 格式 * /
var str = ""
for ((attrName, attrValue) <- attrs) {
str += String.format("<%s>%s</%s>", attrName, attrValue.toString, attrName)
}
val rootName = getClass.getSimpleName
XML.loadString(String.format("<%s>%s</%s>", rootName, str, rootName))
}
override def toString: String = {
val rootName = getClass.getSimpleName
var str = rootName + ": /n"
for ((attrName, attrValue) <- attrs) {
str += String.format("%s: %s/n", attrName,attrValue.toString)
}
str
}
override def equals(that: Any): Boolean = {
that match {
case x: Attrs => attrs == x.attrs
case _ => false
}
}
}
/* 定义 Class 类 ,继承 Attrs */
class Item extends Attrs {
def attrs: Map[String, Any] = Map( /* 实现方法 ,将类的属性放入 Map 中 */
"name" -> name,
"phonenumber" -> phonenumber,
"weburl" -> weburl,
"phone_id" -> phone_id)
var name = ""
var phonenumber = ""
var weburl = ""
var phone_id = ""
}
object Item {
def make(name: String, phonenumber: String, weburl: String = "", phone_id: String = ""): Item = {
val item = new Item
item.name = name
item.phonenumber = phonenumber
item.weburl = weburl
item
}
}
/* 同 Class 类 */
class Phone extends Attrs {
def attrs:Map[String, Any] = Map(
"id" -> id,
"height" -> height
)
var id = "1"
var height = "10"
}
object Phone {
def make(id: String, height: String = "10"): Phone = {
val phone = new Phone
phone.id = id
phone.height = height
phone
}
}
object Database {
val items_file = "item.xml" /*item .xml 文件 */
val phones_file = "phone.xml" /* phone.xml 文件 */
var items: List[Item] = Nil /* 存放所有的 item 对象 */
var phones: List[Phone] = Nil /* 存放所有的 phone 对象 */
def findItemByPhoneNumber(phonenumber: String):Item = { /* 通过手机号码查找用户 */
val list = items.filter(_.phonenumber == phonenumber)
if(list.isEmpty)
new Item
else
list.head
}
def addPhone(id: String, height: String = "10"): Unit = { /* 添加 phone 对象 */
phones = Phone.make(id, height) :: phones ::: Nil
persist /* 调用 该方法,将对象持久化,即把对象存放在 xml 文件中 */
}
def addItem(name: String, phonenumber: String, weburl: String = "", phone_id: String = ""): Unit = {
/* 添加 item 对象 * /
items = Item.make(name, phonenumber, weburl, phone_id) :: items ::: Nil
persist /* 调用 该方法,将对象持久化,即把对象放入 xml 文件中 * /
}
def persist: Unit = { /* 将对象转换为 xml 格式 */
val items_xml = <items>{items.map(_.toXml)}</items>
val phones_xml =<phones>{phones.map(_.toXml)}</phones>
/* 将数据写入 xml 中 */ def writeXmlToFile(xml: String, file_name:String):Unit = {/* 定义方法 :用于将字符串以 xml 格式显示在 xml 文件中 */
import java.io._
val out = new BufferedWriter(new FileWriter(file_name))
out.write(xml)
out.close()
}
/* 调用 write XmlToFile 方法将 items_xml 以 xml 格式保存在 items_file 文件中 */
writeXmlToFile(items_xml.toString, items_file)
writeXmlToFile(phones_xml.toString, phones_file)
}
* 从 xml 中读取数据 */ def preload: Unit = {
/* 加载要读取的 xml 文件 */
val items_xml = XML.loadFile(items_file)
val phones_xml = XML.loadFile(phones_file)
for(elem <- items_xml.child){ /* 循环遍历对象 */
items = Item.make(
(elem / "name").text, // 获得对象的属性值
(elem / "phonenumber").text,
(elem / "weburl").text,
(elem / "phone_id").text
) :: items
}
for(elem <- phones_xml.child){
phones = Phone.make(
(elem / "id").text,
(elem / "height").text
) :: phones
}
}
} Console.scala 中的代码: package com.sglnetwork.phonebook.console import org.apache.mina.core.service.IoAcceptor; import org.apache.mina.transport.socket.nio.NioSocketAcceptor; import org.apache.mina.filter.codec.ProtocolCodecFilter; import org.apache.mina.filter.codec.textline.TextLineCodecFactory; import org.apache.mina.filter.logging.LoggingFilter; import org.apache.mina.transport.socket.nio.NioSocketAcceptor; import java.util.Date import org.apache.mina.core.session.IdleStatus; import org.apache.mina.core.service.IoHandlerAdapter; import org.apache.mina.core.session.IoSession; import java.nio.charset.Charset; import java.net.InetSocketAddress object Console{ val PORT = 8010 def main(argv: Array[String]):Unit = { import com.sglnetwork.phonebook.model._ Database.preload // 每次运行的时候要加载读取数据 val acceptor:IoAcceptor = new NioSocketAcceptor() acceptor.getFilterChain().addLast( "logger", new LoggingFilter() ) acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" )))) acceptor.setHandler( new TimeServerHandler() ); acceptor.getSessionConfig().setReadBufferSize( 2048 ); acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 ); acceptor.bind( new InetSocketAddress(PORT) ); } } class TimeServerHandler extends IoHandlerAdapter{ override def exceptionCaught(session: IoSession, cause:Throwable ):Unit = { cause.printStackTrace(); } import com.sglnetwork.phonebook.model._ override def messageReceived(session:IoSession, message:Any):Unit ={ val str = message.toString(); val trimedStr = str.trim if(trimedStr == "all"){ session.write(Database.items.mkString(":)/n")) /* 将所有对象打印出 */ }else{ import java.io._ val item = Database.findItemByPhoneNumber(trimedStr) Runtime.getRuntime().exec("firefox " + item.weburl); session.write( item.toString );
/* 将制定的对象打印出来 ,并且使用 firefox 打开设置的首页 * /
}
}
override def sessionIdle(session:IoSession, status:IdleStatus):Unit = {
System.out.println( "IDLE " + session.getIdleCount( status ));
}
}
操作 : 1. 打开控制台,找到工程: sbt---> run
2. 新打开一个控制台, telnet localhost 8010
3.all 或者 一个手机号码(若有这个对象,就会到相应的主页)
注解: 特质 trait 是 Scala 里代码复用的基础单元。特质封装了方法和字段的定义 ,
并可以通过混入到 类中重用它们。不像类的继承那样 , 每个类都只能继承唯一的超类 , 类可以混入任意个特质。 一旦特质被定义了 , 就可以使用 extends 或 with 关键字 , 特质而不是继承它们 , 因为特质的混入与那些其它语言
中的多继承有重要的差别。 你可以使用 extends 关键字混入特质 ; 这种情况下你隐式地继承了特质的超类。