Tuesday, August 18, 2015

How to make a POST request in Java with multipart-form encoding with parameters and a file upload



download httpcore-4.4.1.jar, httpclient-4.5.jar and httpmime-4.5.jar from this link
http://ftp.wayne.edu/apache//httpcomponents/httpclient/binary/httpcomponents-client-4.5-bin.zip

extract zip file, go into lib directory, get jars and add to your projects WEB-INF/lib folder
Then add jars to build classpath in eclipse


In your java code, paste this code and resolve dependencies, then run it.

resumeFile is a File
urlString is the full URL of the rest API you're connecting to
paramName1/value1 should be self explanatory
cookieValue is used in some API's if there is authentication via cookies

====================

        CloseableHttpClient httpClient = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost(urlString);
   
        // This is how to set a header cookie if you need one
    httpPost.addHeader("Cookie",  "cookieValue");

    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
    builder.addTextBody("paramName1", "paramValue1", ContentType.TEXT_PLAIN);
     builder.addTextBody("paramName2", "paramValue2", ContentType.TEXT_PLAIN);
     builder.addTextBody("paramName3", "paramValue3", ContentType.TEXT_PLAIN);
   
    builder.addBinaryBody("ResumeFile", resumeFile);
   
    HttpEntity multipart = builder.build();

    httpPost.setEntity(multipart);

        try
        {
                
        CloseableHttpResponse response = httpClient.execute(httpPost);
       
        if(response.getStatusLine().getStatusCode() == 200 )
        {
HttpEntity entity = response.getEntity();
if (entity != null)
{
String responseBody = EntityUtils.toString(entity);
System.out.println("finalResult: " + responseBody.toString());
                } else {
                log.info("Entity is null");
                }        
        }
     
        } catch (IOException e) {
            e.printStackTrace();
        }          

Monday, July 13, 2015

Web Services connection - cookie value retrieval and resubmission

package [COMPANY NAME];

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom2.*;
import org.jdom2.input.SAXBuilder;

public class WebServiceHelper {

private final String USER_AGENT = "Mozilla/5.0";
private static Log log = LogFactory.getLog(WebServiceHelper.class);


/**
     * Login Form
     * @param username
     * @param password
     * @param entityId
     * @return
     */
    public LoginToken login( String username, String password, String entityId) {
   
    LoginToken token = new LoginToken();
   
try {
URL url = new URL("REST-URL");

HttpURLConnection con = (HttpURLConnection) url.openConnection();

//add reuqest header
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", USER_AGENT);
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");

String urlParameters = "UserName=" + username + "&Password=" + password + "&EntityID=" + entityId;

// Send post request
con.setDoOutput(true);

DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();

con.connect();

// retrieves the cookie from the response header
token.setCookie(con.getHeaderField("Set-Cookie"));

SAXBuilder builder = new SAXBuilder();
Document xmlDocument;

xmlDocument = builder.build(con.getInputStream());
xmlDocument.setDocType(new DocType("xml"));
Element rss = xmlDocument.getRootElement();

// retrieves the currentUserID from the xml response
token.setGuID(rss.getChild("Data").getChildText("Message").split("\\|")[1]);


} catch (JDOMException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}

return token;

}
   
   
   
    public Element callService( String urlString, String method, String urlParameters, LoginToken token ) {
   
    Element element = null;
   
try {
URL url = new URL(urlString);

HttpURLConnection con = (HttpURLConnection) url.openConnection();

//add reuqest header
con.setRequestMethod(method);
con.setRequestProperty("Cookie", token.getCookie());
con.setRequestProperty("User-Agent", USER_AGENT);
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");

// Send post request
con.setDoOutput(true);

// USE THIS ONLY ON POST METHODS
if ( method.toUpperCase().equals("POST")) {
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
}

con.connect();

SAXBuilder builder = new SAXBuilder();
Document xmlDocument;

int status = con.getResponseCode();
log.info("Response Code: " + status);

// MAKE SURE THE RESPONSE CODE IS VALID, AKA 200.
if ( status == 200 ) {
xmlDocument = builder.build(con.getInputStream());
xmlDocument.setDocType(new DocType("xml"));
element = xmlDocument.getRootElement();
} else if ( status == 404 ) {
log.info("404 ERROR: IF YOU'RE MAKING A GET CALL. MAKE SURE YOU'RE NOT WRITING OUTPUT");
}


} catch (JDOMException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}

return element;

}
   


public static void printOutElements(Element current, int depth) {
   printSpaces(depth);
   if ( null != current ) {
   System.out.println(current.getName() + " " + current.getValue());
   List children = current.getChildren();
   Iterator iterator = children.iterator();
   while (iterator.hasNext()) {
     Element child = (Element) iterator.next();
     printOutElements(child, depth+1);
   }
   }
 
 }

private static void printSpaces(int n) {
 
   for (int i = 0; i < n; i++) {
     System.out.print(' ');
   }
 
 }
 
   

   

}

How to POST an XML Feed file to Google GSA Server with Java

Instead of use the Google GSA python scripts or other google related java code for uploading a feed to the GSA, I decided to write my own Java XML Feed Client for Google GSA. This took some time to write. If you get a 200 response , that means the file upload succeeded. Log into your GSA admin console, go to the Feeds page, scroll down and you should see the feed under the datasource column.

Hopefully it saves someone out there some time and frustration. If you enjoyed this code and want to say thank you or discuss consulting, drop me a line , sean at computervip dot com

Note: replace any [ ] with the name of your files and url's

---------------------------





import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.security.GeneralSecurityException; import java.util.logging.Level; import javax.net.ssl.HttpsURLConnection; import org.apache.http.HttpEntity; import org.apache.http.entity.mime.HttpMultipartMode; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.content.FileBody; import org.apache.log4j.Logger; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;


        private static Log log = LogFactory.getLog(FeedUploader.class);
private static final String feedFileName = "[yourxmlfile].xml";
private static final String boundary = "*****";
private static final int CONNECT_TIMEOUT = 15000;
private static final int READ_TIMEOUT = 10000;
private static final String CRLF = "\r\n";
private static final String charset = "UTF-8";
private static final String BOUNDARY = "<<";
private static final String TEXT_PLAIN = "text/plain";
private static final String TEXT_XML = "text/xml";
private String feedType = "metadata-and-url";
private String dataSource = "[your-data-source-name]";
private HttpURLConnection conn = null;
OutputStream out = null;

public void uploadFeed() {

try {
// RETRIEVE THE XML FEED FROM THE WEB-INF/FEEDS FOLDER IN THIS PROJECT
// THEN CREATE THE FILE OBJECT USING THE PATH TO THE FEED
URL resource = getClass().getResource("/");
String path = resource.getPath();
path = path.replace("classes/", "feeds/");
log.info("Path = " + path.toString());
File feedFile = new File(path.toString() + feedFileName);

// CREATE AN HTTL URL CONNECTION
URL url = new URL("http://[yourserver.com]:19900/xmlfeed");
conn = (HttpURLConnection) url.openConnection();

// SET THE POST REQUEST HEADERS
conn.setConnectTimeout(CONNECT_TIMEOUT);
conn.setReadTimeout(READ_TIMEOUT);
conn.setRequestMethod("POST");
conn.setDoOutput(true); // ALLOWS THE FILE TO HAVE AN OUTPUTSTREAM
conn.setRequestProperty("ENCTYPE", "multipart/form-data");  // THIS MEANS WE'RE UPLOADING A FILE
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY); // THIS MEANS WE'RE UPLOADING A FILE

// DO THE MULTI-PART ENCODING
StringBuilder buf = new StringBuilder();
byte[] prefix;

// BUILD THE DATA PAYLOAD PREFIX
contentWrapper(buf, "datasource", TEXT_PLAIN);
buf.append(dataSource).append(CRLF);
contentWrapper(buf, "feedtype", TEXT_PLAIN);
buf.append(feedType).append(CRLF);
contentWrapper(buf, "data", TEXT_XML);
prefix = buf.toString().getBytes(charset);

// BUILD THE DATA PAYLOAD SUFFIX
byte[] suffix;
buf.setLength(0);
buf.append(CRLF).append("--").append(BOUNDARY).append("--").append(CRLF);
suffix = buf.toString().getBytes(charset);

// EVERY POST REQUEST NEEDS THE CORRECT CONTENT LENGTH
// GETS THE LENGTH OF THE PREFIX TEXT, THE LENGTH OF THE FILE AND THE LENGTH OF THE SUFFIX TEXT
// THEN TAKES THE STRING VALUE OF THEM AND SETS THE "CONTENT LENGTH" ATTRIBUTE OF THE REQUEST
long contentLength = prefix.length + feedFile.length() + suffix.length;
String strContentLength = new Long(contentLength).toString();
log.info("Content Length = " + strContentLength );
conn.setRequestProperty("Content-Length", strContentLength);

// WRITE THE FILE TO THE REQUEST OBJECT IN 3 PARTS
// FIRST IS THE PREFIX, THEN THE DATA PAYLOAD, THEN THE SUFFIX
out = conn.getOutputStream();

InputStream ios = null;
out.write(prefix);
try {
       byte[] buffer = new byte[4096];
       // FILE MUST BE CONVERTED TO FILEINPUTSTREAM IN ORDER TO GET METHODS THAT ALLOW TO READ BYTES
       ios = new FileInputStream(feedFile);
       int read = 0;      
       // ITERATE THROUGH THE XML FILE AND READ 4096 BYTES AT A TIME TO THE OUTPUTSTREAM
       while ( (read = ios.read(buffer)) != -1 ) {
           out.write(buffer, 0, read);
       }
   } finally {
    ios.close();
   }
out.write(suffix);
out.flush();

// AFTER THE FILE IS SENT - GETRESPONSECODE RETRIEVES A NUMBER INDICATING THE SERVER RESPONSE
// 200 RESPONSE IS GOOD!
// 400 RESPONSE MEANS SOMETHING IS OFF
// 411 RESPONSE MEANS THE CONTENT LENGTH IS INCORRECT
int responseCode = conn.getResponseCode();
log.info("Response Code Returned: " + responseCode);

} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

/**
* EACH FORM PART NEEDS PROPER FORMATTING OR AKA CONTENT DISPOSITION
* @param builder
* @param name
* @param mimetype
*/
private void contentWrapper(StringBuilder builder, String name, String mimetype) {
builder.append("--").append(BOUNDARY).append(CRLF);
builder.append("Content-Disposition: form-data;");
builder.append(" name=\"").append(name).append("\"").append(CRLF);
builder.append("Content-Type: ").append(mimetype).append(CRLF);
builder.append(CRLF);
}

Wednesday, May 27, 2015

CORS vs JSONP in Java

I’m having issues with accessing your web server.  This is a total dealbreaker. If we can’t fix this, we can’t even go forward. Nothing in the WebServiceHelper you provided deals with CORS … The way to get around CORS is to use JSONP but JSONP does not support POST AND your code does not use JSON or JSONP …. I’m assuming because all your code is inter-domain communicating, you don’t have the CORS issues. Simply put, if you use XMLHttpRequest across different domains, you must resolve Cross Origin Allow Origin issues, I am 100% certain of this. See my tests below.  

We need to implement CORS “access control” on your server.  I will need a technical resource to work through it with me. Right now, we cannot continue. We’re stuck.

Please see my reference materials.

Thursday, March 12, 2015

PANDA SEO Design tips

  • Would you trust the information presented in this article?
  • Is this article written by an expert or enthusiast who knows the topic well, or is it more shallow in nature?
  • Does the site have duplicate, overlapping, or redundant articles on the same or similar topics with slightly different keyword variations?
  • Would you be comfortable giving your credit card information to this site?
  • Does this article have spelling, stylistic, or factual errors?
  • Are the topics driven by genuine interests of readers of the site, or does the site generate content by attempting to guess what might rank well in search engines?
  • Does the article provide original content or information, original reporting, original research, or original analysis?
  • Does the page provide substantial value when compared to other pages in search results?
  • How much quality control is done on content?
  • Does the article describe both sides of a story?
  • Is the site a recognized authority on its topic?
  • Is the content mass-produced by or outsourced to a large number of creators, or spread across a large network of sites, so that individual pages or sites don’t get as much attention or care?
  • Was the article edited well, or does it appear sloppy or hastily produced?
  • For a health related query, would you trust information from this site?
  • Would you recognize this site as an authoritative source when mentioned by name?
  • Does this article provide a complete or comprehensive description of the topic?
  • Does this article contain insightful analysis or interesting information that is beyond obvious?
  • Is this the sort of page you’d want to bookmark, share with a friend, or recommend?
  • Does this article have an excessive amount of ads that distract from or interfere with the main content?
  • Would you expect to see this article in a printed magazine, encyclopedia or book?
  • Are the articles short, unsubstantial, or otherwise lacking in helpful specifics?
  • Are the pages produced with great care and attention to detail vs. less attention to detail?
  • Would users complain when they see pages from this site?
  1. On SEO pages, make sure each page has somewhat unique content and a UNIQUE DESCRIPTION AND LISTING
  2. Create unique content

  3. • Use the results to define low quality sites with the factors that Google can measure. This gives Google a mathematical definition of low quality.

  1. If we start here, we can think of a number of factors that Google might be able to measure to define low quality, including:
    • A high % of duplicate content. This might apply to a page, a site or both. If it’s a site measure then that might contribute to each page’s evaluation.
    • A low amount of original content on a page or site.
    • A high % (or number) of pages with a low amount of original content.
    • A high amount of inappropriate (they don’t match the search queries a page does well for) adverts, especially high on the page.
    • Page content (and page title tag) not matching the search queries a page does well for.
    • Unnatural language on a page including heavy-handed on-page SEO (‘over-optimization’ to use a common oxymoron). Eg unnatural overuse of a word on a page.
    • High bounce rate on page or site.
    • Low visit times on page or site.
    • Low % of users returning to a site.
    • Low clickthrough % from Google’s results pages (for page or site).
    • High % of boilerplate content (the same on every page).
    • Low or no quality inbound links to a page or site (by count or %).
    • Low or no mentions or links to a page or site in social media and from other sites.

Thursday, February 12, 2015

Liferay 6.2 - How to submit a form on another pages portlet to populate fields on another page in a different portlet

So, lets say I have a search form at the top of a page in one portlet. All you want it to do is take the parameters and forward it to a search form. Simple right?

Sort of... So let me copy all the code that pertains to this whole thing in order of processing.


[PORTLET A: VIEW.JSP]

<portlet:actionURL var="editContentURL">
    <portlet:param name="method" value="find-a-job" />
</portlet:actionURL>

<aui:form action="<%= editContentURL %>" method="post">
 <aui:input name="<portlet:namespace />jobTitle" placeholder="Job Title" />
<aui:button type="submit" value="Submit" />
</aui:form>


[PORTLET A: CUSTOM MVC PORTLET > processAction( )]

ThemeDisplay themeDisplay = (ThemeDisplay)aReq.getAttribute(WebKeys.THEME_DISPLAY);
String jobTitle = ParamUtil.getString(aReq, "<portlet:namespace />jobTitle");
String redirect = themeDisplay.getPortalURL() + "/web/48924/jobseekers/find-a-job?jobTitle=" + jobTitle;
aResp.sendRedirect(redirect);


[PORTLET B: CUSTOM MVC PORTLET > doView() ]

HttpServletRequest httpReq = PortalUtil.getOriginalServletRequest(PortalUtil.getHttpServletRequest(renderRequest));
String jobTitle = httpReq.getParameter("jobTitle");

log.info("jobTitle = " + jobTitle);
renderRequest.setAttribute("jobTitle",  jobTitle);


[PORTLET B: VIEW.JSP ]

<% String jobTitle = (String)request.getAttribute("jobTitle"); %>
<aui:input label="Job Title or Keywords" name="<portlet:namespace />title" cssClass="title1" value="<%= jobTitle %>" />

Friday, February 6, 2015

Liferay 6.2 - Display a sub-tree layout type side nav bar in Liferay

<%@ include file="init.jsp" %>
<%
        long groupId = themeDisplay.getLayout().getGroupId();
List<Layout> rootLayouts = LayoutLocalServiceUtil.getLayouts(layout.getGroupId(), layout.isPrivateLayout());

String friendlyURL = themeDisplay.getLayout().getFriendlyURL();
friendlyURL = friendlyURL.substring(friendlyURL.indexOf("/") + 1);
String rootURL = friendlyURL.substring(0, friendlyURL.indexOf("/"));

%>


<ul class="unstyled">
<% 

for (Layout layout1 : rootLayouts ) { 
if ( layout1.getFriendlyURL().contains(rootURL)) {
%>       
            <li><a href="/web/<%= groupId %><%= layout1.getFriendlyURL() %>"><%= layout1.getName() %></a></li>
        <% } } %>

Tuesday, January 27, 2015

Liferay Snippets

<!-- This is my latest init.jsp for all JSP files -->
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%@ taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %>
<%@ page import="com.liferay.portal.model.Layout"%>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList"%>
<%@ page import="javax.portlet.PortletPreferences" %>
<%@ page import="com.liferay.portal.kernel.util.StringPool" %>
<%@ page import="com.liferay.portal.theme.ThemeDisplay"%>
<%@ page import="com.liferay.portal.kernel.util.Constants" %>
<%@ page import="com.liferay.portal.kernel.util.GetterUtil" %>
<%@ page import="com.liferay.portal.service.LayoutLocalServiceUtil" %>
<%@ page import="com.liferay.portal.service.ResourceActionLocalServiceUtil" %>
<%@ page import="com.liferay.portal.model.LayoutConstants" %>
<portlet:defineObjects />
<liferay-theme:defineObjects />



<!-- How to get the themedisplay object in JSP --->

Use imports above
Instance ID <%= themeDisplay.getPortletDisplay().getInstanceId() %><br>
Id <%= themeDisplay.getPortletDisplay().getId() %><br>
Name <%= themeDisplay.getPortletDisplay().getPortletName() %><br>


<!-- How to iterate over the layouts -->

long rootLayoutId = LayoutConstants.DEFAULT_PARENT_LAYOUT_ID;
List<Layout> rootLayouts = LayoutLocalServiceUtil.getLayouts(layout.getGroupId(), layout.isPrivateLayout(), rootLayoutId);
long groupId = themeDisplay.getLayout().getGroupId();
String friendlyUrl = themeDisplay.getLayout().getFriendlyURL();
List<Layout> l2  = LayoutLocalServiceUtil.getLayouts( groupId, false);

for (Layout pageProperties : l2)
{
       %>
            <%= pageProperties.getFriendlyURL() %>
        <%
}



<!-- Improving the Default Message Board Email Notifications -->
<b>Dear User, <br><br>
[$MESSAGE_USER_NAME$] ( [$MESSAGE_USER_ADDRESS$] ) has added a new message. <br><br></b>
<blockquote><i>[$MESSAGE_BODY$]</i></blockquote>


<!--- generate your own child page sitemap -->
<%
String showLocationAddress_view = portletPreferences.getValue("showLocationAddress", "String");
long groupId = themeDisplay.getLayout().getGroupId();
String friendlyUrl = themeDisplay.getLayout().getFriendlyURL();

long rootLayoutId = LayoutConstants.DEFAULT_PARENT_LAYOUT_ID;
long layoutId = LayoutConstants.DEFAULT_PLID;
String typeUrl = LayoutConstants.TYPE_URL;
List<Layout> rootLayouts = LayoutLocalServiceUtil.getLayouts(layout.getGroupId(), layout.isPrivateLayout());
List<Layout> layouts55 = themeDisplay.getLayout().getAllChildren();
%>

rootlayoutid <%= rootLayoutId %><br>
layoutid <%= layoutId %> <br>
typeurl <%= typeUrl %> <br>
locale = <%= themeDisplay.getLocale() %><br>
size: = <%= layouts55.size() %><br>

<ul>

<%


for (Layout layout1 : layouts55 )
{
%>      
           <li><a href="/web/<%= groupId %>/<%= layout1.getFriendlyURL() %>"><%= layout1.getName() %></a></li>
       <%
}

%></ul><%