2012년 1월 30일 월요일

Mobile Device에서 HTTP Post를 이용한 파일 첨부


Mobile Device에서 Server Side로 첨부 파일을 보내는 방법을 생각해 봤습니다.
  1. File을 Base64 Encoding 하여 Parameter로 Server에 전달 Server는 Base64 Decoding 하여 사용.
  2. Server Side API에 SOAP Message Attachments을 사용.
  3. Server Side API에 Axis의 DataHandler을 사용하는 방법.
  4. HTTP Body에 Binary Data을 넣어서 보내는 방법.


1.번은 File 크기가 크다면 문제가 될 것이고, 2,3번은 별도의 Client Stub을 생성하여 가지고 있어야 하니 번거롭고, 4번이 가장 적당할 것 같습니다.

간단하게 전송 규약을 정해봤습니다.

  • HTTP Method: Post
  • contentType: multipart/formed-data
  • contentLength: 첨부되는 파일의 크기
  • “FILE_NAME”의 Custom header을 사용하여 파일 명 전달.


Server Side Code

String contentType = request.getContentType();
int contentLength = request.getContentLength();
String fileName = request.getHeader("FILE_NAME");
File f = recvFile(request.getInputStream(), contentLength, fileName);

private File recvFile(InputStream in, int length, String fileName)
throws IOException {
   if (fileName == null || fileName.length() == 0 || length <= 0)
       return null;

BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(in);
bos = new BufferedOutputStream(new FileOutputStream("C:/"+fileName));

int c;
while ((c = bis.read()) != -1) {
bos.write(c);
}
bos.flush();
}
catch (Exception e) {
e.printStackTrace();
return null;
}
finally {
try {
if (bis != null)
bis.close();
}
catch (Exception ex) {}
try {
if (bos != null)
bos.close();
}
catch (Exception ex) {}
}

   return new File(fileName);
}


Client Side Code
File addFile = new File(filePath);
HttpParams params = new BasicHttpParams();

HttpConnectionParams.setConnectionTimeout(params, 30000);
HttpConnectionParams.setSoTimeout(params, 30000);
HttpConnectionParams.setTcpNoDelay(params, true);

// Server Side URL
String addPicURL = url+getString(R.string.default_value_picAdd);
HttpPost post = new HttpPost(addPicURL);
post.addHeader("FILE_NAME", "첨부되는 파일 이름");
FileEntity entity = new FileEntity(addFile, "multipart/formed-data");
post.setEntity(entity);
DefaultHttpClient client = new DefaultHttpClient(params);

HttpResponse response = client.execute(post);

int statusCode = response.getStatusLine().getStatusCode();
if(statusCode == 200) {
// Etc Code
} else {
Log.d(this.getClass().getSimpleName(), "StatusCode: "+statusCode);
}


이미지 파일이 전송되는 경우라면 Mobile Device(iOS, Android)에서 이미지를 적당히 줄여서 보낼수 있습니다. Mobile Device에서 촬영한 사진은 1~2M 정도지만 적당히 줄이면 200kb 정도로 전송할 수 있습니다.

2012년 1월 27일 금요일

Android에서 JavaScript 한글 onKeyUp Event 문제


Android Webview 뿐만 아니라 특정 브라우저에서도 한글 입력시 javascript keyup Event가 잡히지 않는 문제가 있습니다.


예를 들어 Twitter의 140글자를 Check 처럼 Web의 “textarea”에 한글을 입력 할 경우에 keyup event을 잡지 못하는 것 처럼 말입니다. 물론 iPhone 계열에서는 keyup Event가 잘 잡힙니다.

Googling 해서 여러 방법을 찾아 보고 최선의 방법을 여기 적습니다.

JavaScript Object “Observe”는 timer로 주기적으로 특정 form을 check하여 “keyup” Event을 발생 시킨다.

Observe.js
var Observe = function(oEl) {
 this._o = oEl;
 this._value = oEl.value;
 this._bindEvents();
};
Observe.prototype._bindEvents = function() {
 var self = this;
 var bind = function(oEl, sEvent, pHandler) {
   if (oEl.attachEvent) oEl.attachEvent('on' + sEvent, pHandler);
   else oEl.addEventListener(sEvent, pHandler, false);
 };
 bind(this._o, 'focus', function() {
  
   if (self._timer) clearInterval(self._timer);
   self._timer = setInterval(function() {

     if (self._value != self._o.value) {
       self._value = self._o.value;
       self._fireEvent();
     }
    
   }, 50);
  
 });
 bind(this._o, 'blur', function() {
  
   if (self._timer) clearInterval(self._timer);
   self._timer = null;
  
 });
          
};
Observe.prototype._fireEvent = function() {
        
 if (document.createEvent) {
  
   var e;
  
   if (window.KeyEvent) {
    
     e = document.createEvent('KeyEvents');
     e.initKeyEvent('keyup', true, true, window, false, false, false, false, 65, 0);
    
   } else {
    
     e = document.createEvent('UIEvents');
     e.initUIEvent('keyup', true, true, window, 1);
     e.keyCode = 65;
    
   }
  
   this._o.dispatchEvent(e);
  
 } else {
  
   var e = document.createEventObject();
   e.keyCode = 65;
  
   this._o.fireEvent('onkeyup', e);
  
 }
};


Observe.js 사용 예
<script src="Observe.js"></script>
<script type="text/javascript">
   $().ready(function() {
       new Observe(document.getElementById('search_head'));
   });

$('#search_head').bind('keyup', function(event, ui) {
.. 실행 Script
});

</script>
<div id="searchCondition" class="srchBar" style="height: 45px; padding-top: 10px;">
   <input id="search_head" name="search_head" type="search">
</div>


문제는..
Observe.js에 0.5초 단위로 timer을 설정하였다. 결국 keyup Event가 0.5초 단위로 계속 발생.

2012년 1월 3일 화요일

Enterprise Application Development using Spring Roo 1.2

This article is excerpted from "SOFT(WARE) THOUGHTS BY JOHN"


Spring Roo is an open source Rapid Application Development tool for Java developers. Spring based applications performing CRUD (Create, Read, Update, Delete) on Entities can be easily auto generated using Roo. It is not an IDE or a runtime. It is just a programming methodology combined with a code generation tool. This post describes the features of Spring Roo briefly and analyses its applicability in building enterprise applications where simple CRUD functionality and auto generated screens may not be sufficient.
Spring Roo Features
It is very easy to kick start a Spring Roo project. You just need to give few commands and the project will be ready for you. Then you can provide information about your entities, their fields and constraints. Spring Roo can generate end to end code for all CRUD operations. The generated components include JSP pages, MVC Controller classes, Entities with their persistence logic and database tables. Roo can also create custom finders with filter fields of your choice. From version 1.2 onwards, you can also generate service layer and repository layer if you wish.

Other key aspects are as follows:

  • Roo has excellent round trip handling. Most of the auto generated code is at your disposal to edit. Roo accommodates your changes even when it recreates the code. This ensures that most of the NFRs required for an Enterprise application are available off the shelf.
  • Roo generates application on top of robust Spring framework.
  • It has integration with many of the industry standard frameworks like Hibernate, Spring MVC, log4j, Google Web Toolkit, Solr search engine, EclipseLink, OpenJPA etc
  • Application runtime is independent of Roo. Role of Roo ends in development cycle.
  • Supports Database Reverse Engineering.

You may read more about Roo features in my older post.

What else you need for an Enterprise Application?
If an application is being developed for internal use of an enterprise, you may be able to use auto generated application as such with some tweaks. But, if the scope of the application is beyond that, you will have additional requirements.
  • There will be complex business logics to be performed.
  • Even for simple CRUD functionality, you may need custom screens to improve aesthetics and usability.
  • You may have strict NFR requirements in terms of performance, security, transaction management, logging, audit, internationalization, maintainability etc. Your application will require a robust architecture to support all these.

So the key requirements here are customizability to the customer needs and adherence to NFRs. We will see each of these in detail.
Architecture Analysis
Following diagram describes the architecture of a typical Roo based application, when service and repository are enabled.
<><><><><><><><><>
High Level Architecture of a Spring Roo based application (Click to enlarge)

You may notice that the architecture is robust with appropriate layers and proven technology components.
Note: In most of the cases business services and repository will not be doing anything other than delegating the call to underlying layer. But presence of these layers can provide great peace of mind to
a) an architect, because of the flexibility it provides for any future requirements.
b) a manager, because the architecture resembles any other proven enterprise architecture he would have already seen.

Customizability
For any auto generated application, the extent of customizability will be a major concern. Let’s now look into the customizability of Spring Roo based applications.
Depending on the requirements, Spring Roo applications can be customized to different extents, and there are side effects for some of the customizations, especially when we try to modify the data model after customization. For example, when you add a field after doing the customization, some times, you may need to tweak the code a bit.

UI Customization
Look and Feel: User interface is the area where maximum customization is required, because the end user directly interacts with it. You may change the overall look of the application by modifying its stylesheets, images and template files. You can also modify the property files to change labels, titles and messages. All these changes are completely non-invasive and Roo will keep these changes intact even when it updates these files.
UI Components: All the html fields are represented as tagx components in Spring Roo. If there is a requirement to change the behavior of a field, it can be done at the component level, so that all the pages will be changed automatically.
Additional Client Side Logic: It is possible to add custom Javascripts to perform client side logic like doing a specific validation.
Page Layout: Roo generated pages will have a normal two column layout. But we can modify the layout by including table or div tags around the fields without touching the field definition. This gives us complete flexibility in page layout.
When new fields are added to the screen, Roo will update the file we have modified. But it will keep our layout tags intact. Once it is re-generated, we may need to properly place the newly generated fields in our layout infrastructure, because Roo doesn’t understand our layout logic. Similarly, when a field is removed, we may need to readjust the layout of other fields.
Business Customization
In some cases we may need to add additional business logic, other than simple validation and persistence. With the help of newly added service layer, this is very easy to achieve. By default, the service implementation class will be empty and the actual implementation will be in ITD file (Click here, if you are not familiar with ITD). You can define the same method in the implementation class with additional logic, and Roo will automatically remove the default method from the ITD file.

Introducing New Functionality
There could be certain functionality which are complex and will not match to any CRUD operations. Eg. A flight availability search. You may need to create the entire layers for such functionality without the help of Roo and update the menu generated by Roo to give link to the new functionality. Depending on the modularity requirement, new functionality can be implemented as new classes or as additional methods in existing controller and service classes. In some cases, it will be possible to reuse the auto generated persistence logic itself and we just need to create the screen and business logic. If we need to update persistence logic as well, we may modify the entity (if we are using active record pattern) or add a new dao class. It is absolutely ok to mix Roo and “non Roo” functionality in a single application. However it is recommended to use a technical architecture which matches with Spring Roo architecture, ie and architecture based on Spring and Spring MVC.

NFR Support
Adherence to Non Functional Requirements is important for any enterprise application. Let us investigate how the well the NFRs can be addressed in a Roo based application.
Security
Security can be easily incorporated to Roo based application using Spring security. Intercept-url tag in spring security can be used to enforce authorization at presentation layer. As the URL for all CRUD operations of an entity are same, you may need to use http method also to enforce fine grained access control. But if service layer is used, authorization can be easily enforced at service layer by adding MethodSecurityInterceptor using AOP.

Performance
Roo does all the work during compilation. Once the Roo based application is compiled and deployed, it is just like any other web application. So there will not be a performance impact due to auto generation.
The architecture uses Spring MVC at presentation layer and Spring at business layer and they are well known light weight components.
The only area where we can have some performance concern is the persistence layer. As the entire persistence layer is ORM/JPA based, there could be performance issues in bulk retrievals, especially when dealing with entities with children. You may mitigate this issue, by updating service class to invoke a separate DAO which invoke JDBC calls for performance critical reads.

Transaction
If we opt to have a service layer, transaction is enforced at service layer. Otherwise, transactions are enforced at the domain layer. As normal CRUD functionality generated by Spring Roo deals only with one entity and its children, transaction enforcement at domain layer is sufficient. When we add a functionality which deals with multiple entities, we need to have a service layer which interacts with these entities and the transaction can be enforced at service layer.

Logging
Spring Roo has off the shelf support for Log4J and it could be used for any logging requirement. Interceptors can be put into service and persistence layer to introduce generic entry/exit logging.

Audit
The recommended approach is to use Entity listeners to perform audit. Alternatively custom implementation can be provided using interceptors.

Internationalization
All the labels and messages in the application are externalized to property files. So the application can be easily localized for any language.

Maintainability
Roo based application has excellent maintainability due to the ITD approach. In all the Java classes from presentation controller to entity, auto generated code is separated into ITD files. So, by default, Java files will not have much code. We will be adding our custom logic in these Java files and even after that they will be lean, as normal setters, getters, persistence logic, delegation etc. will not be present in them. It is easy to maintain these classes as they contain just enough code that a developer has to see. Any other code which does not need a human brain to maintain are separated and thus maintainability of a Roo based application will be better than a normal Java application.

Scalability & Availability
As already stated, Roo does not have any role at run time. A Roo based application will be just like any other application based on Spring and Spring MVC. As we all know, Spring and Spring MVC are most light weight and stateless frameworks and they can be scaled to any level. By providing a proper deployment architecture, any level of availability can be guaranteed for a Roo based application.

Recommended Approach
For an enterprise application "generate and forget it" approach will not be sufficient. The approach should be "generate -> tweak -> enhance -> deploy"
Steps could be as follows.
  1. Decide on the functionalities for which Roo will be used.
  2. Finalize the domain model as far as possible.
  3. Auto-generate the functionality using Roo, enabling service and repository layers.
  4. Make customizations in styles, images, labels, top level layout etc.
  5. Modify the UI components wherever required.
  6. Modify the .jspx file to change the layout of the pages, if required.
  7. Add additional Javascripts if required.
  8. Customize Service and repository classes by overriding the auto generated methods.
  9. Add new manual webpages, controller methods and entity methods for custom functionality wherever required.

Conclusion
Spring Roo is a robust and reliable mechanism to perform Rapid Application Development. Roo acts during compile time and this ensures that auto-generated application will be highly customizable. As the application is Spring based, it can leverage all the strengths of Spring framework.
Spring Roo can surely improve the productivity in development of normal CRUD functionality, without compromising the flexibility and NFRs. Complex functionality in the enterprise application can still be developed without using Roo. Roo based functionality and other functionality can coexist well in an enterprise application.
Features provided by Roo 1.2 made it more favorable for enterprise application development.

ETL 솔루션 환경

ETL 솔루션 환경 하둡은 대용량 데이터를 값싸고 빠르게 분석할 수 있는 길을 만들어줬다. 통계분석 엔진인 “R”역시 하둡 못지 않게 관심을 받고 있다. 빅데이터 역시 데이터라는 점을 볼때 분산처리와 분석 그 이전에 데이터 품질 등 데이...