Upload
tom-marrs
View
2.019
Download
0
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
Apache Utilities at Work
Tom Marrs
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
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
4 © 2008 CIBER, Inc. All rights reserved
Prerequisites
• Core Java SE• The right mindset
– Leverage existing utilities
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
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
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
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;
}
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()
10 © 2008 CIBER, Inc. All rights reserved
With StringUtils
// Usage
if (StringUtils.isEmpty(myString)) {
…
}
if (StringUtils.isBlank(myString)) {
…
}
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
12 © 2008 CIBER, Inc. All rights reserved
Getting Properties – What we want
String emailTo = MyPropertyUtil.getProperty(EMAIL_TO);
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; }
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)
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"));
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; }}
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
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
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
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++; } }
21 © 2008 CIBER, Inc. All rights reserved
Generate an Excel File with POI … Cont’d
workBook.write(fileOut);
}
}
catch (IOException e) {
...
}
}
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; }
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; }
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
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
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); }
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; }
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) { … } }
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
30 © 2008 CIBER, Inc. All rights reserved
Velocity Overview
• Templating Engine– http://velocity.apache.org
• Other good tools exist:– FreeMarker – http://freemarker.sourceforge.net/
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 (…) { …}
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>
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
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”
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); …
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));
} }
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 }
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) { …
39 © 2008 CIBER, Inc. All rights reserved
HttpClient Example … Cont’d
} finally {
if (is != null) {
try {
is.close();
} catch (…) {
…
}
}
}
return responseString;
}
}
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
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
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) { …
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;
}
}
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;
}
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
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?
47 © 2008 CIBER, Inc. All rights reserved
Questions?
Tom Marrs
Principal Architect
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