how to save a base64 as image in java server faces project - servlets

I am doing a project for school. Subject of project is tshirt design. I am using jsf and primefaces. But I don't know well jsf and primefaces. I wanted save a base64 from html as image in jsf project. But when I had tried to following functions, NullPointerException. This function is called in a Servlet. A base64 is grabbed by this Servlet.
public static void save(String dataURL){
line85: ExternalContext external = FacesContext.getCurrentInstance().getExternalContext();
ServletContext servletContext = (ServletContext) external.getContext();
String filename = servletContext.getRealPath("cloud.png");
BASE64Decoder decoder = new BASE64Decoder();
byte[] decodedBytes;
try {
decodedBytes = decoder.decodeBuffer(dataURL.split("data:image/(png|jpg);base64,")[1]);
BufferedImage imag=ImageIO.read(new ByteArrayInputStream(decodedBytes));
ImageIO.write(imag, "png", new File(filename));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
23.Ara.2012 17:48:20 org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [org.soft.tshirt.servlets.DesignServlet] in context with path [/Tshirt] threw exception
java.lang.NullPointerException
at org.soft.tshirt.beans.ImageBean.save(ImageBean.java:85)
at org.soft.tshirt.servlets.DesignServlet.processRequest(DesignServlet.java:102)
at org.soft.tshirt.servlets.DesignServlet.doPost(DesignServlet.java:76)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)

The current instance of the FacesContext is only available in the HTTP request thread which is been served through the FacesServlet who is the one responsible for creating the FacesContext. In other words, only when the request URL matches the URL pattern of the FacesServlet. In other words, only JSF pages, JSF managed beans (and thus not backing beans which you instantiate yourself like as is happening here!) and all other JSF artifacts like event/phase listeners, UI components, etc have the current instance of the FacesContext available to them.
In an arbitrary homegrown HTTP servlet, the FacesContext isn't available at all, for the simple reason that the FacesServlet is not been invoked beforehand. So the getCurrentInstance() method on it would return null. You know, trying to access/invoke any fields/method on null will cause NullPointerException. See also its javadoc.
In order to achieve the sole goal of obtaining the ServletContext, just invoke the inherited GenericServlet#getServletContext() method inside the servlet.
protected void doPost(...) {
String filename = getServletContext().getRealPath("cloud.png");
// ...
}
Pass that information instead to the method responsible for creating the file. You might want to extract that code into a different class which is reused between your servlet and backing bean.
Unrelated to the concrete problem, writing files to the expanded WAR folder is really a bad practice for the reasons mentioned in among others this answer: Uploaded image only available after refreshing the page.

Related

Spring MVC Processing multipart form data

Using Craig Walls book "Spring in Action, 4th Edition", 7.2. Processing multipart form data
The code does not run no matter what path you try. I even tried
C:\something. Don't you have to create the directory first?
When I run the code, I get the error below:
root cause org.springframework.web.multipart.MultipartException:
Could not parse multipart servlet request; nested exception is
java.io.IOException: The temporary upload location
[C:\Users\jokra_000\sts-bundle\pivotal-tc-server-developer-3.1.1.RELEASE\base-instance\work\Catalina\localhost\spittr\tmp\spittr\uploads]
is not valid
Has anyone successfully uploaded an image file as outlined in Chapter 7? It seems there's far more to it than what's described, as the code Craig supplied does not run. Instead it crashes and will not upload a file.
Any suggestions on how to implement MultipartFile and the Path?
Craig's suggestion:
in AbstractAnnotationConfigDispatcherServletInitializer:
#Override
protected void customizeRegistration(Dynamic registration) {
registration.setMultipartConfig(
new MultipartConfigElement("/tmp/spittr/uploads", 2097152, 4194304, 0));
}
in Controller processRegistration:
MultipartFile profilePicture = spitterForm.getProfilePicture();
profilePicture.transferTo(new File("/tmp/spittr/" + spitter.getUsername() + ".jpg"));
It worked when I did the following:
I changed MultipartResolver:
#Bean
public MultipartResolver multipartResolver() throws IOException {
return new CommonsMultipartResolver();
}
and also added the dependency:
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.2</version>
</dependency>
and then imported to the file that extends WebMvcConfigurerAdapter:
import org.apache.commons.fileupload.FileItemFactory;

Liferay: how to get the current login user details in servlet?

I'm completely new to Liferay. I have configured Orbeon Forms in Liferay by using the Proxy Portlet, finally I created an Orbeon form and sent the form data to a demo portlet (custom portlet). In the portlet I have created a servlet. If user save the orbeon form data then my servlet getting called and I'm able to get the form data. Now I need to get the current user name or userid in the servlet.
In form builder I have send the orbeon form data to my servlet.
properties-local.xml
<property
as="xs:string"
name="oxf.fr.detail.process.send.*.*"
value='require-valid
then send(uri = "http://localhost:9090/FRunner-portlet/html/jsp/formData.jsp?username={xxf:get-request-header('Orbeon-Username')}", method="POST", content="metadata")
then success-message("save-success")
recover error-message("database-error")'/>
If I tried the above code I got the following errors,
SEVERE: Exception sending context initialized event to listener instance of class org.orbeon.oxf.webapp.OrbeonServletContextListener
javax.servlet.ServletException: org.orbeon.oxf.common.ValidationException: line 80, column 122 of oxf:/config/properties-local.xml: Fatal error: Element type "property" must be followed by either attribute specifications, ">" or "/>".
at org.orbeon.oxf.webapp.OrbeonServletContextListener$$anonfun$contextInitialized$2.apply(OrbeonServletContextListener.scala:39)
at org.orbeon.oxf.webapp.OrbeonServletContextListener$$anonfun$contextInitialized$2.apply(OrbeonServletContextListener.scala:39)
at org.orbeon.oxf.util.ScalaUtils$.withRootException(ScalaUtils.scala:87)
at org.orbeon.oxf.webapp.OrbeonServletContextListener.contextInitialized(OrbeonServletContextListener.scala:39)
Caused by: org.orbeon.oxf.common.ValidationException: line 80, column 122 of oxf:/config/properties-local.xml: Fatal error: Element type "property" must be followed by either attribute specifications, ">" or "/>".
at org.orbeon.oxf.xml.XMLParsing$ErrorHandler.fatalError(XMLParsing.java:215)
at orbeon.apache.xerces.util.ErrorHandlerWrapper.fatalError(Unknown Source)
at orbeon.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at orbeon.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at orbeon.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at orbeon.apache.xerces.impl.XMLScanner.reportFatalError(Unknown Source)
SEVERE: Exception sending context destroyed event to listener instance of class org.orbeon.oxf.webapp.OrbeonServletContextListener
javax.servlet.ServletException: java.lang.NullPointerException
at org.orbeon.oxf.webapp.OrbeonServletContextListener$$anonfun$contextDestroyed$2.apply(OrbeonServletContextListener.scala:44)
at org.orbeon.oxf.webapp.OrbeonServletContextListener$$anonfun$contextDestroyed$2.apply(OrbeonServletContextListener.scala:44)
at org.orbeon.oxf.util.ScalaUtils$.withRootException(ScalaUtils.scala:87)
at org.orbeon.oxf.webapp.OrbeonServletContextListener.contextDestroyed(OrbeonServletContextListener.scala:44)
at org.apache.catalina.core.StandardContext.listenerStop(StandardContext.java:4819)
at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5466)
at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:232)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:160)
Caused by: java.lang.NullPointerException
at org.orbeon.oxf.pipeline.InitUtils$.org$orbeon$oxf$pipeline$InitUtils$$fromProperty$1(InitUtils.scala:195)
at org.orbeon.oxf.pipeline.InitUtils$.processorDefinitions$lzycompute(InitUtils.scala:196)
at org.orbeon.oxf.pipeline.InitUtils$.processorDefinitions(InitUtils.scala:179)
at org.orbeon.oxf.webapp.Orbeon$.initialize(Orbeon.scala:84)
at org.orbeon.oxf.webapp.OrbeonWebApp$$anonfun$1.apply(WebAppContext.scala:117)
at org.orbeon.oxf.webapp.OrbeonWebApp$$anonfun$1.apply(WebAppContext.scala:117)
at scala.collection.mutable.MapLike$class.getOrElseUpdate(MapLike.scala:189)
at org.orbeon.oxf.webapp.ParametersAndAttributes$$anon$1.getOrElseUpdate(WebAppContext.scala:93)
at org.orbeon.oxf.webapp.OrbeonWebApp$class.$init$(WebAppContext.scala:117)
Update
xxf:get-request-header('orbeon-liferay-user-email')
With the above statement I am able to get the liferay login user mail id. Now I need to pass this username to my portlet as a parameter. Can you please let me know what is the procedure to pass the mailid to my portlet. I tried in different ways but it is not happen. Please suggest me something to send the liferay user mail id to my portlet.
FormData Servlet code
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
try {
DataInputStream in = new DataInputStream (request.getInputStream());
StringBuffer buffer = new StringBuffer();
int value;
while ((value=in.read()) != -1) {
buffer.append((char)value);
}
String formData = buffer.toString();
System.out.println("Form Data==========>"+ formData);
} catch (Exception e) {
System.out.println("ERROR2=====>"+e);
}
}
How to get the current user details when servlet getting called?
One way is to explicitly pass it to the URL of the send action, for example:
uri = ".../FormData?username={xxf:get-request-header('Orbeon-Username')}"
In Orbeon Forms 4.9, there is a new xxf:username() function which is more direct.
On the servlet side, you can retrieve a URL parameter using:
request.getParameter("username")

How to implement Dart with Spring MVC and Thymeleaf?

I'm currently trying to implement Dart in an existing project which uses Spring MVC (4.0.0) and Thymeleaf (2.1.1) as template engine.
Currently I am deploying all my Dart resources to /dart as shown belown.
<link rel="import" th:href="#{/dart/wb-control-text.html}" />
<script type="application/dart" th:src="#{/dart/packages/polymer/init.dart}"></script>
<script th:src="#{/dart/packages/browser/dart.js}"></script>
Thymeleaf rewrites the urls to http://localhost:8080/context/dart/..., which is correct.
Dart works really great if you open a HTML file directly which has the packages folder directly beneath it. However, this is not the case in my project, which has friendly urls like /action/users/browse and you don't have access directly to the HTML file.
When a Dart library tries to import a package, I get a 404 error because it is looking for it in the wrong place (e.g. /dart/packages/polymer/packages/polymer/polymer.dart).
Do I need to provide a URL request handler or a filter that handles all **/packages/** requests (and just use paths relative to the current url)? Or is there an option in Dart where you can set where it should look for packages?
What is the solution (or workaround) for this?
Edit
I currently have a temporary solution that works, but it is dirty and I'm still looking for a cleaner solution.
I added the packages to my classpath and I created a DartPackagesFilter that streams the resources:
public class DartPackagesFilter extends OncePerRequestFilter
#Override
protected void doFilterInternal(final HttpServletRequest request,
final HttpServletResponse response,
final FilterChain filterChain)
throws ServletException, IOException {
final String uri = request.getRequestURI();
final int index = uri.indexOf("/packages/");
if ( index != -1 ){
final String resourceName = uri.substring(index);
writeResourceToResponse(response, resourceName);
return;
}
filterChain.doFilter(request, response);
}
private void writeResourceToResponse(final HttpServletResponse response, final String resourceName) throws IOException {
final ClassPathResource resource = new ClassPathResource(resourceName);
response.setContentType(resolveContentType(resourceName));
ChannelUtils.stream(resource.getInputStream(), response.getOutputStream());
}
private String resolveContentType(final String resourceName){
if ( resourceName.endsWith("dart") ){
return "application/dart";
} else if ( resourceName.endsWith("js")){
return "text/javascript";
}
throw new IllegalArgumentException("Resource must be a Dart or Javascript file!");
}
}
In web.xml:
<filter-mapping>
<filter-name>DartPackagesFilter</filter-name>
<url-pattern>*.dart</url-pattern>
<url-pattern>*.js</url-pattern>
</filter-mapping>
In my HTML file I refer to the packages relatively to the current URL:
<script src="packages/browser/dart.js"></script>
You will need to handle /packages/ requests separately, like your work-around. However, these hacks would only be needed for development when you are working with the actual .dart files.
When you deploy your app, you'll use either dart2js, dart2dart or, most likely, both. These tools produce a monolithic script file which does not rely on the external packages directory.
Since you only need the /packages/ directory for development, it is possible to set the the packages URL through a flag in Dartium. However, in my experience, this is an awkward solution since the flag applies to all Dart applications -- all Dart apps would need to fetch packages through the same URL scheme. It also makes it difficult to share your app with other Dartium installations.

sending mail using thymeleaf in Spring Schedular

I am trying to send email using thymeleaf template. But I am getting an error message as
org.thymeleaf.exceptions.TemplateProcessingException: Resource resolution by ServletContext with org.thymeleaf.resourceresolver.ServletContextResourceResolver can only be performed when context implements org.thymeleaf.context.IWebContext [current context: org.thymeleaf.context.Context]
at org.thymeleaf.resourceresolver.ServletContextResourceResolver.getResourceAsStream(ServletContextResourceResolver.java:74)
at org.thymeleaf.TemplateRepository.getTemplate(TemplateRepository.java:221)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1192)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1148)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1095)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1008)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:982)
at in.coep.vlabteam.leap.implementations.ScheduleNotificationImpl.sendNotification(ScheduleNotificationImpl.java:205)
at in.coep.vlabteam.leap.implementations.ScheduleNotificationImpl.sendScheduleNotificationMail(ScheduleNotificationImpl.java:105)
at in.coep.vlabteam.leap.services.ScheduleNotificationService.sendScheduleNotificationByMail(ScheduleNotificationService.java:47)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:64)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:53)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:98)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:206)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
10936 [taskScheduler-1] ERROR org.thymeleaf.TemplateEngine - [THYMELEAF][taskScheduler-1] Exception processing template "scheduleMail.html": Resource resolution by ServletContext with org.thymeleaf.resourceresolver.ServletContextResourceResolver can only be performed when context implements org.thymeleaf.context.IWebContext [current context: org.thymeleaf.context.Context]
I cant used WebContext() instead of Context(). Because for webContext I need HttpServletRequest object that I can't get here, because it is not in scope of request.
I am trying to send mail using context(), but I am getting an error.
Please anyone have solution on this. Thanks in advance
Here is my code,
final Context ctx = new Context();
ctx.setVariable("eagletId", user.getEagletId());
ctx.setVariable("name", user.getFirstName());
ctx.setVariable("setSentDate", new Date());
ctx.setVariable("department", user.getDepartment());
ctx.setVariable("batch", user.getBatch());
// ctx.setVariable("month" Constants.LeapConstants.UserType);
// Prepare message using a Spring helper
final MimeMessage mimeMessage = this.mailSender.createMimeMessage();
final MimeMessageHelper message =
new MimeMessageHelper(mimeMessage, true /* multipart */, "UTF-8");
message.setSubject("Create your report for month");
message.setFrom("leap#gmail.com");
message.setTo("vlab#gmail.com");
// Create the HTML body using Thymeleaf
final String htmlContent = this.templateEngine.process("scheduleMail.html", ctx);
message.setText(htmlContent, true /* isHtml */);
// Send mail
this.mailSender.send(mimeMessage);
Your template engine is configured with ServletContextTemplateResolver instead of either FileTemplateResolver or ClassLoaderTemplateResolver. This will be defined most likely in a spring config file somewhere. If configured in code, see the Thymeleaf user's guide on configuring the template engine and configuration of the templateResolver. It's good doc.
Via xml configuration, it should look something like this:
<beans:bean id="templateResolver"
class="org.thymeleaf.templateresolver.ClassLoaderTemplateResolver">
</beans:bean>

RequestDispatcher ending in infinite loop

I have two WAR applications and the mode of communication between them is via servlets.
My application (WAR A) opens a child window with the URL of a servlet in another WAR (lets say WAR B).
The servlet (in WAR B) processes the data and should send the processed data back to original application's servlet (i.e WAR A's servlet).
But this process ends in an infinite loop and also the URL parameters sent from WAR-A are null.
Here is the code snippet :
The below script opens a child window with the URL of servlet in WAR-B also passing some URL parameters.
function invokePlugin(invokeURL, custValJSON, meaCompPartJSON) {
window.open(invokeURL + '?custValJSON=' + custValJSON,'');
}
Below is servlet code in WAR-B which extracts the URL parameters and process the data and again send the request back to WAR-A's servlet...
private void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String custValJSON = request.getParameter("custValJSON");
System.out.println("custValJSON : " + custValJSON);
CustomValues custVal = gson.fromJson(custValJSON, CustomValues.class);
if(custVal != null) {
System.out.println("Cust val details : " + custVal.getName());
custVal.setValue("Satya");
}
String destination = "/testPlannerPluginResult";
RequestDispatcher reqDispatch = request.getRequestDispatcher(destination);
request.setAttribute("custValJSON", gson.toJson(custVal));
if(reqDispatch != null) {
reqDispatch.forward(request, response);
}
}
Does anybody have idea on this?
Regards,
Satya
That then just means that the servlet is basically calling itself everytime. I don't immediately see the cause in the information given so far, but apparently the URL which you passed into the getRequestDispatcher() matches the URL of the servlet itself.
I however see a major mistake here:
RequestDispatcher reqDispatch = request.getRequestDispatcher(destination);
request.setAttribute("custValJSON", gson.toJson(custVal));
That can impossibly invoke the servlet which runs in another servlet context (read: another WAR). You need ServletContext#getContext() first to get the other servlet context and then use ServletContext#getRequestDispatcher() to dispatch the request to there.
ServletContext otherServletContext = getServletContext().getContext("/otherContextPath");
RequestDispatcher dispatcher = otherServletContext.getRequestDispatcher(destination);
This only requires that the both WARs are configured to expose the context for sharing. On Tomcat for example, this is to be done by adding crossContext="true" to the <Context>.

Resources