How to configure Spring Security + OAuth2 - spring

I'm building a REST Application using Spring Security + OAuth2.
If i use
curl -u clientapp:123456 -X POST http://localhost:8080/oauth/token -H "Accept:application/json" -d "username=admin&password=123456&grant_type=password"
I do not get the response
But if i add the application contextpath i am able to.
curl -u clientapp:123456 -X POST http://localhost:8080/demoproject/oauth/token -H "Accept:application/json" -d "username=admin&password=123456&grant_type=password"
Also getting success response
{"access_token":"dc86814f-94a5-43b7-9e8d-73b143b28c64","token_type":"bearer","re
fresh_token":"09c7e31e-b8e7-4bf2-a839-9e8d4702b822","expires_in":2837,"scope":"r
ead write"}
But when use the access token to request a secured API, I'm getting login page as response because of Spring Security Configuration.
Here is my Configration:
WebMvcInitializer.java
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class WebMvcInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] {
WebConfig.class,
WebSecurityConfiguration.class,
Oauth2ServerConfiguration.AuthConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
WebSecurityConfiguration .java
#Configuration
#EnableWebSecurity
#EnableWebMvcSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("admin").password("123456").roles("USER", "ADMIN");
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
public PasswordEncoder passwordEncoder() {
PasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().hasRole("USER");
//super.configure(http);
}
}
WebConfig.java
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "edu.demo.springoauth")
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("/static/");
}
}
SecurityInitializer.java
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {
}
Oauth2ServerConfiguration.java
#Configuration
public class Oauth2ServerConfiguration {
private static final String SERVER_RESOURCE_ID = "oauthdemo";
private static InMemoryTokenStore tokenStore = new InMemoryTokenStore();
#Configuration
#EnableResourceServer
protected static class ResourceServer extends ResourceServerConfigurerAdapter {
#Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(SERVER_RESOURCE_ID);
}
#Override
#Order(Ordered.HIGHEST_PRECEDENCE)
public void configure(HttpSecurity http) throws Exception {
http.requestMatchers().antMatchers("/oauth/**" , "/noauth/**" , "/api/r/**")
.and()
.authorizeRequests().antMatchers("/api/w/**").hasAuthority("ROLE_USER");
}
}
#Configuration
#EnableAuthorizationServer
protected static class AuthConfig extends AuthorizationServerConfigurerAdapter {
#Autowired
#Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.allowFormAuthenticationForClients();
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient("clientapp").authorizedGrantTypes("password","client_credentials", "authorization_code", "refresh_token", "implicit")
.authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT", "ROLE_USER")
.scopes("read", "write").resourceIds(SERVER_RESOURCE_ID).secret("123456").accessTokenValiditySeconds(3600);
}
#Bean
#Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setSupportRefreshToken(true);
tokenServices.setTokenStore(tokenStore);
return tokenServices;
}
}
}
Pom.xml
<?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>edu.demo</groupId>
<artifactId>springoauth</artifactId>
<name>springoauth</name>
<packaging>war</packaging>
<version>1.0.0-BUILD-SNAPSHOT</version>
<properties>
<build.profile.id>dev</build.profile.id>
<java-version>1.8</java-version>
<spring.security.oauth2.version>2.0.1.RELEASE</spring.security.oauth2.version>
<spring-security.version>3.2.4.RELEASE</spring-security.version>
<spring.version>4.0.5.RELEASE</spring.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring-security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${spring-security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring-security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>${spring.security.oauth2.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-dbcp</artifactId>
<version>7.0.47</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.1.8.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.22</version>
</dependency>
</dependencies>
<profiles>
<profile>
<id>dev</id>
<properties>
<build.profile.id>dev</build.profile.id>
</properties>
</profile>
</profiles>
<build>
<finalName>springoauth</finalName>
<filters>
<filter>profiles/${build.profile.id}/config.properties</filter>
</filters>
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/messages*.properties</exclude>
</excludes>
</resource>
<resource>
<filtering>false</filtering>
<directory>src/main/resources</directory>
<includes>
<include>**/messages*.properties</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<additionalProjectnatures>
<projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
</additionalProjectnatures>
<additionalBuildcommands>
<buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
</additionalBuildcommands>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>${java-version}</source>
<target>${java-version}</target>
<compilerArgument>-Xlint:all</compilerArgument>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>org.test.int1.Main</mainClass>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
Is there something in spring configuration that I'm doing wrong?

Related

spring boot 2 authorization server - all endpoints return 404

I have an application with an authorization server (OAuth2) which I migrated from Spring Boot 1.X to 2.X. Whenever I try to access any of the endpoint functions (e.g. /oauth/token or /oauth/token_key) it results in HTTP-404. The service itself is up which I can see in /actuator/health. It was working without problems with the old Spring Boot.
I already tried to enable all services but without success. I'm using Spring Boot 2, Resilience4J, and OAuth2.
This is my code:
AuthApplication
#SpringBootApplication
#EnableFeignClients
#EnableCircuitBreaker
#EnableAutoConfiguration
public class AuthApplication {
public static void main(String[] args) {
SpringApplication.run(AuthApplication.class, args);
}
}
AuthServerConfig
#Configuration
#EnableAuthorizationServer
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {
#Autowired
#Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
#Autowired
private CustomUserDetailsService userDetailsService;
#Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
#Bean
protected AuthorizationCodeServices authorizationCodeServices() {
return new InMemoryAuthorizationCodeServices();
}
#Bean
public OAuth2AccessDeniedHandler oauthAccessDeniedHandler() {
return new OAuth2AccessDeniedHandler();
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authorizationCodeServices(authorizationCodeServices())
.authenticationManager(this.authenticationManager)
.tokenStore(this.tokenStore())
.userDetailsService(this.userDetailsService)
.approvalStoreDisabled();
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("acme").secret("acme")
.authorizedGrantTypes("authorization_code", "refresh_token", "password")
.scopes("openid", "request", "write", "read");
}
#Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security
.tokenKeyAccess("permitAll()");
}
}
SecurityConfiguration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Autowired
private CustomUserDetailsService userDetailsService;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.anonymous()
.and()
.authorizeRequests()
.anyRequest().permitAll()
.and().logout().permitAll().logoutSuccessUrl("/")
.and().httpBasic().disable().csrf().disable();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(this.passwordEncoder());
}
protected PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
I also added this to the bootstrap.yml in the hope it would help, but it didn't:
management:
endpoints:
web:
exposure:
include: "*"
Why are non of the endpoints of the authorization server available?
EDIT 1
pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.domain</groupId>
<artifactId>auth</artifactId>
<version>0.0.2-SNAPSHOT</version>
<name>auth</name>
<description>Demo project for Spring Boot</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>11</java.version>
<spring-cloud.version>Hoxton.SR6</spring-cloud.version>
<docker.image.prefix>app</docker.image.prefix>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.3.6</version>
<executions>
<execution>
<id>build-image</id>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
<configuration>
<repository>${docker.image.prefix}/${project.artifactId}</repository>
<buildArgs>
<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
</plugins>
</build>
</project>

How to make spring batch to catch exception and continue with work without complete job?

I want to catch an exception in the item processor, do something and continue to work with the job without completing the job. And if it is possible with this to have JdbcPagingItemReader to avoid possible thread issue when reading.
Configuration:
#Configuration
#EnableJpaRepositories
#Slf4j
public class AppConfig {
private final ProcessorVerificationSkipper processorVerificationSkipper;
private final WriterVerificationSkipper writerVerificationSkipper;
private final JobBuilderFactory jobBuilderFactory;
private final StepBuilderFactory stepBuilderFactory;
private final MyProcessor myProcessor;
private final MyWriter myWriter;
private final DataSource dataSource;
public AppConfig (
JobBuilderFactory jobBuilderFactory,
StepBuilderFactory stepBuilderFactory,
MyProcessor myProcessor,
MyWriter myWriter,
DataSource dataSource,
ProcessorVerificationSkipper processorVerificationSkipper,
WriterVerificationSkipper writerVerificationSkipper) {
this.processorVerificationSkipper = processorVerificationSkipper;
this.writerVerificationSkipper = writerVerificationSkipper;
this.jobBuilderFactory = jobBuilderFactory;
this.stepBuilderFactory = stepBuilderFactory;
this.myProcessor = myProcessor;
this.myWriter= myWriter;
this.dataSource = dataSource;
}
/* Without pagination
#Bean
public ItemReader<MyTable> itemReader() {
JdbcCursorItemReader contactJdbcCursorItemReader = new JdbcCursorItemReader<>();
contactJdbcCursorItemReader.setSql("SELECT * FROM MYTABLE");
contactJdbcCursorItemReader.setDataSource(dataSource);
contactJdbcCursorItemReader.setRowMapper(new BeanPropertyRowMapper<>(MyTable.class));
return contactJdbcCursorItemReader;
}*/
// with pagination
#Bean
public JdbcPagingItemReader<MyTable> itemReader() throws Exception {
return new JdbcPagingItemReaderBuilder<Object>()
.dataSource(dataSource)
.saveState(false)
.queryProvider(queryProvider())
.rowMapper(new BeanPropertyRowMapper<>(MyTable.class))
.pageSize(10)
.fetchSize(10)
.build();
}
#Bean
public PagingQueryProvider queryProvider() throws Exception {
SqlPagingQueryProviderFactoryBean provider = new SqlPagingQueryProviderFactoryBean();
provider.setDataSource(dataSource);
provider.setSelectClause("SELECT *");
provider.setFromClause("FROM MYTABLE");
provider.setSortKey("ID");
return (PagingQueryProvider)provider.getObject();
}
#Bean
TaskExecutor taskExecutorStepPush() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(2);
taskExecutor.setMaxPoolSize(20);
taskExecutor.setQueueCapacity(4);
taskExecutor.setAllowCoreThreadTimeOut(true);
taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
return taskExecutor;
}
#Bean
public Step step() throws Exception {
DefaultTransactionAttribute attribute = new DefaultTransactionAttribute();
attribute.setPropagationBehavior(Propagation.REQUIRED.value());
attribute.setIsolationLevel(Isolation.READ_COMMITTED.value());
// return
SimpleStepBuilder<MyTable, MyTable> builder =
(SimpleStepBuilder<MyTable, MyTable>)stepBuilderFactory.get("stepName")
.<MyTable, MyTable >chunk(10)
.reader(itemReader())
.processor(myProcessor)
.faultTolerant()
.skipLimit(Integer.parseInt(env.getProperty(CHUNK_SIZE)))
.skip(Exception.class)
.skipPolicy(processorVerificationSkipper)
.writer(myWriter)
.faultTolerant()
.skip(Exception.class)
.skipPolicy(writerVerificationSkipper)
.noRetry(Exception.class)
.noRollback(Exception.class)
.transactionAttribute(attribute);
return builder.build();
}
ProcessorVerificationSkipper.java
#Component
public class ProcessorVerificationSkipper implements SkipPolicy {
#Override
public boolean shouldSkip(Throwable throwable, int i) throws SkipLimitExceededException {
return true;
}
}
WriterVerificationSkipper.java
#Component
public class WriterVerificationSkipper implements SkipPolicy {
#Override
public boolean shouldSkip(Throwable throwable, int i) throws SkipLimitExceededException {
return true;
}
}
MyTable.java
#Getter
#Setter
#Entity(name = "MYTABLE")
public class MyTable{
#Id
#Column(name = "ID", nullable = false, precision = 0)
private Long sourceId;
#Basic
#Column(name = "A", nullable = true, length = 10)
private String a;
}
application.properties:
spring.batch.job.enabled=false
job.delay.fixed=120000
## Actuator When to show full health details.
management.endpoint.health.show-details=always
spring.main.allow-bean-definition-overriding=true
## Actuator - Endpoint IDs that should be included or '*' for all.
management.endpoints.web.exposure.include=*
management.endpoints.web.exposure.exclude=shutdown,flyway
java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory
spring.datasource.jndi-name=jdbc/MyDS
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.datasource.auto-commit=false
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
MyProcessor.java:
#Slf4j
#Component
public class MyProcessor implements ItemProcessor<MyTable, MyTable> {
#Override
public Object process(MyTable myTable) {
return doSomething(myTable);
}
private Object doSomething(MyTable myTable) {
try {
myTable.setA("a");
// do something
}
catch(Exception1 e) {
myTable.setA("e1");
}
catch(Exception e) {
myTable.setA("e2");
}
return object;
}
}
MyWriter.java
#Component
public class MyWriter implements ItemWriter<MyTable> {
private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;
public DocumentWriter(NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
}
#Override
public void write(List<? extends MyTable> list) {
SqlParameterSource[] batch = SqlParameterSourceUtils.createBatch(list.toArray());
int[] updateCounts = namedParameterJdbcTemplate.batchUpdate("UPDATE MYTABLE SET A = :a, batch);
}
pom.xml
<?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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.myapp</groupId>
<artifactId>my-app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version>
<oracle-ojdbc8.version>12.2.0.1</oracle-ojdbc8.version>
<maven-jaxws-plugin.version>2.5</maven-jaxws-plugin.version>
<maven-jaxb2-plugin.version>2.4</maven-jaxb2-plugin.version>
<jupiter.version>5.5.0</jupiter.version>
<mockito.version>2.23.0</mockito.version>
<maven-surefire-plugin.version>2.22.1</maven-surefire-plugin.version>
<maven-war-plugin.version>3.2.2</maven-war-plugin.version>
<weblogic-wlclient.version>12.1.1</weblogic-wlclient.version>
<lombok.version>1.16.20</lombok.version>
<oracle-ojdbc.version>12.2.0.1</oracle-ojdbc.version>
<appache.http-client.version>4.5.9</appache.http-client.version>
<mockito.version>3.0.0</mockito.version>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.7.28</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>com.oracle.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>12.2.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${appache.http-client.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<profiles>
</profiles>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.3.RELEASE</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
<classpathDependencyExcludes>
<classpathDependencyExcludes>ch.qos.logback:logback-classic</classpathDependencyExcludes>
</classpathDependencyExcludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>${maven-war-plugin.version}</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<archive>
<index>true</index>
<manifest>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
<addClasspath>true</addClasspath>
</manifest>
<manifestEntries>
<Implementation-Version>${project.version}</Implementation-Version>
<Implementation-Vendor-Id>${project.groupId}</Implementation-Vendor-Id>
<Implementation-URL>${project.url}</Implementation-URL>
<Build-Time>${maven.build.timestamp}</Build-Time>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
<configuration>
<additionalProperties>
<version>${project.version}(${build.number})</version>
<Implementation-Version>${project.version}(${build.number})</Implementation-Version>
<BuildNumber>${build.number}</BuildNumber>
<BuildURL>${build.url}</BuildURL>
</additionalProperties>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
With this when an exception occurs job finished as COMPLETED which I don't want. I want to go for all selected records to the end, no matter of exceptions, just to set the value of the property depending on the type of exception.
Is this possible?
How to configure a job?

Spring Boot #Controller not working when deploy on Tomcat standalone

I have an Spring Boot Application + ThymeLeaf, with #RestController and #Controller, everything work fine with tomcat embedded but when I deploy my app with war file to Tomcat 8.5 #Controller class not working #RestController is working fine, when I go to any page with controller use #Controller I have 404 error.
This is my pom.xml:
<?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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.example.boot</groupId>
<artifactId>boot-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>api</artifactId>
<packaging>war</packaging>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>com.example.boot</groupId>
<artifactId>web</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.14</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>[5.0.2,5.1.47)</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-cas</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
<version>${spring-security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<scope>provided</scope>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<skip>false</skip>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<showDeprecation>true</showDeprecation>
<showWarnings>true</showWarnings>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<packagingExcludes>WEB-INF/lib/tomcat-*.jar</packagingExcludes>
<warName>skillinventory</warName>
</configuration>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/classes/resources/</outputDirectory>
<resources>
<resource>
<directory>${project.parent.basedir}/web-si/src/main/web/dist/FrontEnd/</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
This is my Spring Boot app class:
#SpringBootApplication
#EnableScheduling
#PropertySource("classpath:application.properties")
public class Application extends SpringBootServletInitializer {
#Value("${cas.service}")
private String service;
#Value("${cas.loginUrl}")
private String loginUrl;
#Value("${cas.cas30ServiceTicketValidator}")
private String cas30ServiceTicketValidator;
#Value("${cas.createAuthorityList}")
private String createAuthorityList;
#Value("${cas.key}")
private String key;
#Value("${cas.logoutFilterLink}")
private String logoutFilterLink;
#Value("${cas.setFilterProcessesUrl}")
private String setFilterProcessesUrl;
#Value("${cas.setCasServerUrlPrefix}")
private String setCasServerUrlPrefix;
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Bean
public ServiceProperties serviceProperties() {
ServiceProperties serviceProperties = new ServiceProperties();
serviceProperties.setService(service);
serviceProperties.setSendRenew(false);
return serviceProperties;
}
#Bean
#Primary
public AuthenticationEntryPoint authenticationEntryPoint(ServiceProperties sP) {
CasAuthenticationEntryPoint entryPoint = new CasAuthenticationEntryPoint();
entryPoint.setLoginUrl(loginUrl);
entryPoint.setServiceProperties(sP);
return entryPoint;
}
#Bean
public TicketValidator ticketValidator() {
return new Cas30ServiceTicketValidator(cas30ServiceTicketValidator);
}
#Bean
public CasAuthenticationProvider casAuthenticationProvider() {
CasAuthenticationProvider provider = new CasAuthenticationProvider();
provider.setAuthenticationUserDetailsService(customUserDetailsService());
provider.setKey(key);
return provider;
}
#Bean
public AuthenticationUserDetailsService<CasAssertionAuthenticationToken> customUserDetailsService() {
return token -> {
AttributePrincipal principal = token.getAssertion().getPrincipal();
String name = principal.getName();
return new User(name, "pwd", AuthorityUtils.createAuthorityList(createAuthorityList));
};
}
#Bean
public SecurityContextLogoutHandler securityContextLogoutHandler() {
return new SecurityContextLogoutHandler();
}
#Bean
public LogoutFilter logoutFilter() {
LogoutFilter logoutFilter = new LogoutFilter(logoutFilterLink, securityContextLogoutHandler());
logoutFilter.setFilterProcessesUrl(setFilterProcessesUrl);
return logoutFilter;
}
#Bean
public SingleSignOutFilter singleSignOutFilter() {
SingleSignOutFilter singleSignOutFilter = new SingleSignOutFilter();
singleSignOutFilter.setCasServerUrlPrefix(setCasServerUrlPrefix);
singleSignOutFilter.setIgnoreInitConfiguration(true);
return singleSignOutFilter;
}
#EventListener
public SingleSignOutHttpSessionListener singleSignOutHttpSessionListener(HttpSessionEvent event) {
return new SingleSignOutHttpSessionListener();
}
}
My security config:
#EnableWebSecurity
#Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
private AuthenticationProvider authenticationProvider;
private AuthenticationEntryPoint authenticationEntryPoint;
#Autowired
public SpringSecurityConfig(CasAuthenticationProvider
casAuthenticationProvider,
AuthenticationEntryPoint authenticationEntryPoint) {
this.authenticationProvider = casAuthenticationProvider;
this.authenticationEntryPoint = authenticationEntryPoint;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/v1/datas/**")
.permitAll()
.and()
.authorizeRequests()
.regexMatchers("/")
.authenticated()
.and()
.authorizeRequests()
.regexMatchers("/")
.permitAll()
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint);
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws
Exception {
auth.authenticationProvider(authenticationProvider);
}
#Override
protected AuthenticationManager authenticationManager() throws Exception {
return new ProviderManager(Arrays.asList(authenticationProvider));
}
#Bean
public CasAuthenticationFilter casAuthenticationFilter(ServiceProperties serviceProperties) throws Exception {
CasAuthenticationFilter filter = new CasAuthenticationFilter();
filter.setServiceProperties(serviceProperties);
filter.setAuthenticationManager(authenticationManager());
return filter;
}
My controller with #Controller :
#Controller
public class ManagerDataController {
#Value("${theme.root}")
private String themeRoot;
#RequestMapping(value = "/hr/skilldatas", method = RequestMethod.GET)
public String goProgessData(Model model) {
model.addAttribute("themeRoot", themeRoot);
return "data-process";
}
#RequestMapping(value = "/hr/datas", method = RequestMethod.GET)
public String goDataManager(Model model) {
model.addAttribute("themeRoot", themeRoot);
return "datamanager";
}
}
I don't know why it working fine with tomcat embeded but tomcat standalone?
It turn out that because I declare thymeleaf dependency scope is provided, it not Spring false, after I change scope to compile it working now.

Spring 5 MVC - InternalResourceViewResolver and Spring Security

I'm learning Spring, and I've got stuck on some issues i can't resolve. I run it on a GlassFish Server.
I'm implementing a simple WebMvcConfigurer which has an InternalResourceViewResolver, it looks like this:
#Configuration
#EnableWebMvc
public class WebMvcConfig implements WebMvcConfigurer {
#Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setViewClass(JstlView.class);
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
#Bean
public MessageSource messageSource() {
ResourceBundleMessageSource source = new ResourceBundleMessageSource();
source.setBasename("messages");
return source;
}
#Override
public Validator getValidator() {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setValidationMessageSource(messageSource());
return validator;
}
}
and my Controller:
#WebServlet(value = "/")
#Controller
public class HomeController extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("index.jsp").forward(request,response);
}
}
I would assume that when I run the app, it would open the index.jsp file, but it doesn't, instead I get a 404. When I change it to
request.getRequestDispatcher("/WEB-INF/views/index.jsp").forward(request,response);
it opens it.
Also, I've followed the documentation on Spring Security and implemented simple security. From my understanding, every request should be authenticated and it should redirect the user to a login page, but it doesn't.
Here is the code:
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Bean
public UserDetailsService userDetailsService() {
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("user").password("user").roles("USER").build());
manager.createUser(User.withUsername("admin").password("admin").roles("USER", "ADMIN").build());
return manager;
}
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.httpBasic();
}
}
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{ApplicationConfig.class, WebSecurityConfig.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebMvcConfig.class };
}
#Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
// you might want to add stuff to enable spring security
return new Filter[]{characterEncodingFilter};
}
}
#Configuration
public class ApplicationConfig {
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
I'm suspecting that the issues are related, but can't see what I'm missing here. When i change the path in the Controller as mentioned above, I do not get redirected to the login page.
Here is the pom.xml
<?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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.vives</groupId>
<artifactId>spring-mvc-quickstart</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>spring-mvc-quickstart</name>
<properties>
<endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java-version>1.8</java-version>
<!-- Override Spring version -->
<spring.version>5.0.0.RELEASE</spring.version>
<jackson.version>2.9.1</jackson.version>
<thymeleaf-extras-java8time-version>3.0.1.RELEASE</thymeleaf-extras-java8time-version>
<!-- AssertJ is not a part of Spring IO platform, so the version must be provided explicitly -->
<assertj-core-version>3.8.0</assertj-core-version>
</properties>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.1.RELEASE</version>
</dependency>
<!-- Security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>5.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<!-- Avoid issue #72 Could not initialize class org.thymeleaf.templateresolver.ServletContextTemplateResolver due to 'validation is not supported' -->
<exclusions>
<exclusion>
<artifactId>pull-parser</artifactId>
<groupId>pull-parser</groupId>
</exclusion>
</exclusions>
<version>5.2.9.Final</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>spring-release</id>
<name>Spring Release Repository</name>
<url>https://repo.spring.io/release</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<compilerArguments>
<endorseddirs>${endorsed.dir}</endorseddirs>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<outputDirectory>${endorsed.dir}</outputDirectory>
<silent>true</silent>
<artifactItems>
<artifactItem>
<groupId>javax</groupId>
<artifactId>javaee-endorsed-api</artifactId>
<version>7.0</version>
<type>jar</type>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Can someone explain to me what is happening or what I'm doing wrong?
I've finally resolved the issues I had.
As for security, i forgot to add SecurityWebApplicationInitializer and as for navigation, this link helped me.

spring boot build a war file deploy into an external container, error:NoSuchBeanDefinitionException: No qualifying bean of type

Trying to build a war file that is both executable and deployable into an external container and I get this error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.jusfoun.test.service.TestService com.jusfoun.test.controller.TestController.testService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testServiceImpl': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.jusfoun.test.dao.TestMapper] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#javax.annotation.Resource(shareable=true, lookup=, name=, description=, authenticationType=CONTAINER, type=class java.lang.Object, mappedName=)}
It works when started up via java -jar test.war
Project:
pom.xml:
<project>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--Quartz setting -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<!--junit setting -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<!-- datasource heroku -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP-java6</artifactId>
<exclusions>
<exclusion>
<artifactId>tools</artifactId>
<groupId>com.sun</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- aspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
<!-- Spring boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Provided (for embedded war support) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- myBatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.8</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- mybatis pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>3.6.3</version>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
</dependency>
<!-- javax -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.53</version>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<classifier>jdk15</classifier>
<version>2.4</version>
</dependency>
<!-- other service dependency package of jusfoun -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<useSystemClassLoader>true</useSystemClassLoader>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
</plugin>
</plugins>
</build>
<packaging>war</packaging>
</project>
Application.java:
#Configuration
#ComponentScan({"com.jusfoun.test"})
#EnableAutoConfiguration
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(applicationClass, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(applicationClass);
}
private static Class<Application> applicationClass = Application.class;
}
TestController.java
package com.jusfoun.test.controller;
#RestController
#RequestMapping(value = "/test")
public class TestController {
#Autowired
private TestService testService;
/**
* GET /test -> show test
*/
#RequestMapping(value = "/get", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String test() {
System.out.println("teststestestsetstsetest");
return testService.test();
}
}
TestService.java
package com.jusfoun.test.service;
public interface TestService {
String test();
}
TestServiceImpl.java
package com.jusfoun.test.service.impl;
#Service
public class TestServiceImpl implements TestService {
#Resource
private TestMapper testMapper;
#Override
public String test() {
List<Test> tlist = testMapper.selectByExample(null);
JSONArray array = JSONArray.fromObject(tlist);
return array.toString();
}
}
TestMapper.java
package com.jusfoun.test.dao;
#Component
public interface TestMapper {
...
}
TestMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.jusfoun.test.dao.TestMapper" >
...
MapperClassNamePlugin
package com.jusfoun.test.dao.mybatis.plugin;
import java.util.List;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
public class MapperClassNamePlugin extends PluginAdapter {
public boolean validate(List<String> warnings) {
return true;
}
#Override
public void initialized(IntrospectedTable table) {
super.initialized(table);
table.setMyBatis3JavaMapperType(table.getMyBatis3JavaMapperType()
.replaceAll("Mapper$", "Dao"));
}
}
MapperXmlNamePlugin
package com.jusfoun.test.dao.mybatis.plugin;
import java.util.List;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
public class MapperXmlNamePlugin extends PluginAdapter {
public boolean validate(List<String> warnings) {
return true;
}
#Override
public void initialized(IntrospectedTable table) {
super.initialized(table);
table.setMyBatis3JavaMapperType(table.getMyBatis3JavaMapperType()
.replaceAll("Mapper", ""));
}
}
DataBaseConfiguration.java
#Configuration
#EnableTransactionManagement
public class DataBaseConfiguration implements EnvironmentAware {
private RelaxedPropertyResolver propertyResolver;
private static Logger log = LoggerFactory
.getLogger(DataBaseConfiguration.class);
private Environment env;
#Override
public void setEnvironment(Environment env) {
this.env = env;
this.propertyResolver = new RelaxedPropertyResolver(env, "jdbc.");
}
#Bean(destroyMethod = "shutdown")
public DataSource dataSource() {
log.debug("Configruing DataSource");
if (propertyResolver.getProperty("url") == null
&& propertyResolver.getProperty("databaseName") == null) {
log.error("Your database conncetion pool configuration is incorrct ! The application "
+ "cannot start . Please check your jdbc");
Arrays.toString(env.getActiveProfiles());
throw new ApplicationContextException(
"DataBase connection pool is not configured correctly");
}
HikariConfig config = new HikariConfig();
config.setDataSourceClassName(propertyResolver
.getProperty("dataSourceClassName"));
if (propertyResolver.getProperty("url") == null
|| "".equals(propertyResolver.getProperty("url"))) {
config.addDataSourceProperty("databaseName",
propertyResolver.getProperty("databaseName"));
config.addDataSourceProperty("serverName",
propertyResolver.getProperty("serverName"));
} else {
config.addDataSourceProperty("url",
propertyResolver.getProperty("url"));
}
config.setUsername(propertyResolver.getProperty("username"));
config.setPassword(propertyResolver.getProperty("password"));
if ("com.mysql.jdbc.jdbc2.optional.MysqlDataSource"
.equals(propertyResolver.getProperty("dataSourceName"))) {
config.addDataSourceProperty("cachePrepStmts",
propertyResolver.getProperty("cachePrepStmts"));
config.addDataSourceProperty("prepStmtCacheSize",
propertyResolver.getProperty("prepStmtsCacheSize"));
config.addDataSourceProperty("prepStmtCacheSqlLimit",
propertyResolver.getProperty("prepStmtCacheSqlLimit"));
config.addDataSourceProperty("userServerPrepStmts",
propertyResolver.getProperty("userServerPrepStmts"));
}
return new HikariDataSource(config);
}
}
MybatisConfiguration.java
#Configuration
#ConditionalOnClass({ EnableTransactionManagement.class, EntityManager.class })
#AutoConfigureAfter({ DataBaseConfiguration.class })
#MapperScan(basePackages={"com.jusfoun.test.dao"})
public class MybatisConfiguration implements EnvironmentAware {
private static Log logger = LogFactory.getLog(MybatisConfiguration.class);
private RelaxedPropertyResolver propertyResolver;
#Inject
private DataSource dataSource;
#Override
public void setEnvironment(Environment environment) {
this.propertyResolver = new RelaxedPropertyResolver(environment,"mybatis.");
}
#Bean
#ConditionalOnMissingBean
public SqlSessionFactory sqlSessionFactory() {
try {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setTypeAliasesPackage(propertyResolver
.getProperty("typeAliasesPackage"));
sessionFactory
.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources(propertyResolver
.getProperty("mapperLocations")));
sessionFactory
.setConfigLocation(new DefaultResourceLoader()
.getResource(propertyResolver
.getProperty("configLocation")));
return sessionFactory.getObject();
} catch (Exception e) {
logger.warn("Could not confiure mybatis session factory");
return null;
}
}
#Bean
#ConditionalOnMissingBean
public DataSourceTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource);
}
}
Using mybatis-spring-boot-starter (https://github.com/mybatis/spring-boot-starter), your setup can be simplified to the following:
Remove DataBaseConfiguration and MybatisConfiguration (which will be done by mybatis-spring-boot-starter.
Modifiy TestMapper:
package com.jusfoun.test.dao;
#Mapper
public interface TestMapper {
...
}
I remove annotation of #ConditionalOnClass in MybatisConfiguration.
The project works when war deploy into an external container(tomcat8).
Before remove the annotation, it works with java -jar xxx.war but not works deploy into external tomcat.
#Configuration
#AutoConfigureAfter({ DataBaseConfiguration.class })
#MapperScan(basePackages={"com.jusfoun.test.dao"})
public class MybatisConfiguration implements EnvironmentAware {

Resources