Google Code Prettify

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

2018年6月3日 星期日

讓自己開發的系統 擁有較好的穩定性


把工作上的救火經驗,匯集成一點點心得分享
希望能幫到一些新手

https://yulinliu.gitbook.io/share/

2016年7月14日 星期四

Generate Swagger Specification

在網路上與官方網站的範例大多是在 Application Server 上產生 swagger.json

但這種方法會讓 Server 浪費資源,也有漏洞的風險

    Swagger高危漏洞,影響Html、PHP、Java和 Ruby等開發應用
    原文網址:https://read01.com/Lz7eJg.html

最近終於找到能獨立產出 swagger.json 的方式,程式碼如下

2016年2月29日 星期一

wildfly 10 add postgresql jdbc driver

1.  ./bin/jboss-cli.sh --connect

2.  module add --name=org.postgresql --slot=main --resources=/software/java/postgresql-9.4.1208.jar --dependencies=javax.api,javax.transaction.api

3.  /subsystem=datasources/jdbc-driver=postgres:add(driver-name="postgres",driver-module-name="org.postgresql",driver-class-name=org.postgresql.Driver)

執行完這3個步驟,回傳 {"outcome" => "success"}
即為增加成功


2016年2月21日 星期日

Apache Kafka 9.0 需注意的地方

Apache Kafka 9.0
     Documentation  http://kafka.apache.org/documentation.html

kafka 雖然沒限制 topics 的數量,但在機器數量少時 還是需要避免這種設計方式
因為kafka 是使用 file 的儲存方式,每一個topics 至少會產生1個目錄與2個檔案

kafka cluster 中的所有檔案數量是:
     (topics * partition * replication-factor * 2) + (offsets * n)

100K topics 在 3台 kafka 主機裡,至少會產生:
     (100K * 1 * 1 * 2) +(N) = 200k + N

每台 kafka 至少要產生 200K / 3 (約66666) 的檔案,超過一般linux fs.file-max = 65536 的設定,當然這還是有辦法解決

但在每個 partition 都需要相對應的 thread 來處理,這就比較麻煩了
100K 需要多少 thread 來處理才能夠即時回應,不造成timeout?
每台硬體都要有足夠的RAM 跟 夠好的 CPU時 也許可行, 但還是避掉這種設計會比較好


在設定檔有幾個需要注意的地方
    server.properties
  • broker.id 需特別注意編號 每台主機不可重覆
  • 如果需要 delete topic,需增加 delete.topic.enable=true
    producer.properties

  • client.id 在每個 thread 不能重覆
    consumer.properties
  • group.id=PG 修改預設的group id
  • offsets.storage=kafka 設定 offset 資料存在 kafka
ZooKeeper Cluster 設定
    可參考 http://myjeeva.com/zookeeper-cluster-setup.html
    修改 zookeeper.properties

    設定 zookeeper cluster id
        mkdir /tmp/zookeeper/
        echo 1 > /tmp/zookeeper/myid (id 需特別注意編號,跟zookeeper.properties 需對應)

2016年2月15日 星期一

Jetty 參數修改

關閉 http dir view

修改 etc/webdefault.xml,  dirAllowed value 設為 false
    dirAllowed
    false

設定 classloading 優先讀 jetty resources

修改 etc/jetty-deploy.xml,在 WebAppProvider 下增加
    true

預設classloading 順序為 webapps > jetty resources > jetty lib
改完參數則會變為 jetty lib > jetty resources > webapps


webapps 下的檔案, 如果 xml  跟 war 名稱不一致 會重覆載入


Server thread 設定max thread參考計算

    thread.max > (http.acceptors + http.selectors + [http.request=1])

2016年2月13日 星期六

Distributed Lock

這幾年一直在碰 HA 相關的系統

一直有一些需求,希望這個程式能在一個 cluster 環境中,只有一台主機執行
不想用DB存相關資料,但一直找不到簡單方便的解決方法

終於發現有一個能跟 java 結合,不需另外寫script

jgroups 提供一個 LockService , 可以實現 DistributedLock

DistributedLock 可以用來做什麼?
  1. Transaction lock , 補足一些 NoSQL 不支援的問題
  2. Service running lock, 讓 Master Node 執行 job, 其它Node 則是一直等待
  3. other lock ???
寫了一個sample code 放在 git

2015年8月19日 星期三

RESTful Services 幾項重點

1. HTTP Method 對應Server處理方式
HTTP MethodData operateDescription
 POST Create Create a resource without id.
 GET Read Get a resource.
 PUT Update Update a resource or create a resource with id if not existed.
 DELETE Delete Delete a resource

2. Server Response Content Type
    JSON or XML or Text

3. 透過 HTTP Authorization 限制使用者存取資源的權限,也可用其它方式(ip、cookie)

4. response status code、error code 直接參考 http status code

5. REST 中的資源 一般是名詞 (podcasts, customers, user, accounts 等) 而不是動詞 (getPodcast, deleteUser 等)

2013年12月24日 星期二

Apache Shiro Password Hashing

SHA 512 Hash

Sha512Hash s = new Sha512Hash("password", "salt string", 1024);
UsernamePasswordToken token = new UsernamePasswordToken("milla", s.toString());
Subject subject = SecurityUtils.getSubject();
subject.login(token);

Apache Shiro Cryptography Features

http://shiro.apache.org/cryptography-features.html

2013年10月8日 星期二

Apache Shiro Use Cache Server

Apache Shiro 已經有內建 Cache 機制,http://shiro.apache.org/caching.html

但也能自行 implement,整合其它的 Cache Server (JCache, Ehcache, JCS, OSCache, JBossCache, TerraCotta, Coherence, GigaSpaces)

implement 方式,可以參考這個網址
http://www.java2s.com/Open-Source/Java/Authentication-Authorization/shrio/org/apache/shiro/cache/ehcache/Catalogehcache.htm


使用時,需在 shiro.ini 增加幾行資料

#Use Infinispan HotRod Cache
cacheManager = com.test.cache.SessionCacheManager
securityManager.cacheManager = $cacheManager
sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
securityManager.sessionManager.sessionDAO = $sessionDAO

Apache Shiro JdbcRealm and RememberMe

僅需要在 shiro.ini 增加幾行資料

#Setting JdbcRealm
jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm

#取得帳號密碼
jdbcRealm.authenticationQuery = select user_pass from users where user_name = ?

#取得Roles資料
jdbcRealm.userRolesQuery = select role_name from user_roles where user_name = ?

#使用JNDI DataSource
dataSource = org.apache.shiro.jndi.JndiObjectFactory
dataSource.resourceName = java:/comp/env/jdbc/EmployeeDB

jdbcRealm.dataSource = $dataSource
securityManager.realms = $jdbcRealm

#-----------------------------------------------------------------------------------------

#Setting RememberMe
rememberMeManager = org.apache.shiro.web.mgt.CookieRememberMeManager
securityManager.rememberMeManager = $rememberMeManager
securityManager.rememberMeManager.cookie.name = remember_me

#設定cookie.maxAge = blah , cookie會無法正常寫入
#securityManager.rememberMeManager.cookie.maxAge = blah

securityManager.rememberMeManager.cookie.domain = testdomain.com

2012年9月20日 星期四

JMuPdf PDF to Image

MuPdf 實在有夠強大的,解析檔案出現字型問題,還是能夠正常輸出畫面

JMuPdf JNI library http://code.google.com/p/jmupdf/

轉jpg範例


PdfDocument pdfDoc = new PdfDocument(pdf_file);
int count = pdfDoc.getPageCount();
int zoom = 1;

for(int i=0;i < count ;i++){
     PageRenderer render = new PageRenderer(pdfDoc.getPage((i+1)), zoom, Page.PAGE_ROTATE_AUTO, ImageType.IMAGE_TYPE_RGB);
     render.setAntiAliasLevel(8);//需設為8,不然中文字會變醜
     render.render(true);

     JPGOptions options = new JPGOptions();
     options.setQuality(96);

     FileOutputStream out = new FileOutputStream(new File(out_dir+(i+1)+".jpg"));
     JimiWriter writer = Jimi.createJimiWriter("image/jpeg", out);
     writer.setSource(render.getImage().getSource());
     writer.setOptions(options);
     writer.putImage(out);
    
     out.flush();out.close();
    
     render.dispose();
}

pdfDoc.dispose();

2010年5月21日 星期五

OpenOffice service

一般網路上的教學都是使用下列指令
soffice -headless -accept="socket,host=localhost,port=8100;urp;StarOffice.Service" -nofirststartwizard

但如果使用非管理者的帳號啟動上列指令,可能會發生部分目錄下的轉檔失敗。
可以改用下列指令啟動
soffice.bin -accept="socket,host=localhost,port=8100;urp;StarOffice.Service" -headless
-nofirststartwizard

2009年6月26日 星期五

Dynamic Web service client

//多個回傳參數用法

String wsdl = "http://localhost:8080/SOA-DO1/PortTypeBndPort?WSDL";

org.apache.axis.client.Service service = new org.apache.axis.client.Service();

Call call = service.createCall();
call.setTargetEndpointAddress(wsdl);
call.setOperationName(new QName("http://schemas.xmlsoap.org/wsdl/soap/","Add"));

//Input
call.addParameter( "machineid",org.apache.axis.encoding.XMLType.XSD_STRING,javax.xml.rpc.ParameterMode.IN);
call.addParameter( "passcode",org.apache.axis.encoding.XMLType.XSD_STRING,javax.xml.rpc.ParameterMode.IN);
call.addParameter( "uid",org.apache.axis.encoding.XMLType.XSD_STRING,javax.xml.rpc.ParameterMode.IN);
call.addParameter( "url",org.apache.axis.encoding.XMLType.XSD_STRING,javax.xml.rpc.ParameterMode.IN);
call.addParameter( "note",org.apache.axis.encoding.XMLType.XSD_STRING,javax.xml.rpc.ParameterMode.IN);
call.addParameter( "handle_time",org.apache.axis.encoding.XMLType.XSD_STRING,javax.xml.rpc.ParameterMode.IN);

//Output
call.addParameter( "status",org.apache.axis.encoding.XMLType.XSD_STRING,javax.xml.rpc.ParameterMode.OUT);
call.addParameter( "message",org.apache.axis.encoding.XMLType.XSD_STRING,javax.xml.rpc.ParameterMode.OUT);
call.addParameter( "time",org.apache.axis.encoding.XMLType.XSD_STRING,javax.xml.rpc.ParameterMode.OUT);
call.addParameter( "sno",org.apache.axis.encoding.XMLType.XSD_STRING,javax.xml.rpc.ParameterMode.OUT);

call.setUseSOAPAction(true);
call.setSOAPActionURI("do1.soa.com/PortType/Add");

String machineid = "sdfs";
String passcode = "sdfsf";
String uid = "C123456789";
String url = "http://www.google.com.tw";
String note = "測試網站-新增測試";
String handle_time = "";


List list = new ArrayList();
list.add(machineid);
list.add(passcode);
list.add(uid);
list.add(url);
list.add(note);
list.add(handle_time);


Object [] inputParams = list.toArray();
List outputParams = new ArrayList();

//取得第一個回傳值
outputParams.add(call.invoke(inputParams));

//取得剩餘的回傳值
outputParams.addAll(call.getOutputValues());

for(int i=0;i<outputParams.size();i++){
      System.out.println(i+"="+outputParams.get(i));
}

2009年5月18日 星期一

Spring MultiActionController 也能應用在檔案下載功能

public ModelAndView download(HttpServletRequest req, HttpServletResponse res) throws Exception {
     String sno = req.getParameter("abc");

     try{
          List list = dao.Select("select * from abc_file where abc="+abc);
          if(list.size() != 0){
               Map map = (Map) list.get(0);
               String file_name = map.get("file_name")==null?"":(String)map.get("file_name");
               Long file_size = map.get("file_size")==null?Long.valueOf(0):(Long)map.get("file_size");
               byte[] file_contents = (byte[]) map.get("file_contents");
               String content_type = map.get("content_type")==null?"":(String)map.get("content_type");

               String agent = req.getHeader("User-Agent");

               res.reset();

               if(agent.indexOf("MSIE") != -1){
                    file_name = URLEncoder.encode(file_name,"UTF8");
               }else{
                    file_name = new String(file_name.getBytes("UTF-8"),"ISO8859-1");
               }

               res.setHeader("Content-disposition","attachment; filename="+file_name);
               res.setContentLength(file_size.intValue());
               res.setContentType(content_type);

               BufferedOutputStream ou = new BufferedOutputStream(res.getOutputStream());
               ou.write(file_contents);
               ou.flush();
               ou.close();
          }

     } catch ( Exception e ) {
          logger.error(e);
          throw e;
     }

     return null;
}

Spring MVC + Velocity

參考手冊

http://www.javaworld.com.tw/confluence/display/opensrc/Spring
http://velocity.apache.org/engine/devel/user-guide.html


開發外掛

SpringIDE http://springide.org/updatesite/
VeloEclipse http://veloeclipse.googlecode.com/svn/trunk/update/
Dreamweaver Velocity http://velocity.gilluminate.com/


設定
  1. 相關jar檔
    commons-collections.jar
    commons-lang.jar
    commons-logging.jar
    log4j-1.2.15.jar
    spring.jar
    spring-web.jar
    spring-webmvc.jar
    velocity-1.6.2.jar
    velocity-tools-generic-1.4.jar
    velocity-tools-view-1.4.jar

  2. web.xml
    將所有網址.do的頁面導向spring servlet做處理。

  3. spring-servlet.xml
    Bean id=velocityConfig,設定Velocity參數。
    Bean id=viewResolver,解析*.vm頁面。



    Bean id=paramMethodResolver,解析url上的method參數,導入至對應的Method,預設值為view。
    Bean id=thinkonDao,宣告為Bean方式,方便其它Bean注入引用。
    Bean id=urlMapping,解析url,導入至對應的Bean id。
    Bean id=indexAction,測試範例,對應/index.do,注入dao引用。




範例
  1. index.java (Spring MultiActionController)
    輸出參數至ModelAndView,導入index.vm做剖析輸出畫面。

  2. index.vm (Velocity)
    ${title}會對應至ModelAndView的title參數。
    #set($a = ‘abcsdfsd’) 為宣告頁面變數。
    ${a}會對應至#set($a)的值。


  3. 輸出結果
    ${uic}因尚未找到任何對應的變數,所以不處理。

2009年5月15日 星期五

基本JSR-168 Portlet 開發範例

以下範例採用NetBeans 6.5開發,Portlet開發外掛為 Portal Pack 3.0

1.建立新專案



2.填入專案名稱



3.選擇Portlet Supper相關設定
     Portlet Version: 1.0(JSR-168) 2.0(JSR-286)
     Create Portlet:產生Portlet java source
     Create Jsps:產生 Portlet Mode對應的Jsp
     Package: java source路徑
     Portlet Mode: View 瀏覽模式,也是預設進入的模式。
     Edit 編輯模式,通常用來修改設定參數。
     Help 說明模式。



4.Portlet java source簡介
     此檔類似於 Servlet
     processAction:變更事件時的進入點,執行完此處在會進入所對應的事件funciton。
     doView:執行VIEW模式時,所對應的function。
     doEdit:執行EDIT模式時,所對應的function。
     doHelp:執行HELP模式時,所對應的function。


5.processAction簡易應用
     request.getPortletMode(),取得現在執行的模式。
     request.getParameter(),取得傳入的參數。
     request.setAttribute(),塞入參數,對應的模式或jsp顯示時,能取得此參數。
     responese.setPortletMode(),修改預定要執行的模式。


6.JSP撰寫
     Portlet java source中的RenderRequest會變成renderRequest。
     Portlet顯示時不需要寫出完整的HTML(不需<html><body>),僅將區塊顯示出來即可,最好使用div的區塊方式。

HTTP + SSL

//受信認的憑證方式,加入一行程式碼即可


System.setProperty( "java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol" );

URL url = new URL("https://xxx.xxx.xxx");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();

-----------------------------------------------------------------------------------------------
//非受信認的憑證方式


TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager(){
public java.security.cert.X509Certificate[] getAcceptedIssuers(){
return null;
}
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType){}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType){}
}};

SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());

//不判斷Hostname是否正確


HostnameVerifier hv = new HostnameVerifier(){
public boolean verify(String hostname, SSLSession session) {return true;}
};

HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(hv);

URL url = new URL("https://xxx.xxx.xxx");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();

WebService + SSL

WebService Server 上的SSL憑證,為非公開受信任的憑證時

可手動將憑證匯入JDK之中

cd C:\jdk1.6.0_03\jre\lib\security

keytool -keystore client.keystore -import -file ooxx.crt

查詢清單
keytool -list -keystore cacerts