Send HTML file in Apache Camel RouteBuilder - java

I am having HTML file which I want to send as a response for the rest call inside Apache camel RouteBuilder. The code looks like below
public class RestEndpointRouteBuilder extends RouteBuilder {
#Override
public void configure() {
rest("/form")
.post()
.produces(MediaType.TEXT_HTML_VALUE)
.to("file:target/classes/static/form.html");
}
But, I am getting below error when I call the API
org.apache.camel.component.file.GenericFileOperationFailedException: Cannot write null body to file: target\classes\static\form.html\ID-*****-***-****
at org.apache.camel.component.file.FileOperations.storeFile(FileOperations.java:245)
at org.apache.camel.component.file.GenericFileProducer.writeFile(GenericFileProducer.java:277)
at org.apache.camel.component.file.GenericFileProducer.processExchange(GenericFileProducer.java:165)
at org.apache.camel.component.file.GenericFileProducer.process(GenericFileProducer.java:79)
at org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:145)
Basically, I want to return an HTML file, which is a ReactJS application, alongwith JS minified files. Could someone please help me with this?

There are several problems in your code:
The more appropriate HTTP method is rather GET instead of POST
The file component here is a to endpoint so it is used as a producer, in other words, it will save into the file instead of reading it as you expect.
The URI of the file component is incorrect, the URI format is file:directoryName[?options] which means that target/classes/static/form.html is supposed to be a directory, not a file.
What you try to achieve could be done as follow:
rest("/form")
// Fix #1: Use "get" instead of "post"
.get()
.produces(MediaType.TEXT_HTML)
.to("direct:fileContent");
from("direct:fileContent")
// Fix #2: Use "pollEnrich" to use the file component as a
// consumer to read the file
// Fix #3: Fix the URI to have the directory name on one side
// and the file name on the other side
.pollEnrich("file:target/classes/static?fileName=form.html");
NB: Even if what I described above will work, please note that a rest endpoint is not meant to be used for static content, you are supposed to use a reverse proxy instead.

Related

Apache Camel: How to look inside body to determine file format

We receive .csv files (both via ftp and email) each of which can be one of a few different formats (that can be determined by looking at the top line of the file). I am fairly new to Apache Camel but want to implement a content based router and unmarshal each to the relevant class.
My current solution is to break down the files to a lists of strings, manually use the first line to determine the type of file, and then use the rest of the strings to create relevant entity instances.
Are there a cleaner and better way?
You could use a POJO to implement the type check in whatever way works best for your files.
public String checkFileType(#Body File file) {
return determineFileType(file);
}
private String determineFileType(File file) {...}
Like this you can keep your route clean by separating the filetype check and any other part of processing. Because the filetype check is just metadata enrichment.
For example you could just set the return value as a message header by calling the bean)
.setHeader("fileType", method(fileTypeChecker))
Then you can route the files according to type easily by using the message header.
.choice()
.when(header("fileType").isEqualTo("foo"))
...

How to post a big string/json using AJAX on Play Framework 1.4.x

I have a JSON that looks more or less like this:
{"id":"id","date":"date","csvdata":"csvdata".....}
where csvdata property is a big amount of data in JSON format too.
I was trying to POST this JSON using AJAX in Play! Framework 1.4.x so I sended just like that, but when I receive the data in the server side, the csvdata looks like [object Object] and stores it in my db.
My first thought to solve this was to send the csvdata json in string format to store it like a longtext, but when I try to do this, my request fails with the following error:
413 (Request Entity Too Large)
And Play's console show me this message:
Number of request parameters 3623 is higher than maximum of 1000, aborting. Can be configured using 'http.maxParams'
I also tried to add http.maxParams=5000 in application.conf but the only result is that Play's console says nothing and in my database this field is stored as null.
Can anyone help me, or maybe suggest another solution to my problem?
Thanks you so much in advance.
Is it possible that you sent "csvdata" as an array, not a string? Each element in the array would be a separate parameter. I have sent 100KB strings using AJAX and not run into the http.maxParams limit. You can check the contents of the request body using your browser's developer tools.
If your csvdata originates as a file on the client's machine, then the easiest way to send it is as a File. Your controller action would look like:
public static void upload(String id, Date date, File csv) {
...
}
When Play! binds a parameter to the File type, it writes the contents of the parameter to a temporary file which you can read in. (This avoids running out of memory if a large file is uploaded.) The File parameter type was designed for a normal form submit, but I have used it in AJAX when the browser supported some HTML5 features (File API and Form Data).

CXF JAX-RS downloading resource from URL

I want to send across resource(say a image) from some URL to front-end.
The typical way of doing this is to create a File and build the response. Is there any way in which I don't have to create the File in java code and still send the resource to front-end.
Front-end cannot access the URL due to some constraints.
Currently the Pseudo code looks like this.
File file = new File(fullPath);
FileUtils.copyURLToFile(url, file);
ResponseBuilder response = Response.ok(modulePDF);
I want to send content of URL to front-end without creating file. Is there any way?
What way did have in mind to actually obtain the file without creating a File object?
Not sure I fully understand the complete requirement, but you don't have to create a File object. You can send out a byte[], or simply write it to the response output stream by returning StreamingOutput.
#GET
public StreamingOutput getString() {
return new StreamingOutput(){
#Override
public void write(OutputStream out)
throws IOException, WebApplicationException {
// write to the `out` stream
}
};
}
For anything more than that, you will have to greatly elaborate on your requirement. The information you've provided, (especially the highlighted line) doesn't quite paint a clear enough problem as to what actual problem is you are facing.

How to get file contents from a MultipartHttpServletRequest object?

I would like to upload a file from the web page using this strategy. i.e. Ajax file upload tutorial . It is going all fine, but the issue is on the server side, where I want to open this file and read its contents.
I am using the following signature for the method which is called on the submit of the form.
i.e.
public #ResponseBody String getFile(MultipartHttpServletRequest request)
Can any body please let me know that how can I extract the contents of the file?
MultipartHttpServletRequest extends MultipartRequest, which has methods for accessing the files.
You can do this:
MultipartFile file = request.getFile(paramName);
See http://docs.spring.io/spring-framework/docs/3.2.0.M1/api/org/springframework/web/multipart/MultipartRequest.html

How can I get content from Exchange.In:Body object from a ProcessDefinition in Camel

I am integrating data between two systems using Apache Camel. I want the resulting xml to be written to an xml file. I want to base the name of that file on some data which is unknown when the integration chain starts.
When I have done the first enrich step the data necessary is in the Exchange object.
So the question is how can I get data from the exchange.getIn().getBody() method outside of the process chain in order to generate a desirable filename for my output file and as a final step, write the xml to this file? Or is there some other way to accomplish this?
Here is my current Process chain from the routebuilders configuration method:
from("test_main", "jetty:server")
.process(new PiProgramCommonProcessor())
.enrich("piProgrammeEnricher", new PiProgrammeEnricher())
// after this step I have the data available in exchange.in.body
.to(freeMarkerXMLGenerator)
.to(xmlFileDestination)
.end();
best regards
RythmiC
The file component takes the file name from a header (if present). So you can just add a header to your message with the desired file name.
The header should use the key "CamelFileName" which is also defined from Exchange.FILE_NAME.
See more details at: http://camel.apache.org/file2

Categories

Resources