顯示具有 JAVA 標籤的文章。 顯示所有文章
顯示具有 JAVA 標籤的文章。 顯示所有文章

2012年4月16日 星期一

Jjava 記憶體參數說明

JVM的記憶體空間如下:

(出處:http://www.sapgeek.net/2010/11/java-jvm-memory-structure/)



METHOD AREA:存放要載入類別的各種資訊,當要使用的記憶體超出允許的大小時,會抛出OutOfMemory的錯誤資訊,在JDK中這塊區域對應Permanet Generation,預設最小值為16MB,最大值為64MB,可透過-XX:PermSize-XX:MaxPermSize來指定最小值和最大值!

HEAP:Heap用於儲存物件實例及陣列值,可認為Java中所有透過new建立物件都在此分配,在32bit電腦上最大限制為2GB,64bit無此限制,可透過-Xms-Xmx控制!HEAP有包含New Generation及Old Generation:

  • New Generation:可透過-Xmn指定大小
  • Old Generation:即-Xmx減去-Xmn的大小
NATIVE METHOD STACK:儲存每個native method呼叫的狀態,如C

JAVA STACK & PROGRAM COUNTER REGISTER:PC REGISTER存放的為CPU暫存器或OS記憶體;JAVA STACK存放的為OS記憶體,當JAVA STACK不足時會抛出StackOverflowError,可透過-Xss指定大小!

JDK參數設定策略:

一般設置

java -Xmx3550m -Xms3550m -Xmn2g -Xss128k
-Xmx3550m:設置JVM最大可用記憶體為3550M.
-Xms3550m:設置JVM促使記憶體為3550m.此值可以設置與-Xmx相同,以避免每次垃圾回收完成後JVM重新分配記憶體.
-Xmn2g:設置New Generation大小為2G.整個stack大小 = New Generation + Old Generation
!此值對系統性能影響較大,Sun官方推薦配置為整個堆的3/8
-Xss128k:設置每個執行緒的Stack大小。JDK5.0以後每個執行緒Stack大小為1M,以前每個執行緒Stack大小為256K!更具應用的執行緒所需記憶體大小進行調整。在相同實體記憶體下!減小這個值能生成更多的執行緒。但是作業系統對一個進程內的執行緒數還是有限制的。不能無限生成,大約在3000~5000左右。


java -Xmx3550m -Xms3550m -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxPermSize=16m -XX:MaxTenuringThreshold=0
-XX:NewRatio=4
:設置New Generation (包括Eden和兩個Survivor)Old Generation的比值.設置為4,則New GenerationOld Generation所占比值為1:4New Generation占整個Stack1/5
-XX:SurvivorRatio=4:New GenerationEden區與Survivor區的大小比值設置為4,則兩個Survivor區與一個Eden區的比值為2:4,一個Survivor區占整個New Generation1/6
-XX:MaxPermSize=16m
:設置Permanet Generation大小為16m
-XX:MaxTenuringThreshold=0:設置垃圾最大年齡.如果設置為0的話,New Generation物件不經過Survivor,直接進入Old Generation。對於Old Generation有比較多的應用話可以提高效率。如果將此值設置為一個較大值,New Generation物件會在Survivor區進行多次複製,這樣可以增加物件再New Generation的存活時間,減少在New Generation即被回收的概論。

2011年11月28日 星期一

利用 java進行中文字轉碼

翻譯國外程式變成中文版時,一般程式使用 utf-8碼,但是中文通常用big5 碼
此時翻譯的 中文檔案 需要先轉碼後才可以正確使用 否則會變成亂碼
可用以下方式:
利用 java native2ascii 程式:
需要安裝 任何一版 java SDK
於 安裝目錄下假設為 c:\java
則 java\bin\ 有一 nativeascii 程式 可轉碼
假設原本檔案為 mydata.txt 要轉為 utf-8 輸出為 mydata_utf8.txt 請執行以下指令
java\bin\native2ascii -encoding big5 mydata.txt mydata_utf8.txt即可
若想將轉換後 utf-8檔 變回 big5檔 ,執行以下指令
java\bin\native2ascii -reverse -encoding big5 mydata_utf8.txt mydata.txt
native2ascii原文網址

2010年1月17日 星期日

在Java中使用JSON

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。同时也易于机器解析和生成。 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。 这些特性使JSON成为理想的数据交换语言。

JSON目前慢慢的興起,也有人鼓吹取代複雜的XML格式,因此我在這次的專案中即使用JSON,也順便記錄一下。
連結
JSON的英文官網JSON的中文網頁

要在Java使用JSON必須要使JSON-lib

在開始使用之前還必須要一些其他的lib配合:
  • Apache-commons-beanutils
  • Apache-commons-collections
  • Apache-commons-lang
  • Apache-commons-logging
  • EZMorph
其中EZMorph比較少見,EZMorph是一個簡單的將物件轉換(複製)成另一個物件的lib,類似於Apache commons BeanUtils的Bean Copy。
而EZMorph本來就是負責JSON-lib裏物件的轉換,現在獨立成一個專案,EZMorph可以進行基本型別(Primitive)、物件(Object)及多維度的資料轉換等等...

現在有一個Member物件,程式如下

public class Member
{
private String memberAccount;
private String memberPassword;
private String mailAddress;
private String mobilePhone;
private Integer activeType;
public String getMemberAccount() {
return memberAccount;
}
public void setMemberAccount(String memberAccount) {
this.memberAccount = memberAccount;
}
public String getMemberPassword() {
return memberPassword;
}
public void setMemberPassword(String memberPassword) {
this.memberPassword = memberPassword;
}
public String getMailAddress() {
return mailAddress;
}
public void setMailAddress(String mailAddress) {
this.mailAddress = mailAddress;
}
public String getMobilePhone() {
return mobilePhone;
}
public void setMobilePhone(String mobilePhone) {
this.mobilePhone = mobilePhone;
}
public Integer getActiveType() {
return activeType;
}
public void setActiveType(Integer activeType) {
this.activeType = activeType;
}

public String toString()
{
return "memberAccount = " + this.memberAccount + "\n" +
"memberPassword = " + this.memberPassword + "\n" +
"memberMailAddress = " + this.mailAddress + "\n" +
"memberMobilePhone = " + this.mobilePhone + "\n" +
"memberActiveType = " + this.activeType;

}
}

JSON有獨特的書寫格式如下:

{
memberAccount:"15320",
memberPassword: "234567",
mailAddress: "gh@ebsbu.com",
mobilePhone:"13587344829",
activeType: "1"
}


下面看個範例

public class JsonTest {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub

String jsonStr = "{memberAccount: \"15320\"," +
"memberPassword: \"234567\"," +
"mailAddress: \"gh@ebsbu.com\"," +
"mobilePhone: \"13587344829\"," +
"activeType: \"1\"}";

//建立JSON物件
JSONObject jsonObj = JSONObject.fromObject(jsonStr);
//透過JSONArray印出JSON的內容
System.out.println("jsonArray = " + JSONArray.fromObject(jsonObj));
//將JSONObject轉換給Member物件(用複製的說法會較為洽當)
Member member = (Member)JSONObject.toBean(jsonObj, Member.class);

System.out.println("member = " + member.toString());

}

}


看起來很簡單吧!其實JSON也是字串,主要就是利用JSONObject轉換成JSON物件,如果要看內容的話利用JSONArray印出,最後在利用JSONObject.toBean(....)轉換給Java物件。

在我這次的專案中已經成功的與RestFul結合,透過RestFul與JSON讓JAVA與.NET平台溝通,寫法也很簡單,大家都可以試試。

2010年1月4日 星期一

在Spring中利用XFire構建WebService

以往在建構Java的WebService時總是很偷懶的用Eclipse的Web Service工具,很直覺也很方便,但總是會自動生成一些很複雜也不太想看的代碼,這次碰到要在Spring中建構Web Service,便下定決心要好好研究一下如何建構Web Service。

講到建構WebService馬上想到Apache的Axis2,但是Axis對此次目標而言太過複雜,經過一番研究後決定使用XFire

XFire是与Axis 2并列的新一代WebService框架。之所以并称为新一代,因为它:

  • 支持一系列Web Service的新标准--JSR181、WSDL2.0 、JAXB2、WS-Security等 ;
  • 使用Stax解释XML,性能有了质的提高。XFire采用Woodstox 作Stax实现;
  • Easily Create Services from POJOs;
  • Spring的结合;
  • 灵活的Binding机制,包括默认的Aegis,xmlbeans,jaxb2,castor。
接下來說明如何在Spring中加入Web Service

首先建立xfire-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

<import resource="classpath:org/codehaus/xfire/spring/xfire.xml" />


<bean id="xmlbeansTypeRegistry" class="org.codehaus.xfire.xmlbeans.XmlBeansTypeRegistry" />
<bean id="webAnnotations"
class="org.codehaus.xfire.annotations.jsr181.Jsr181WebAnnotations" />
<bean id="handlerMapping" class="org.codehaus.xfire.spring.remoting.Jsr181HandlerMapping">
<property name="typeMappingRegistry" ref="xmlbeansTypeRegistry" />
<property name="xfire" ref="xfire" />
<property name="webAnnotations" ref="webAnnotations" />
</bean>


<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="urlMap">
<map>
<entry key="/">
<ref bean="handlerMapping" />
</entry>
</map>
</property>
</bean>
</beans>

再來是在web.xml中加入以下的片段


<context-param>
<param-name>contextConfigLocation</param-name>
<!--將xfire-servlet.xml加入-->
<param-value>
classpath:/beans.xml
/WEB-INF/xfire-servlet.xml
</param-value>
</context-param>

<servlet>
<servlet-name>xfire</servlet-name>
<servlet-class>org.codehaus.xfire.spring.XFireSpringServlet</servlet-class>
</servlet>
<!--任何經過/service/進入的都會被此Servlet攔下-->
<servlet-mapping>
<servlet-name>xfire</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>

最後是在beans.xml中宣告service


<bean id="personService" class="com.foxconn.service.impl.PersonServiceImpl">
</bean>


在beans.xml中的宣告一如往昔,完全不用修改。

接下來即要進入程式的實現


package com.foxconn.service;

import javax.jws.WebService;

@WebService
public interface PersonService
{
public void add();
}


注意到了嗎?在inteface上方要用annotation宣告此interface為WebService。

再來是interface的實現

package com.foxconn.service.impl;

import javax.jws.WebService;

import com.foxconn.service.PersonService;

@WebService(serviceName = "person", endpointInterface = "com.foxconn.service.PersonService")
public class PersonServiceImpl implements PersonService {

@Override
public void add()
{
// TODO Auto-generated method stub
System.out.println("add....................");
}

}

在此實做類別的上方也要用annotation宣告。
serviceName指的是webservice的名稱。
endpointInterface指的是webservice的進入點。

完成後佈署啓動即可在瀏覽器輸入http://localhost:8080/XFireTest/services/person?wsdl
就可以看到動態生成的WSDL了(XFireTest是專案名稱也就是站點名稱囉)。

接下來要進行webService的測試。

我建立了一個很單純的Java Project,並寫了如下的code

package com.test;
import java.net.URL;

import org.codehaus.xfire.client.Client;


public class ClientTest {

/**
* @param args
*/
public static void main(String[] args)throws Exception
{
// TODO Auto-generated method stub
//利用XFire的Client建立WebService客戶端
Client c = new Client(new URL("http://localhost:8080/XFireTest/services/person?wsdl"));

//呼叫服務,服務的方法為add,一定要傳入引數,但這個service並沒有引數,所以就隨便傳
Object result[] = c.invoke("add",new Object[0]);

}

}

最後執行即可看到Console印出add....................了
在最後撰寫webservice Client端時我心血來潮將一個個要用到Jar放入並,整理如下:

2010年1月3日 星期日

利用dom4j解構與解析XML(一)

利用dom4j可以進行XML的解析與建構,可到dom4J Sourceforge下載。

在建構的時候必須要先建構一個Document物件,然後再往下加Element物件,透過這種方式,一步步的將XML建構出來。

如下的程式碼:

package com;

import java.util.ArrayList;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

public class BuildTest {

/**
* @param args
*/
public static void main(String[] args)
{
// 創建須放在XML裏的範例
// TODO Auto-generated method stub
ProductCategory category1 = new ProductCategory();
category1.setProductCategoryId("0001");
category1.setCategoryName("小說");
category1.setCategoryLevel("B");
category1.setParentId("001");
category1.setCategoryDesc("電子書類別");
category1.setOrderBy("1");

ProductCategory category2 = new ProductCategory();
category2.setProductCategoryId("0002");
category2.setCategoryName("漫畫");
category2.setCategoryLevel("B");
category2.setParentId("002");
category2.setCategoryDesc("電子書類別");
category2.setOrderBy("1");

List list = new ArrayList ();

list.add(category1);
list.add(category2);

// 呼叫buildeXML(...)
BuildTest test = new BuildTest();
System.out.println(test.buildXML(list));

}

public String buildXML(List list) {
Integer TotalRecordCount = list.size();

// 創建一個Document實例
Document document = DocumentHelper.createDocument();
// 生成Document下的一個根節點
Element root = document.addElement("Response");
// 生成root的一個節點
Element apiName = root.addElement("BbPdtCategorySelRsp");
// 加入TotalRecordCount節點
Element count = apiName.addElement("TotalRecordCount");
// 設置TotalRecordCount節點的值
count.addText(TotalRecordCount.toString());
// 加入CategoryInfoList節點
Element categoryInfoList = apiName.addElement("CategoryInfoList");
// 加入多個CategoryInfoList節點
for (ProductCategory temp : list) {
Element categoryInfo = categoryInfoList.addElement("CategoryInfo");

Element categoryID = categoryInfo.addElement("CategoryID");
categoryID.addText(temp.getProductCategoryId() == null ? "" : temp
.getProductCategoryId().toString());
Element categoryName = categoryInfo.addElement("CategoryName");
categoryName.addText(temp.getCategoryName() == null ? "" : temp
.getCategoryName());
Element parentID = categoryInfo.addElement("ParentID");
parentID.addText(temp.getParentId() == null ? "" : temp
.getParentId().toString());
Element categoryDesc = categoryInfo.addElement("CategoryDesc");
categoryDesc.addText(temp.getCategoryDesc() == null ? "" : temp
.getCategoryDesc());
Element categoryLevel = categoryInfo.addElement("CategoryLevel");
categoryLevel.addText(temp.getCategoryLevel() == null ? "" : temp
.getCategoryLevel().toString());
Element orderBy = categoryInfo.addElement("OrderBy");
orderBy.addText(temp.getOrderBy() == null ? "" : temp.getOrderBy()
.toString());

}
//傳回建構過很的XML
return document.asXML();
}

}

2010年1月2日 星期六

Apache Common Digester

Apache Common Digester是專門解析XML文件的工具,目前已發布到2.0版。

在開始之前必須先下載LoggingBeanUtils

例如有個XML文檔如下:




<Request> 'Request'
<BbPdtCategorySelReq> 'Request/BbPdtCategorySelReq'
<ParameterList> 'Request/BbPdtCategorySelReq/ParameterList'
<Parameter> 'Request/BbPdtCategory/ParameterList/Parameter'
<Name>Oliver</Name> 'Request/BbPdtCategory/ParameterList/Parameter/Name'
<Value>Good</Value> 'Request/BbPdtCategory/ParameterList/Parameter/Value'
</Parameter>
<Parameter> 'Request/BbPdtCategory/ParameterList/Parameter'
<Name>Joyce</Name> 'Request/BbPdtCategory/ParameterList/Parameter/Name'
<Value>Gool</Value> 'Request/BbPdtCategory/ParameterList/Parameter/Value'
</Parameter>
</ParameterList>
</BbPdtCategorySelReq>
</Request>


Digester是利用路徑的概念進行解析,可以由上述的範例看出每個XML Tag所對應,相當的直覺。

首先必須建立欲解析的Bean,利用上述的範例為ParameterList及Parameter

package com;

import java.util.ArrayList;
import java.util.List;

public class ParameterList {
private List parameters = new ArrayList();

public List getParameters() {
return parameters;
}

public void addParameter(Parameter parameter) {
this.parameters.add(parameter);
}

}




package com;

public class Parameter {
private String name;
private String value;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getValue() {
return value;
}

public void setValue(String value) {
this.value = value;
}
}


最後是XML的解析



package com;
import java.io.IOException;


import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.digester.Digester;
import org.xml.sax.SAXException;

public class DigesterTest {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String xmlDocp = “<Request><BbPdtCategorySelReq>“+
”<ParameterList><Parameter>“+
”<Name>Oliver</Name>”+
“<Value>Good</Value>”+
“</Parameter>”+
“<Parameter>”+
“<Name>Joyce</Name>”+
“<Value>Gool</Value>”+
“</Parameter>”+
“</ParameterList>”+
“</BbPdtCategorySelReq>“
“</Request>”;

try {
// 調用解析方法

DigesterTest t = new DigesterTest();

ParameterList parameterList = t.parseByDigesterP(xmlDocp);
// 循環所有的Parameter
for (Parameter p : parameterList.getParameters())
{
p.getName(); // 取得NAME
p.getValue(); // 取得對應的VALUE
}
} catch (IOException e) {
// TODO 自動產生 catch 區塊
e.printStackTrace();
} catch (SAXException e) {
// TODO 自動產生 catch 區塊
e.printStackTrace();
}

}

public ParameterList parseByDigesterP(String xmlDoc) throws IOException,
SAXException {

System.out.println(xmlDoc);

StringReader read = new StringReader(xmlDoc);

System.out.println(read);

ParameterList parameterList = new ParameterList();
// 實例Digester物件
Digester d = new Digester();
// DTD檔進行驗證
d.setValidating(false);
// push:放入一个根节点物件,要從哪個節點放入就設哪一個
d.push(parameterList);

// 對節點Parameter創建一個Parameter的物件
d.addObjectCreate(
"Request/BbPdtCategorySelReq/ParameterList/Parameter",
Parameter.class);
// 相當于調用Parameter中的setName()
d.addBeanPropertySetter(
"Request/BbPdtCategorySelReq/ParameterList/Parameter/Name",
"name");
d.addBeanPropertySetter(
"Request/BbPdtCategorySelReq/ParameterList/Parameter/Value",
"value");
// 想當與調用ParameterList中的addParameter()
d.addSetNext(
"Request/BbPdtCategorySelReq/ParameterList/Parameter",
"addParameter");
// 得到相應的ParameterList物件
parameterList = (ParameterList) d.parse(read);

return parameterList;
}
}




範例文檔