Hi guys,
I am back with the solution. I finally managed how to do that! First thing
was to find out that consumer sends all data in headers and you can't access
the exchange's body. I managed to get data from headers and pass them into
Camel's properties which could be then globally passed wherever I need to.
REST part
------------------------------------------------------------------------------------
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/upload")
@Produces(MediaType.APPLICATION_JSON)
public Response uploadFile(MultipartBody multipartBody){
return null;
}
JAVA part
------------------------------------------------------------------------------------
/*
* Method for parsing CamelHttpQuery
* The URL query looks like a=1&b=2
*/
public static Map<String, String> getQueryMap(String query) {
String[] params = query.split("&");
Map<String, String> map = new HashMap<String, String>();
for (String param : params) {
String name = param.split("=")[0];
String value = param.split("=")[1];
map.put(name, value);
}
return map;
}
/*
* Setting Camel's properties for @POST Consumer
*
* MessageContentList can't be used, because @POST consumer sends all
data
in headers.
* Therefore there is different way how to get data for properties.
*/
public void setupPostProperties(Exchange exchange) throws IOException {
String query =
exchange.getIn().getHeader("CamelHttpQuery").toString();
Map<String, String> map = getQueryMap(query);
String Host = map.get("Host");
String Port = map.get("Port");
String User = map.get("username");
String Password = map.get("password");
String Filename = map.get("pathToFile");
String FolderId = map.get("folderId");
exchange.setProperty("HOST", Host);
exchange.setProperty("PORT", Port);
exchange.setProperty("USERNAME", User);
exchange.setProperty("PASSWORD", Password);
exchange.setProperty("PATH_TO_FILE", Filename);
exchange.setProperty("FOLDER_ID", FolderId);
exchange.setProperty("UPLOAD_API", "/webservice/upload.php");
logger.debug(String.format(
"setupBasicProperties Host=%s, Port=%s,
User=%s, "
+ "Password=%s, Filename=%s,
FolderId=%s",
Host, Port, User, Password, Filename,
FolderId));
}
/*
* Sending @POST HTTP request
*
* Here we need org.apache.http.client.HttpClient library installed in
Karaf.
* It will not work with org.apache.commons.httpclient.HttpClient
* You must install org.apache.httpcomponents to Karaf.
* I am not sure which solution works, but one does :-)
*
* osgi:install -s wrap:mvn:org.apache.httpcomponents/httpmime/4.2.3
* osgi:install -s
wrap:mvn:org.apache.httpcomponents/httpclient/4.2.3
* osgi:install -s wrap:mvn:org.apache.httpcomponents/httpcore/4.2.3
*
* install mvn:org.apache.httpcomponents/httpmime/4.2.3
* install mvn:org.apache.httpcomponents/httpclient/4.2.3
* install mvn:org.apache.httpcomponents/httpcore-osgi/4.2.3
*
* This method just sets variables which will be sent via @POST request
* Using MultipartEntity I can send variables in different format(binary
file and string in this case).
* If there is a need to add more parameters, just add one more
entity.addPart()
*/
public void sendPostRequest(Exchange exchange) throws IOException {
String pathToUploader = "https://" +
exchange.getProperty("HOST").toString() + ":"
+ exchange.getProperty("PORT").toString()
+ exchange.getProperty("UPLOAD_API").toString();
String filename =
exchange.getProperty("PATH_TO_FILE").toString();
String session_id =
exchange.getProperty("SESSION_ID").toString();
String action = "A";
String output = "json";
File myfile = new File(filename);
if(myfile.exists()){
HttpClient client = new DefaultHttpClient();
client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION,
HttpVersion.HTTP_1_1);
HttpPost post = new HttpPost(pathToUploader);
MultipartEntity entity = new
MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
// For File parameters
entity.addPart("myfile", new FileBody(((File) myfile),
"application/octet-stream"));
// For usual String parameters
entity.addPart("session_id", new StringBody(session_id,
"text/plain",
Charset.forName("UTF-8")));
entity.addPart("action", new StringBody(action,
"text/plain",
Charset.forName("UTF-8")));
entity.addPart("output", new StringBody(output,
"text/plain",
Charset.forName("UTF-8")));
post.setEntity(entity);
String response =
EntityUtils.toString(client.execute(post).getEntity(),
"UTF-8");
exchange.getOut().setBody(response);
client.getConnectionManager().shutdown();
}else{
logger.error("File does not exist!!!");
throw new FileNotFoundException();
}
}
CAMEL ROUTE
---------------------------------------------------------------------------------------------------
from("cxfrs:bean:myServer")
.routeId("myService-mainRoute")
.choice()
/*
* Upload part
*/
.when(header(Exchange.HTTP_PATH).isEqualTo("/upload"))
/*
* Setting properties for @POST request
*/
.beanRef("myserviceBean", "setupPostProperties")
/*
* Authentication and getting session_id
*/
.to("direct:getSessionId")
/*
* Here you are telling Camel
that you want to send data as @POST
*/
.setHeader(Exchange.HTTP_METHOD, constant("POST"))
/*
* Here we send binary file and strings
together as @POST HTTP request.
* It simulates sending of form via
@POST method.
* Response is already in JSON format
*/
.beanRef("MyBean","sendPostRequest")
.endChoice();
/*
* Here you just call address where you get session_id
* based on your credentials.
*/
from("direct:getSessionId")
.removeHeader(Exchange.HTTP_URI)
.removeHeader(Exchange.HTTP_PATH)
.removeHeader(Exchange.HTTP_QUERY)
.recipientList(simple(BASE + API + "?" +
REST_AUTH_OPTIONS))
.beanRef("MyBean",
"getSessionId");
Hope this will help someone :-)
-Br, Roman
--
View this message in context:
http://camel.465427.n5.nabble.com/Send-file-via-POST-request-tp5728674p5729109.html
Sent from the Camel - Users mailing list archive at Nabble.com.