Sunday, 21 May 2017

Serve static resources from external folder outside webapps tomcat

This is quite an important blog for all folks who is looking on how to serve static content from a location on a disk which is completely outside of the webapps folder in Apache Tomcat. This method is quite useful to server images, JS, CSS, PDFs and even static HTML web pages.

Tomcat will serve any static content from a WAR file using the DefaultServlet. This works great for serving files that are bundled with your Java code inside of a WAR file – it’s fast enough for most purposes and it just works, but with one major drawback: you have to re-deploy the WAR file if you want to add or amend a static file.

Tomcat can be configured to read files from anywhere on the disk and serve on a specific URL. This configuration is completely separate to our application configuration.

You just need to change a single file server.xml that resides under $CATALINA_HOME/config/server.xml.

Just open the server.xml file and make the changes like below.

Remember: You need to take bounce of server after the making the changes to take effect of the changes.

<Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
   
  <Context docBase="C:\Ankur\testFiles"  path="/companyLogo" />

       <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />

</Host>

A <context>  element is added inside the <HOST>  element. Context has two attributes: docBase is the directory on disk that contains your static files and path is the URL that you want to serve the files on. 

Make sure that Tomcat has access to read the files in docBase. Using the example server.xml snippet above, if we had an image in C:\Ankur\testFiles called test.png then we would be able to access it via local Tomcat instance using http://localhost:8081/companyLogo/test.png.

Let's see the example below:

1) Put files inside the C:\Ankur\testFiles directoy

2) Hit the URL: http://localhost:8081/companyLogo/7.png and see the result:




That's it !!

Saturday, 20 May 2017

Spring MVC RESTful web service for file upload

This is one of the common requirement in all the project to upload a file. In the blog, we are gonna to show you the complete example how to create a REST service in Spring that will be used to upload any type of file.

After this blog,  you have learned to how to create REST web service that will take file as a input parameter and upload to any one of the location.

More blogs:

RESTFul API in Spring MVC : CRUD Operation

Secure RESTFul API using OAuth2 : Spring


Download project from here

Tools and Technologies used in this project
  1. Apache Maven 3.0.4
  2. JDK 1.8
  3. Spring 4.2.5.RELEASE
  4. commons fileupload 1.3.1
  5. Eclipse
  6. Tomcat 8.0.38

Project Structure:



pom.xml

As we are using maven project. Let's define the spring specific maven dependencies.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

 <modelVersion>4.0.0</modelVersion>

 <groupId>FileUpload</groupId>

 <artifactId>FileUpload</artifactId>

 <version>0.0.1-SNAPSHOT</version>

 <packaging>war</packaging>

 <name>FileUpload</name>

 <properties>

  <java-version>1.8</java-version>

  <org.springframework-version>4.2.5.RELEASE</org.springframework-version>

  <failOnMissingWebXml>false</failOnMissingWebXml>



 </properties>

 <dependencies>

  <!-- Apache Commons FileUpload -->

  <dependency>

   <groupId>commons-fileupload</groupId>

   <artifactId>commons-fileupload</artifactId>

   <version>1.3.1</version>

  </dependency>



  <!-- Apache Commons IO -->

  <dependency>

   <groupId>commons-io</groupId>

   <artifactId>commons-io</artifactId>

   <version>2.4</version>

  </dependency>



  <dependency>



   <groupId>org.springframework</groupId>

   <artifactId>spring-core</artifactId>

   <version>${org.springframework-version}</version>

  </dependency>

  <dependency>

   <groupId>org.springframework</groupId>

   <artifactId>spring-web</artifactId>

   <version>${org.springframework-version}</version>

  </dependency>

  <dependency>

   <groupId>org.springframework</groupId>

   <artifactId>spring-context</artifactId>

   <version>${org.springframework-version}</version>

   <exclusions>

    <!-- Exclude Commons Logging in favor of SLF4j -->

    <exclusion>

     <groupId>commons-logging</groupId>

     <artifactId>commons-logging</artifactId>

    </exclusion>

   </exclusions>

  </dependency>

  <dependency>

   <groupId>org.springframework</groupId>

   <artifactId>spring-webmvc</artifactId>

   <version>${org.springframework-version}</version>

  </dependency>



  <dependency>

   <groupId>javax.servlet</groupId>

   <artifactId>javax.servlet-api</artifactId>

   <version>3.0.1</version>

   <scope>provided</scope>

  </dependency>





 </dependencies>



 <build>

  <finalName>FileUpload</finalName>

 </build>

</project>



Spring configuration file

In this project we are using java based configuration instead of xml based.

You need to configure multipartResolver which will help to accept multi part requests, along with it's implementation (CommonsMultipartResolver). Also you can provide "maxUploadSize" etc.. properties.


package com.test.configuration;

import java.io.IOException;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration 
@ComponentScan("com.test")
@EnableWebMvc
public class Config extends WebMvcConfigurerAdapter {
 @Bean(name="multipartResolver") 
    public CommonsMultipartResolver getResolver() throws IOException{
        CommonsMultipartResolver resolver = new CommonsMultipartResolver();     
        
        //Set the maximum allowed size (in bytes) for each individual file.
        resolver.setMaxUploadSizePerFile(5242880);//5MB     
         
        return resolver;
    }
}



Below file represents the dispatcher servlet configuration:


package com.test.configuration;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;


public class WebInitializer implements WebApplicationInitializer {

 public void onStartup(ServletContext servletContext) throws ServletException {        
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); 
        ctx.register(Config.class);  
        ctx.setServletContext(servletContext); 
        Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));  
        servlet.addMapping("/");  
        servlet.setLoadOnStartup(1);  
    }  
}



File Upload RestController

The class is marked up with @RestController annotation , which accept HTTP web-service requests and returns the response.

Simple uploadFile method is written which helps to upload file at destination location, In which you need to pass a MultipartFile as a method parameter e.g. @RequestParam("file") MultipartFile file.


package com.test.controller;

import java.io.File;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

@RestController
public class FileUploadController {

 @RequestMapping(value = "/upload", method = RequestMethod.POST)
 public ResponseEntity uploadFile(@RequestParam("file") MultipartFile file){
  
  String originalFilename = file.getOriginalFilename();
     File destinationFile = new File("C:\\Ankur\\testFiles\\"+originalFilename);
     try {
                 
      file.transferTo(destinationFile);
   System.out.println("File path "+destinationFile.getPath());
   System.out.println("File size "+file.getSize());
  } catch (Exception e) {
   
   e.printStackTrace();
  }
  
  
  return new ResponseEntity(destinationFile.getPath(),HttpStatus.CREATED);
 }
}


Once the file will be uploaded, it will return the file path.

Testing

To verify this Rest API, I am using POSTMAN rest client.

Please follow the below instructions to send a POST request using POSTMAN client.

  1. Create .war file and deploy on the tomcat server
  2. Choose POST to be the selected HTTP method.
  3. Specify the request URL as http://localhost:8081/FileUpload/upload
  4. Do not add any header
  5. Select form-data radio button under the Body, enter input parameter name as file, select file from drop down and finally select the file to upload.
  6. Click on Send Button.
  7. Server response with uploaded file path.





Error assembling WAR: webxml attribute is required (or pre-existing WEB-INF/web.xml if executing in update mode) -> [Help 1]

Some time you will be struggling with building the war using maven and will get the error:

Error assembling WAR: webxml attribute is required (or pre-existing WEB-INF/web.xml if executing in update mode) -> [Help 1]

This is because you don't have web.xml in your project and trying to create .war file using maven then you will get this error for sure.

To resolve the issue you need to set the failOnMissingWebXml to false in pom.xml file.

For example:

<properties>
    <failOnMissingWebXml>false</failOnMissingWebXml>  
</properties>

Create .war file. This time you will get success for sure.

Friday, 12 May 2017

Oracle Integration Cloud Service(ICS)

This is my first blog on Oracle Integration Cloud Service(ICS) that would be very useful for all the folks who are interested in learning new Oracle Cloud Service.

In subsequent series of blogs, we will walk you through the concepts as well as running the demo.

Let's get started with the small concept of ICS.

What is Oracle Integration Cloud Service(ICS)?

Oracle Integration Cloud Service (ICS) is Oracle’s integration Platform as a Service (iPaaS). It provides a web-based interface to integrate Software as a Service (SaaS) and on-premise applications. It includes various technology and application adapters.

Oracle Integration Cloud Service (ICS) is a simple and powerful integration platform in the cloud to maximize the value of your investments in SaaS and on-premises applications.

Oracle Integration Cloud Service is Oracle's integration platform as a service (iPaaS) and includes an intuitive web-based integration designer for point and click integration between applications, a rich monitoring dashboard that provides real-time insight into the transactions, all of it running on a mature runtime platform on Oracle Cloud.

ICS will help customers accelerate their integration projects by pre-integrating with several SaaS Applications and will significantly shorten their time-to-market through a highly intuitive user interface and a large library of SaaS Adapters

Advantages of ICS
  • Fast
  • Enterprise grade
  • Simple
  • Little knowledge of technologies required
What integration we can do with ICS?
  • Integration of SaaS to SaaS application
  • Integration of SaaS to on-premises application
  • Integration of on-premises to SaaS application
  • Integration of on-premises to on-premises application
Adapters available in ICS

Oracle provides a number of adapters for use with Oracle Integrated Cloud Service. Till ICS version 17.1.3, ICS contains 50 adapters. Below is the full list of available Adapters that can be used to directly integrate your SaaS and on-premises application.
  • Adobe eSign
  • AQ
  • Ariba
  • Concur
  • DB2
  • DocuSign
  • Eloqa
  • Eventbrite
  • Evernote
  • Facebook
  • File
  • FTP
  • Google Calendar
  • Google Mail
  • Google Task
  • JD Edwards EnterpriseOne
  • JMS
  • LinkedIn
  • Logistics
  • MailChimp
  • Microsoft Calendar
  • Microsoft Contact
  • Microsoft Email
  • Microsoft SQLServer
  • MySQL
  • NetSuite
  • Oracle Commerce Cloud
  • Oracle CPQ
  • Oracle Database
  • Oracle E-Business Suite
  • Oracle ERP Cloud
  • Oracle Field Service Cloud
  • Oracle HCM Cloud
  • Oracle Messaging Cloud Service
  • Oracle RightNow
  • Oracle Sales Cloud
  • Oracle Siebel
  • Oracle Utilities
  • Responsys
  • REST
  • Salesforce
  • SAP
  • ServiceNow
  • SOAP
  • SRM Cloud Adapter
  • Successfactors
  • SurveyMonkey
  • Trello
  • Twilio
  • Twitter
For more details about adapters please go through the link

Security capabilities in Integration Cloud Service?

There are several dimensions of security that Integration Cloud Service supports.
  • Physical/Data center security - provided by Oracle Cloud Data Centers.
  • ICS Product Security – ensuring that your ICS environment is secured from external threats and also ensure the security of any customer's data and metadata within the ICS ecosystem.
  • ICS capabilities to securely integrate with Oracle's own SaaS apps on OPC seamlessly.
  • ICS capabilities to securely integrate with any third party Application (generic SOAP/REST API based interface).
  • ICS capabilities to securely integrate with on-premises applications