Ce binding a été créé pour le cas d'une appli Spring-Boot, Spring-security, se lançant dans un Websphere 8.5.5.
Bean de configuration de l'application récupérant les variables JNDI
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
/**
* The Spring configuration for the application.
*/
@Configuration
@PropertySource(
encoding = "UTF-8",
value = "classpath:application.properties"
)
public class ApplicationConfig extends SpringConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationConfig.class.getCanonicalName());
private static final String JAVA_COMP_ENV = "java:comp/env";
private static final String PATH_STORAGE_FOLDER = "path/toto";
private static final String URL_SERVICE_URL = "url/ServiceUrl";
private static final String MY_DATASOURCE_JNDI_NAME = "my.datasource.jndi.name";
/**
* Load the configuration.
*
* @param environment the Spring environment.
*/
public ApplicationConfig(Environment environment) {
super(environment);
}
/**
* My database datasource.
*
* @return the datasource JNDI name.
*/
@Bean
public String myDatasourceJndiName() {
LOGGER.info("Database JNDI name set to {}", super.getProperty(MY_DATASOURCE_JNDI_NAME, String.class));
return super.getProperty(MY_DATASOURCE_JNDI_NAME, String.class);
}
/**
* Return the JNDI value associated a simple string.
*/
@Bean
public String theNameOfMyBean() {
LOGGER.info("Lonading simple string JNDI variable");
String jndiFoundPath = null;
try {
Context envEntryContext = (Context) new InitialContext().lookup(JAVA_COMP_ENV);
String jndiFoundVariable = (String) envEntryContext.lookup(PATH_STORAGE_FOLDER);
LOGGER.info("Binding JNDI {} gave {}", PATH_STORAGE_FOLDER, jndiFoundVariable);
return jndiFoundVariable;
} catch (NamingException e) {
LOGGER.info("Binding JNDI {} gave null (Naming exception).", PATH_STORAGE_FOLDER);
LOGGER.trace("raised error", e);
//Here you can default value or throw exception
}
LOGGER.info("Binding JNDI Bel storage folder path gave {}", jndiFoundPath);
if (jndiFoundPath == null || "".equals(jndiFoundPath)) {
LOGGER.info("Binding JNDI Bel storage folder path gave null.");
//Here you can default value or throw exception
}
return jndiFoundPath;
}
/**
* Return the JNDI value associated a URL.
*/
@Bean
public String servicesUrl() {
LOGGER.info("Lonading service URL JNDI variable");
String jndiFoundPath = null;
try {
Context envEntryContext = (Context) new InitialContext().lookup(JAVA_COMP_ENV);
URL jndiFoundUrl = (URL) envEntryContext.lookup(URL_SERVICE_URL);
LOGGER.info("Binding JNDI service url gave {}", jndiFoundUrl);
jndiFoundPath = jndiFoundUrl.toString();
} catch (NamingException e) {
LOGGER.info("Binding JNDI ws url gave null.");
LOGGER.trace("raised error", e);
//Here you can default value or throw exception
}
if (jndiFoundPath == null || "".equals(jndiFoundPath)) {
LOGGER.info("Binding JNDI Bel storage folder path gave null.");
//Here you can default value or throw exception
}
return jndiFoundPath;
}
}
Sample pour la datasource :
/**
* Load the Data source for the database.
*
* @return the data source.
*/
@Bean
@Primary
public DataSource dataSource() {
LOGGER.info("Load datasource");
try {
DataSource jndiDataSource = new JndiDataSourceLookup().getDataSource(this.getContext().getBean("myDatasourceJndiName", String.class));
if (jndiDataSource == null) {
LOGGER.info("DB - JNDI datasource returned null object - Default datasource");
jndiDataSource = new BoneCPDataSource(this.connectionPoolConfig());
}
LOGGER.info("DB - JNDI datasource is OK.");
return jndiDataSource;
} catch (BeansException | DataSourceLookupFailureException e) {
LOGGER.info("Error when lookup JNDI datasource => Bone-CP DataSource loaded");
return new BoneCPDataSource(this.connectionPoolConfig());
}
}
Le web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="reviewit-poc">
<display-name>TheNameYouWant</display-name>
<resource-ref>
<res-ref-name>url/ServiceUrl</res-ref-name>
<res-type>java.net.URL</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Unshareable</res-sharing-scope>
</resource-ref>
<resource-env-ref>
<description>BEL Storage Folder</description>
<resource-env-ref-name>path/toto</resource-env-ref-name>
<resource-env-ref-type>java.lang.String</resource-env-ref-type>
</resource-env-ref>
<resource-ref>
<res-ref-name>jdbc/myDatasource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Unshareable</res-sharing-scope>
</resource-ref>
</web-app>
Exemple upload côté client :
fichier html
<input type="file" #package (change)="prepareFile(package.files)" class="is-small fileupload"/>
<button type="button" class="button is-small" (click)="importPackage()" [disabled]="!this.validPackage">Valider</button>
fichier ts :
selectedPackage: any;
prepareFile(files: any) {
this.selectedPackage = files;
//exemple pour bloquer l'upload si on a pas affaire à un zip :
if(files != null){
let extension = files[0].name.split('.').pop();
if(extension == "zip" || extension == "ZIP"){
this.validPackage = true;
}else{
this.validPackage= false;
}
}
}
importPackage(): void {
let file: File = this.selectedPackage[0];
this.packageService.uploadFile(file).subscribe(
result => this.onFileUploaded(result)
);
}
onFileUploaded(result: any): void {
this.selectedPackage = null;
}
packageService.ts
uploadFile(file: File): Observable<Entity[]> {
let formData: FormData = new FormData();
formData.append('file', file, file.name);
const url = `${this.getUrl()}/upload`;
return this.http.post(url, formData)
.map(res => this.extractListFromResponse(res))
.catch(res => this.handleError(res))
}
Dans notre cas, le retour de la requete est une liste d'item. A vous de voir de votre côté.
Controller côté java:
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public ResponseEntity uploadFile(@RequestParam("file") MultipartFile file) {
if (!file.isEmpty()) {
try {
return new ResponseEntity<>(this.packageService.uploadPackage(file.getBytes()), HttpStatus.OK);
} catch (GenericBELException | IOException e) {
return super.forwardException("Impossible de récupérer le package " + file.getOriginalFilename(), e);
}
} else {
return this.createStructuredResponse("Impossible de récupérer le package " + file.getOriginalFilename() + ". Il était vide à la réception.", HttpStatus.NO_CONTENT);
}
}
A partir du file, vous pouvez extraire le contenu avec des BufferReader.
Au sein du projet Java, rajouter les classes nécessaires :
Le starter :
@SpringBootApplication
public class SpringBootWebApplication extends SpringBootServletInitializer {
/**
* Configure the server.
*
* @param application the application.
* @return the builder.
*/
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(SpringBootWebApplication.class);
}
/**
* Start the server.
*
* @param args the arguments.
*/
public static void main(String[] args) {
SpringApplication.run(SpringBootWebApplication.class, args);
}
}
La configuration Web :
@Configuration
@EnableWebMvc
public class ApplicationWebConfiguration extends WebMvcConfigurerAdapter {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"};
private static final int CACHE_PERIOD_ONE_WEEK = 604800;
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS)
.setCachePeriod(CACHE_PERIOD_ONE_WEEK);
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addRedirectViewController("/", "/index.html");
}
// ou
//@Override
//public void addViewControllers(ViewControllerRegistry registry) {
// registry.addViewController("/").setViewName("forward:/index.html");
//}
}
Dans le pom, rajouter le format de packaging et le re-build du projet dans les plugins (spring-boot-maven-plugin).
<?xml version="1.0" encoding="UTF-8"?>
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.itametis</groupId>
<artifactId>itartefactId</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<!-- Spring jar version -->
<spring.version>5.0.4.RELEASE</spring.version>
<spring-boot.version>1.5.10.RELEASE</spring-boot.version>
<!-- Jackson version for Spring -->
<jackson.version>2.9.3</jackson.version>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot.version}</version>
<scope>compile</scope>
</dependency>
<!-- Jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<!-- War maker -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<archive>
<manifest>
<mainClass>${project.groupId}.webserver.SpringBootWebApplication</mainClass>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
<!-- Spring boot : re-build the war to carry the tomcat server -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.5.3.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>${project.groupId}.webserver.SpringBootWebApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
Le war généré par le maven-war-plugin sera re-buildé pour embarquer le tomcat et les outils Spring.