How to send multipart file to springboot server using tornadoFx? - spring-boot

Here can the following funcationality be acheived with TornadoFX. (Sorry for example in java)
<form method = "post" action="/store" enctype="multipart/form-data">
<label>Image</label>
<input type="file" name="imageFile" />
</form>
and on controller side
#PostMapping
public String store(#Valid Item item, #RequestParam("imageFile") MultipartFile file) throws IOException {
if (file != null) {
Path path = Paths.get(System.getProperty("user.dir") + "/images/" + file.getOriginalFilename());
Files.write(path, file.getBytes());
}
repository.save(course);
model.addAttribute("success", "Item saved successfully");
model.addAttribute("item", new Item());
return "redirect:/items/form";
}
I did not find any example, so any small example would be very helpful.
or if there is any other way to acheive this functionality?
regards

Though you can manipulate the Rest client in TornadoFX to do this, it's easier to use Apache HttpClient directly, since it's already on your classpath and provides proper interfaces for sending multipart/form-data. You'll find plenty of HttpClient usage examples for multipart/form-data here on SO :)

Related

Spring Controller does nothing

Greeting my dear fellows
I would appreciate some help since I've been 2 days googling to find out why my code is not working. My webapp is Spring running in a Weblogic Server under Eclipse. Btw, apologies for my spelling (I am not native English speaker)
Straight from my webapp, the following controller works flawless
#RequestMapping(value = "/sendFile")
public ModelAndView vistaEnvioFicheros() throws myCustomException {
ModelAndView model = null;
try {
getLog().debug("Setting model for sending a file");
model = new ModelAndView("/content/sendFileWeb");
} catch (Exception ex) {
getLog().error("Shxx happens: ", ex);
throw new myCustomException(ex.getMessage(), ex);
}
return model;
}
This controller loads a jsp file with a file browser button and a file upload button which works great too.
So when I click on the upload button the following controller triggers:
#RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
public Object subirFichero(#RequestParam(value = "file") MultipartFile file) throws myCustomException {
ModelAndView model = null;
if (file.isEmpty()){
try {
getLog().debug("File is empty");
model = new ModelAndView("/content/errorWeb");
} catch (Exception ex) {
getLog().error("Shxx happens again ", ex);
throw new myCustomException(ex.getMessage(), ex);
}
return model;
}
...
}
Problem is: when I upload empty file, errorWeb jsp file should be shown in my web browser, however nothing happens. If I debbug the controlles I can see the code runs propperly until return model sentence nonetheless errorWeb jsp file is not loaded
Could anyone give me a hint about why first controller loads it jsp view but second controller doesn't. Also I don't get a single error message in any console or whatever
Thank you very much
Ok, I got it solved! This was just a newbie thing (I am a newbie web developper).
The problem was in the client side, where my webapp was sending the request thay triggers the second controller, not by an standard href o after a submit (or whatever), but by a custom javascript function.
This custom javascript function firstly validates the file and then uploads it to the server. After that client side code stops listening the response from the server. That's why the new ModelAndView is ignored.
Thank you for your time to all of you who read the post

How to process TXT e-mail template with Thymeleaf?

I'm trying to send plain text email from Spring application with Thymeleaf.
This is my e-mail service:
#Override
public void sendPasswordToken(Token token) throws ServiceException {
Assert.notNull(token);
try {
Locale locale = Locale.getDefault();
final Context ctx = new Context(locale);
ctx.setVariable("url", url(token));
// Prepare message using a Spring helper
final MimeMessage mimeMessage = mailSender.createMimeMessage();
final MimeMessageHelper message = new MimeMessageHelper(
mimeMessage, false, SpringMailConfig.EMAIL_TEMPLATE_ENCODING
);
message.setSubject("Token");
message.setTo(token.getUser().getUsername());
final String content = this.textTemplateEngine.process("text/token", ctx);
message.setText(content, false);
mailSender.send(mimeMessage);
} catch (Exception e) {
throw new ServiceException("Token has not been sent", e);
}
}
email is sent and delivered into mailbox.
This is my plain text email template:
Token url: ${url}
but in delivered mailbox url variable is not replaced with it's value. Why?
When I use html classic HTML Thymeleaf syntax, variable is replaced:
<span th:text="${url}"></span>
What is proper syntax for e-mail text template?
You can use Thymeleaf in plain text mode as well, like in this example:
Dear [(${customer.name})],
This is the list of our products:
[# th:each="p : ${products}"]
- [(${p.name})]. Price: [(${#numbers.formatdecimal(p.price,1,2)})] EUR/kg
[/]
Thanks,
The Thymeleaf Shop
That means you can have a text-file with just this in it:
Token url: [(${url})]
Take a look at the complete documentation of those features here:
https://github.com/thymeleaf/thymeleaf/issues/395
Edit
As mentioned in a comment, make sure to use version >= 3.0 of Thymeleaf:
<properties>
<thymeleaf.version>3.0.3.RELEASE</thymeleaf.version>
<thymeleaf-layout-dialect.version>2.1.2</thymeleaf-layout-dialect.version>
</properties>
Use an HTML template like this and it will procude plain text.
<html xmlns:th="http://www.thymeleaf.org" th:inline="text" th:remove="tag">
Token url: [[${url}]]
</html>
another way, still using html could be like this
<span th:text="Token url:" th:remove="tag"></span><span th:text="${url}" th:remove="tag"></span>
What you are looking is to produce plain text so thymeleaf will return that for you.

ICEfaces libary in classpath prevents Save As dialog from popping up on file download

As soon as I add the librarys icefaces.jar icepush.jar icefaces_ace.jar to my classpath in order to use ACE components, my SaveAs dialog won't popup? I'm not sure if this is a bug but without the librarys in classpath it works. Here's my save as method :
public void downloadFile(String propertyPath) throws IOException {
ProxyFile fileToDownload = repBean.downloadFile(propertyPath);
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();
response.reset(); response.setContentType(fileToDownload.getContentType());
response.setHeader("Content-Length", String.valueOf(fileToDownload.getLength()));
response.setHeader("Content-disposition", "attachment; filename=\"" + fileToDownload.getName() + "\"");
BufferedInputStream input = null;
BufferedOutputStream output = null;
try {
input = new BufferedInputStream(fileToDownload.getContent());
output = new BufferedOutputStream(response.getOutputStream());
byte[] buffer = new byte[10240];
for (int length; (length = input.read(buffer)) > 0;) {
output.write(buffer, 0, length);
}
} finally {
output.close();
input.close();
facesContext.responseComplete();
}
}
You can't download files using ajax.
Ajax is under the covers executed by JavaScript's XMLHttpRequest object. The request will be successfully executed and the response will be successfully retrieved. However, JavaScript has no facility to write the response to client's disk file system, nor to force a Save As dialogue with the given response. That would be a huge security breach.
The cause of your concrete problem is ICEfaces itself. Namely, when you integrate ICEfaces in a JSF web application, all standard <h:commandXxx> links/buttons will silently be turned into ajax-enabled ones which indeed causes confusion among starters. Make sure that the download link/button isn't implicitly using ICEfaces-introduced ajax facility. As per their wiki page on the subject, you need to explicitly nest a <f:ajax disabled="true"> to disable this.
Disable Ajax for a Component
You can also disable Ajax at the level of the individual component:
<h:commandButton value="Send" actionListener="#{bean.sendMessage}">
<f:ajax disabled="true"/>
</h:commandButton>
Apply it on your download link/button.

how to get a httppostedfile from a ASP.NET Web API (POST or PUT) call?

Actually my question is short.
How can I get a HttpPostedFile from a ASP.NET Web API POST or PUT?
I did see that I can get various information from the Request like Request.Header, Request.Content, Request.Properties. Where in there can I find the file I passed and how can I create a HttpPostedFile from it?
Thanks in advance!
Check out the great article from Henrik Nielsen to post multi-part content (i.e posting a form with file)
UPDATE: Add simple code for a controller to receive a file without multipart content
If you only need your controller to receive a file (i.e. no multipart content), you could do something like the above. The request only contains the file binary and the filename is passed within the URL.
public Task<HttpResponseMessage> Post([FromUri]string filename)
{
Guid uploadedFile = Guid.NewGuid();
Task<HttpResponseMessage> task = Request.Content.ReadAsStreamAsync().ContinueWith<HttpResponseMessage>(t =>
{
if (t.IsFaulted || t.IsCanceled)
throw new HttpResponseException(HttpStatusCode.InternalServerError);
try
{
using (Stream stream = t.Result)
{
//TODO: Write the stream to file system / db as you need
}
}
catch (Exception e)
{
Object o = e;
return Request.CreateResponse(HttpStatusCode.InternalServerError, e.GetBaseException().Message);
}
return Request.CreateResponse(HttpStatusCode.Created, uploadedFile.ToString());
});
return task;
}
Your short question does not have a short answer I am afraid.
ASP.NET Web API exposes you to the wonders of HTTP while ASP.NET MVC abstracted some of it - in this case for HttpPostedFile.
So a bit of background:
HTTP posts where a file is involved usually has multipart form data content. This means that you are mixing different kind of content-type: your normal form data will be sent using formurlencoded while the files will be sent application/octent-stream.
So in Web API, all you have to do is to say
var contents = message.Content.ReadAsMultipartAsync(); // message is HttpRequestMessage
One of the contents will contain your file.

Making Ajax request in portlets for liferay 6

I want to make an ajax call inside my jsp file which calls processAction method of a portlet, based on the success message from processAction method i need to make another call to serveResource method of portlet,please provide some examples..
In portlets, processAction() methods are automatically followed by render method and hence ajax response will get embedded with HTML fragment generated by render method. So writing ajax in portlets is a bit tricky.
Have a look at this blog of mine.
http://ajax-and-portlets.blogspot.com/2011/09/ajax-best-practice-in-portlets.html
It gives an insight view of what's the best practice to implement ajax in portlets (for both JSR-168 and JSR-286 portlets).
In case you want sample portlets, you can contact me through the contact details from the blog. I'll be happy to help you.
Thanks
Jignesh
This question worked for me.
Basically, the Controller
#Controller
#RequestMapping("VIEW") // VIEW mapping (as opposed to EDIT)
public class MyPortlet {
#RenderMapping
public String handleRenderRequest(RenderRequest request, RenderResponse response) {
return "defaultRender";
}
#ResourceMapping("myURL")
public void handleMyResource(ResourceRequest request, ResourceResponse response) {
OutputStream outStream;
try {
outStream = response.getPortletOutputStream();
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(outStream, "Hello world!");
} catch (IOException ex) {
// TODO : Do something with errors.
}
}
}
And the JSP:
<portlet:resourceURL id="myURL" var="myURL"/>
<script type="text/javascript">
var urlink = "<%= myURL %>";
$.ajax({
url: urlink,
cache: false,
type: "POST",
success: function(jsondata) {
console.log(jsondata);
}
});
</script>
based on the success message from processAction method
That's not the right way to do it.
On calling portlet action URL in response you get usual render response, so you'll get page with all the portlets.
Instead you should use Portlet 2.0 resource serving feature, and return your response as a resource.
You can check out my portlet which has examples for both serveResource and processAction methods calling.
Ajax Jquery Portlet

Resources