48
Apache Utilities at Work Tom Marrs

Apache Utilities At Work V5

Embed Size (px)

DESCRIPTION

You're on another typical JavaEE-based project, and you find yourself writing the same old infrastructure code. Are you wondering if there's a quicker way to incorporate the basics such as configuration, logging, and email into your application? If so, then this presentation is for you. By using a number of Apache utilities fromCommons, Logging, and other areas, you can learn how to stop re-inventing the wheel.We'll start with a simple Struts 2 application and iteratively add the ability to:• Use Commons Lang for String and Date utilities.• Use Commons Property Configuration to setup and use application Properties.• Use Commons Logging and Log4J to log messages.• Generate Excel spreadsheets with POI.• Use Velocity Templates and Commons Email to format and send email messages.• Use HttpClient to invoke web apps with HTTP/S.• Use Commons IOUtils to simplify accessing web content.

Citation preview

Page 1: Apache Utilities At Work   V5

Apache Utilities at Work

Tom Marrs

Page 2: Apache Utilities At Work   V5

2 © 2008 CIBER, Inc. All rights reserved

Who am I?

• Background– Co-author of JBoss At Work: A Practical Guide

(O’Reilly, November 2005)• Currently working on 2nd ed.

– User Groups• Founding President of DOSUG

• Past President of DJUG

– Related Experience• I’ve been on several bad projects

• I hate re-inventing the wheel

Page 3: Apache Utilities At Work   V5

3 © 2008 CIBER, Inc. All rights reserved

Learning Objectives

• As a result of this presentation you will learn:– To research Open Source utilities before coding– To avoid re-inventing the wheel– What common utilities are available on Apache– How to use Apache utilities on your project– How to hide the details

Page 4: Apache Utilities At Work   V5

4 © 2008 CIBER, Inc. All rights reserved

Prerequisites

• Core Java SE• The right mindset

– Leverage existing utilities

Page 5: Apache Utilities At Work   V5

5 © 2008 CIBER, Inc. All rights reserved

Session Non-Agenda

In this Session, we will not discuss:

• JavaEE• A full-blown application• Other cool Apache projects:

– Web Services (Axis 2)– CXF– XMLBeans– Geronimo– ServiceMix– ActiveMQ– Camel– Struts– Beehive

Page 6: Apache Utilities At Work   V5

6 © 2008 CIBER, Inc. All rights reserved

Session Agenda

In this Session we will discuss:

• Commons Lang• Commons Configuration• Commons Logging and Log4J• POI• Commons Email• Velocity• HttpClient• Commons IO • Summary

Page 7: Apache Utilities At Work   V5

7 © 2008 CIBER, Inc. All rights reserved

Session Roadmap

Where are we?

• Commons Lang• Commons Configuration• Commons Logging and Log4J• POI• Commons Email• Velocity• HttpClient• Commons IO • Summary

Page 8: Apache Utilities At Work   V5

8 © 2008 CIBER, Inc. All rights reserved

Like Nails on a Blackboard …

if (myString == null || myString.length() == 0) { // Ugh!!

}

// OR only slightly better.

public class MyUtils {

public static boolean isNullOrEmpty(String stringToCheck) {

boolean retValue = false;

if (stringToCheck == null) {

retValue = true;

} else if (stringToCheck.length() == 0) {

retValue = true;

}

return retVal;

}

Page 9: Apache Utilities At Work   V5

9 © 2008 CIBER, Inc. All rights reserved

Commons Lang Overview

• Enhanced methods and classes for core Java SE (java.lang)– http://commons.apache.org/lang

• Includes String, numerical, date/time methods• Useful: StopWatch (simple timing test)• My favorite – StringUtils:

– isBlank()– isEmpty()– isNotBlank()– isNotEmpty()

Page 10: Apache Utilities At Work   V5

10 © 2008 CIBER, Inc. All rights reserved

With StringUtils

// Usage

if (StringUtils.isEmpty(myString)) {

}

if (StringUtils.isBlank(myString)) {

}

Page 11: Apache Utilities At Work   V5

11 © 2008 CIBER, Inc. All rights reserved

Session Roadmap

Where are we?

• Commons Lang• Commons Configuration• Commons Logging and Log4J• POI• Commons Email• Velocity• HttpClient• Commons IO • Summary

Page 12: Apache Utilities At Work   V5

12 © 2008 CIBER, Inc. All rights reserved

Getting Properties – What we want

String emailTo = MyPropertyUtil.getProperty(EMAIL_TO);

Page 13: Apache Utilities At Work   V5

13 © 2008 CIBER, Inc. All rights reserved

Rolling Your Own Properties

public class MyPropertyUtil { private static final String MY_PROPS_FILE_NAME = “…”; // Use –D to set this at startup.

public static String getProperty(String key) throws MyPropertyUtilException { Properties props = null; String value = “”, propsFileName = System.getProperty(MY_PROPS_FILE_NAME);

if (StringUtils.isNotBlank(key) && StringUtils.isNotBlank(propsFileName) { try { // FIXMEE: Move Props File Name & Properties Load to static initializer.

// The Thread Context ClassLoader is the ClassLoader used by the creator // of the Thread that runs your code. By using the Thread Context ClassLoader, // we’re guaranteed to load the resource (class or property file) as long as // it's on the application's CLASSPATH.

ClassLoader myClassLoader = Thread.currentThread().getContextClassLoader(); URL myUrl = myClassLoader.getResource(name); props.load(url.openStream());

value = props.getProperty(key); } catch (Throwable th) { … } }

return value; }

Page 14: Apache Utilities At Work   V5

14 © 2008 CIBER, Inc. All rights reserved

Commons Configuration Overview

• A clean way to configure your application– http://commons.apache.org/configuration

• It loads the configuration data for you• Configuration/Factory (main class) can work

with:– Properties files– XML files– JNDI– JDBC DataSource– System Properties (JVM)– .INI files (Windows)

Page 15: Apache Utilities At Work   V5

15 © 2008 CIBER, Inc. All rights reserved

Commons Configuration Overview … Cont’d

• It can handle hierarchical data• It can combine multiple data sources

(composite):

CompositeConfiguration config = new CompositeConfiguration(); config.addConfiguration(new SystemConfiguration()); config.addConfiguration(new

PropertiesConfiguration("application.properties"));

Page 16: Apache Utilities At Work   V5

16 © 2008 CIBER, Inc. All rights reserved

Properties with Commons Configuration

public class MyPropertyUtil { private static final String MY_PROPS_FILE_NAME = “…”; // Use –D to set this at startup.

public static String getProperty(String key) throws MyPropertyUtilException { Properties props = null; String value = “”, propsFileName = System.getProperty(MY_PROPS_FILE_NAME);

if (StringUtils.isNotBlank(key) && StringUtils.isNotBlank(propsFileName) { try { // FIXMEE: Move Props File Name & Constructor call to static initializer. Configuration config = new PropertiesConfiguration(propsFileName);

value = props.getString(key); } catch (Throwable th) { … } }

return value; }}

Page 17: Apache Utilities At Work   V5

17 © 2008 CIBER, Inc. All rights reserved

Session Roadmap

Where are we?

• Commons Lang• Commons Configuration• Commons Logging and Log4J• POI• Commons Email• Velocity• HttpClient• Commons IO • Summary

Page 18: Apache Utilities At Work   V5

18 © 2008 CIBER, Inc. All rights reserved

Session Roadmap

Where are we?

• Commons Lang• Commons Configuration• Commons Logging and Log4J• POI• Commons Email• Velocity• HttpClient• Commons IO • Summary

Page 19: Apache Utilities At Work   V5

19 © 2008 CIBER, Inc. All rights reserved

POI Overview

• API to access MS file formats– Word– PowerPoint– Outlook– Visio– Publisher– Excel (HSSF)– http://poi.apache.org

Page 20: Apache Utilities At Work   V5

20 © 2008 CIBER, Inc. All rights reserved

Generate an Excel File with POI

private static void populateExcelWorksheet(Collection rows, FileOutputStream fileOut) { try { if (rows.size() > 0) { HSSFWorkbook workBook = new HSSFWorkbook(); HSSFSheet workSheet = workBook.createSheet(); //Create new workSheet Iterator rowDataIterator = rows.iterator(); int rowNum = 0, maxColumnSize = 0;

while (rowDataIterator.hasNext()) { LinkedList rowStringsList = (LinkedList) rowDataIterator.next(); if (rowStringsList.size() > 0) { HSSFRow row = workSheet.createRow(rowNum); // Create header ONLY once if (rowNum == 0) { maxColumnSize = ExcelUtil.createColumnHeaders(rowStringsList, workBook, row); } else { maxColumnSize = ExcelUtil.fillRowCellValue(rowStringsList, workBook, row); } rowNum++; } }

Page 21: Apache Utilities At Work   V5

21 © 2008 CIBER, Inc. All rights reserved

Generate an Excel File with POI … Cont’d

workBook.write(fileOut);

}

}

catch (IOException e) {

...

}

}

Page 22: Apache Utilities At Work   V5

22 © 2008 CIBER, Inc. All rights reserved

Generate an Excel File with POI … Cont’d

private static short createColumnHeaders(LinkedList stringList, HSSFWorkbook workBook, HSSFRow row) { short columnNum = 0; Iterator iter = stringList.iterator(); while (iter.hasNext()) { String value = (String) iter.next();

// Create a new font and alter it. HSSFFont font = workBook.createFont(); //Customize font customizeExcelFont(font); // Fonts are set into a style so create a new one to use. HSSFCellStyle style = workBook.createCellStyle(); style.setFont(font);

HSSFCell cell = null;

cell = row.createCell(columnNum); cell.setCellStyle(style); cell.setCellValue(value); columnNum++; } return columnNum; }

Page 23: Apache Utilities At Work   V5

23 © 2008 CIBER, Inc. All rights reserved

Generate an Excel File with POI … Cont’d

private static short fillRowCellValue(LinkedList stringList, HSSFWorkbook workBook, HSSFRow row) { short columnNum = 0; Iterator iter = stringList.iterator(); while (iter.hasNext()) { String value = (String) iter.next(); HSSFCellStyle style = workBook.createCellStyle(); HSSFCell cell = null; // Set background color with light "foreground" // foreground being the filled, not the font color. style.setFillForegroundColor(HSSFColor.LIGHT_GREEN.index); style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);

cell = row.createCell(columnNum); cell.setCellStyle(style); cell.setCellValue(value); columnNum++; } return columnNum; }

Page 24: Apache Utilities At Work   V5

24 © 2008 CIBER, Inc. All rights reserved

Session Roadmap

Where are we?

• Commons Lang• Commons Configuration• Commons Logging and Log4J• POI• Commons Email• Velocity• HttpClient• Commons IO • Summary

Page 25: Apache Utilities At Work   V5

25 © 2008 CIBER, Inc. All rights reserved

Commons Email Overview

• Simple API for sending email– http://commons.apache.org/email

• Based on JavaMail API (but easier to use)• Key Areas:

– Text– HTML– Attachments

Page 26: Apache Utilities At Work   V5

26 © 2008 CIBER, Inc. All rights reserved

Using JavaMail

public void send(MyEmailParams emailParams) throws EmailException { // Send Text try { Session session = getDefaultSession(); InternetAddress[] recipientsArr = (InternetAddress[]) emailParams.getRecipients().toArray(new InternetAddress[0]);

MimeMessage msg = new MimeMessage(session); msg.setFrom(emailParams.getSender());

msg.setRecipients(Message.RecipientType.TO, recipientsArr); if (!emailParams.getCcRecipients.isEmpty(){ InternetAddress[] ccRecipientsArr = (InternetAddress[])

emailParams.getCcRecipients().toArray(newInternetAddress[0]); msg.setRecipients(Message.RecipientType.CC, ccRecipientsArr); }

Page 27: Apache Utilities At Work   V5

27 © 2008 CIBER, Inc. All rights reserved

Using JavaMail … Cont’d

msg.setSubject(emailParams.getSubject()); msg.setText(emailParams.getBody()); Transport.send(msg); // Send message } catch (MessagingException me) { … } }

private Session getDefaultSession() throws EmailException { Properties props = new Properties(); String mailSmtpHost = MyPropertyUtil.getProperty(MAIL_SMTP_HOST), mailSmtpPort = MyPropertyUtil.getProperty(MAIL_SMTP_PORT), mailDebug = MyPropertyUtil.getProperty(MAIL_DEBUG, FALSE);

props.setProperty(MAIL_TRANSPORT_PROTOCOL, SMTP); props.setProperty(MAIL_SMTP_HOST, mailSmtpPort); props.setProperty(MAIL_SMTP_HOST, mailSmtpHost); props.setProperty(MAIL_DEBUG, mailDebug);

Session session = Session.getDefaultInstance(props);

return session; }

Page 28: Apache Utilities At Work   V5

28 © 2008 CIBER, Inc. All rights reserved

Using Commons Email

public static void sendSimpleEmail(EmailParams emailParams) throws MyEmailUtilException { // Send text.

try { SimpleEmail email = new SimpleEmail(); String hostName = MyPropertyUtil.getProperty(MY_SMTP_SERVER); Iterator toAddrIter = emailParams.getToRecipients().iterator(), ccAddrIter = emailParams.getCcRecipients().iterator(); email.setHostName(hostName); email.setFrom(emailParams.getFromEmailAddr(), emailParams.getFromName()); while (toAddrIter.hasNext()) { email.addTo((String) toAddrIter.next()); } while (ccAddrIter.hasNext()) { email.addCc((String) ccAddrIter.next()); }

email.setSubject(emailParams.getSubject()); email.setMsg(emailParams.getMessage()); email.send(); } catch (EmailException e) { … } }

Page 29: Apache Utilities At Work   V5

29 © 2008 CIBER, Inc. All rights reserved

Session Roadmap

Where are we?

• Commons Lang• Commons Configuration• Commons Logging and Log4J• POI• Commons Email• Velocity• HttpClient• Commons IO • Summary

Page 30: Apache Utilities At Work   V5

30 © 2008 CIBER, Inc. All rights reserved

Velocity Overview

• Templating Engine– http://velocity.apache.org

• Other good tools exist:– FreeMarker – http://freemarker.sourceforge.net/

Page 31: Apache Utilities At Work   V5

31 © 2008 CIBER, Inc. All rights reserved

Using the Velocity API

VelocityEngine velocityEngine = new VelocityEngine();Properties props = new Properties();Template template = null;VelocityContext velocityContext = new VelocityContext(); props.setProperty(VelocityEngine.RESOURCE_LOADER, "classpath");props.setProperty("classpath." + VelocityEngine.RESOURCE_LOADER + ".class", ClasspathResourceLoader.class.getName());

velocityEngine.init(props);

try { StringWriter writer = new StringWriter(); template = velocityEngine.getTemplate(MY_TEMPLATE);

velocityContext.put(RECIPIENT_NAME, recipientName); velocityContext.put(POLICY_NUMBER, policyNumber); velocityContext.put(REFUND_AMOUNT, refundAmount);

template.merge(velocityContext, writer);} catch (…) { …}

Page 32: Apache Utilities At Work   V5

32 © 2008 CIBER, Inc. All rights reserved

Velocity Template

<HTML><BODY> <p> Dear $recipientName, Due to your safe driving record, we are refunding $refundAmount on

your auto policy ($policyNumber). </p></BODY></HTML>

Page 33: Apache Utilities At Work   V5

33 © 2008 CIBER, Inc. All rights reserved

Session Roadmap

Where are we?

• Commons Lang• Commons Configuration• Commons Logging and Log4J• POI• Commons Email• Velocity• HttpClient• Commons IO • Summary

Page 34: Apache Utilities At Work   V5

34 © 2008 CIBER, Inc. All rights reserved

Commons HttpClient Overview

• API to help develop an HTTP Client– GET / POST– Authentication– Redirect– Proxy– Encodings– Cookies

• In its final release (3.x)– http://hc.apache.org/httpclient-3.x/index.html

• To be replaced by HttpComponents:– http://hc.apache.org– Still in Beta– “Not yet, grasshopper”

Page 35: Apache Utilities At Work   V5

35 © 2008 CIBER, Inc. All rights reserved

HttpClient Example

public class MyHttpClient {… public static String sendPostRequest(MyRequestDto myRequestDto) throws MyHttpClientException {

String responseString = null; PostMethod httpPost = null; HttpClient httpClient = new HttpClient(); MyHttpClient.setupProxy(httpClient); try { // Create and send the HTTP Request. httpPost = MyHttpClient.setupHttpPostRequest(myRequestDto); httpClient.executeMethod(httpPost);

// Get the HTTP Status. if (httpPost.getStatusCode() == HttpStatus.SC_MOVED_TEMPORARILY) { MyHttpClient.handleRedirect(httpClient, httpPost); } //Get HTTP response. responseString = MyHttpClient.getHttpResponse(httpPost); …

Page 36: Apache Utilities At Work   V5

36 © 2008 CIBER, Inc. All rights reserved

HttpClient Example … Cont’d

} catch (HttpException he) { … } catch (IOException ioe) { … } finally { httpPost.releaseConnection(); } return responseString; }

private static void setupProxy(HttpClient httpClient) { // Tunnel through a proxy. String useProxy = MyPropertyUtil.getProperty(USE_PROXY); if (StringUtils.isNotBlank(useProxy) && useProxy.equalsIgnoreCase(YES)) { String proxyHost = MyPropertyUtil.getProperty(MY_PROXY_HOST), proxyPort = MyPropertyUtil.getProperty(MY_PROXY_PORT), proxyRealm = MyPropertyUtil.getProperty(MY_PROXY_REALM), proxyUser = MyPropertyUtil.getProperty(MY_PROXY_USER), proxyPassword = MyPropertyUtil.getProperty(MY_PROXY_PASSWORD);

httpClient.getHostConfiguration().setProxy(proxyHost, Integer.parseInt(proxyPort));

httpClient.getState().setProxyCredentials(proxyRealm, proxyHost, new UsernamePasswordCredentials(proxyUser, proxyPassword));

} }

Page 37: Apache Utilities At Work   V5

37 © 2008 CIBER, Inc. All rights reserved

HttpClient Example … Cont’d

private static PostMethod setupHttpPostRequest(MyRequestDto myRequestDto) { String myUrl = MyPropertyUtil.getProperty(ConfigConstants.CONFIG_MY_URL); PostMethod httpPost = new PostMethod(myUrl); // Populate HTTP Post Parameters. httpPost.addParameter(REDIR_KEY, REDIR_VALUE); httpPost.addParameter(FIRST_NAME_KEY, myRequestDto.getFirstName()); …

return httpPost; }

private static void handleRedirect(HttpClient httpclient, PostMethod httpPost) throws MyHttpClientException { try { Header locationHeader = httpPost.getResponseHeader(HTTP_RESPONSE_LOCATION_HEADER);

if locationHeader != null) { String redirectLocation = locationHeader.getValue(); httpPost.setURI(redirectLocation); httpClient.executeMethod(httpPost); } } catch (URIException ue) { … } // 2 others – HttpException, IOException }

Page 38: Apache Utilities At Work   V5

38 © 2008 CIBER, Inc. All rights reserved

HttpClient Example … Cont’d

private static String getHttpResponse(PostMethod httpPost) throws MyHttpClientException { String responseString = null; InputStream is = null;

try { is = httpPost.getResonseBodyAsStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); StringBuffer responseBuffer = new StringBuffer(); String line = null; boolean done = false;

while (!done) { line = br.readLine(); done = (line == null); if (!done) { responseBuffer.append(line); } }

responseString – responseBuffer.toString().trim(); } catch (IOException ioe) { …

Page 39: Apache Utilities At Work   V5

39 © 2008 CIBER, Inc. All rights reserved

HttpClient Example … Cont’d

} finally {

if (is != null) {

try {

is.close();

} catch (…) {

}

}

}

return responseString;

}

}

Page 40: Apache Utilities At Work   V5

40 © 2008 CIBER, Inc. All rights reserved

Session Roadmap

Where are we?

• Commons Lang• Commons Configuration• Commons Logging and Log4J• POI• Commons Email• Velocity• HttpClient• Commons IO • Summary

Page 41: Apache Utilities At Work   V5

41 © 2008 CIBER, Inc. All rights reserved

Commons IO Overview

• API to simplify IO processing– http://commons.apache.org/io

• Key Areas– Utility classes – Perform common tasks– Filters – File filter implementations– Comparators – For comparing lists of files– Streams – Stream, Reader and Writer

implementations

• My Favorite – IOUtils

Page 42: Apache Utilities At Work   V5

42 © 2008 CIBER, Inc. All rights reserved

Stream I/O without Commons IO

private static String getHttpResponse(PostMethod httpPost) throws MyHttpClientException { String responseString = null; InputStream is = null;

try { is = httpPost.getResonseBodyAsStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); StringBuffer responseBuffer = new StringBuffer(); String line = null; boolean done = false;

while (!done) { line = br.readLine(); done = (line == null); if (!done) { responseBuffer.append(line); } }

responseString – responseBuffer.toString().trim(); } catch (IOException ioe) { …

Page 43: Apache Utilities At Work   V5

43 © 2008 CIBER, Inc. All rights reserved

Stream I/O without Commons IO … Cont’d

} finally {

if (is != null) {

try {

is.close();

} catch (…) {

}

}

}

return responseString;

}

}

Page 44: Apache Utilities At Work   V5

44 © 2008 CIBER, Inc. All rights reserved

Stream I/O with Commons IO

private static String getHttpResponse(PostMethod httpPost)

throws MyHttpClientException {

String responseString = null;

InputStream is = null;

try {

is = httpPost.getResonseBodyAsStream();

responseString = IOUtils.toString(is);

} catch (IOExeception ioe) {

} finally {

IOUtils.closeQuietly(is);

}

return responseString;

}

Page 45: Apache Utilities At Work   V5

45 © 2008 CIBER, Inc. All rights reserved

Session Roadmap

Where are we?

• Commons Lang• Commons Configuration• Commons Logging and Log4J• POI• Commons Email• Velocity• HttpClient• Commons IO • Summary

– Conclusions– Questions– Resources

Page 46: Apache Utilities At Work   V5

46 © 2008 CIBER, Inc. All rights reserved

Conclusions

• Apache has a wealth of useful APIs• SourceForge (and others) also have great APIs• Use thin wrappers to hide the details• Research Open Source before coding

– Don’t re-invent the wheel– Google, anyone?

Page 47: Apache Utilities At Work   V5

47 © 2008 CIBER, Inc. All rights reserved

Questions?

Tom Marrs

Principal Architect

[email protected]

Page 48: Apache Utilities At Work   V5

48 © 2008 CIBER, Inc. All rights reserved

Resources

• Apache Main Page: http://www.apache.org• Apache Commons: http://commons.apache.org

– Lang: http://commons.apache.org/lang– Configuration: http://commons.apache.org/configuration– Logging: http://commons.apache.org/logging– Email: http://commons.apache.org/email– IO: http://commons.apache.org/io– HttpClient: http://hc.apache.org/httpclient-3.x/index.html

• Apache Log4J: http://logging.apache.org/log4j/1.2/index.html• Apache Velocity: http://velocity.apache.org• FreeMarket: http://freemarker.sourceforge.net• Apache POI: http://poi.apache.org• Apache HttpComponents: http://hc.apache.org