Merge remote-tracking branch 'origin/master'

This commit is contained in:
Alex Theedom 2016-08-08 20:42:59 +01:00
commit 8251c25b6a
54 changed files with 2444 additions and 47 deletions

View File

@ -0,0 +1,22 @@
package com.baeldung.threadpool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
import java.util.stream.Collectors;
public class CountingTask extends RecursiveTask<Integer> {
private final TreeNode node;
public CountingTask(TreeNode node) {
this.node = node;
}
@Override
protected Integer compute() {
return node.value + node.children.stream()
.map(childNode -> new CountingTask(childNode).fork())
.collect(Collectors.summingInt(ForkJoinTask::join));
}
}

View File

@ -0,0 +1,29 @@
package com.baeldung.threadpool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import com.google.common.util.concurrent.MoreExecutors;
/**
* This class demonstrates the usage of Guava's exiting executor services that keep the VM from hanging.
* Without the exiting executor service, the task would hang indefinitely.
* This behaviour cannot be demonstrated in JUnit tests, as JUnit kills the VM after the tests.
*/
public class ExitingExecutorServiceExample {
public static void main(String... args) {
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);
ExecutorService executorService = MoreExecutors.getExitingExecutorService(executor, 100, TimeUnit.MILLISECONDS);
executorService.submit(() -> {
while (true) {
}
});
}
}

View File

@ -0,0 +1,19 @@
package com.baeldung.threadpool;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class TreeNode {
int value;
Set<TreeNode> children;
public TreeNode(int value, TreeNode... children) {
this.value = value;
this.children = new HashSet<>();
this.children.addAll(Arrays.asList(children));
}
}

View File

@ -0,0 +1,146 @@
package com.baeldung.threadpool;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class CoreThreadPoolTest {
@Test(timeout = 1000)
public void whenCallingExecuteWithRunnable_thenRunnableIsExecuted() throws InterruptedException {
CountDownLatch lock = new CountDownLatch(1);
Executor executor = Executors.newSingleThreadExecutor();
executor.execute(() -> {
System.out.println("Hello World");
lock.countDown();
});
lock.await(1000, TimeUnit.MILLISECONDS);
}
@Test
public void whenUsingExecutorServiceAndFuture_thenCanWaitOnFutureResult() throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newFixedThreadPool(10);
Future<String> future = executorService.submit(() -> "Hello World");
String result = future.get();
assertEquals("Hello World", result);
}
@Test
public void whenUsingFixedThreadPool_thenCoreAndMaximumThreadSizeAreTheSame() {
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);
executor.submit(() -> {
Thread.sleep(1000);
return null;
});
executor.submit(() -> {
Thread.sleep(1000);
return null;
});
executor.submit(() -> {
Thread.sleep(1000);
return null;
});
assertEquals(2, executor.getPoolSize());
assertEquals(1, executor.getQueue().size());
}
@Test
public void whenUsingCachedThreadPool_thenPoolSizeGrowsUnbounded() {
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
executor.submit(() -> {
Thread.sleep(1000);
return null;
});
executor.submit(() -> {
Thread.sleep(1000);
return null;
});
executor.submit(() -> {
Thread.sleep(1000);
return null;
});
assertEquals(3, executor.getPoolSize());
assertEquals(0, executor.getQueue().size());
}
@Test(timeout = 1000)
public void whenUsingSingleThreadPool_thenTasksExecuteSequentially() throws InterruptedException {
CountDownLatch lock = new CountDownLatch(2);
AtomicInteger counter = new AtomicInteger();
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {
counter.set(1);
lock.countDown();
});
executor.submit(() -> {
counter.compareAndSet(1, 2);
lock.countDown();
});
lock.await(1000, TimeUnit.MILLISECONDS);
assertEquals(2, counter.get());
}
@Test(timeout = 1000)
public void whenSchedulingTask_thenTaskExecutesWithinGivenPeriod() throws InterruptedException {
CountDownLatch lock = new CountDownLatch(1);
ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);
executor.schedule(() -> {
System.out.println("Hello World");
lock.countDown();
}, 500, TimeUnit.MILLISECONDS);
lock.await(1000, TimeUnit.MILLISECONDS);
}
@Test(timeout = 1000)
public void whenSchedulingTaskWithFixedPeriod_thenTaskExecutesMultipleTimes() throws InterruptedException {
CountDownLatch lock = new CountDownLatch(3);
ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);
ScheduledFuture<?> future = executor.scheduleAtFixedRate(() -> {
System.out.println("Hello World");
lock.countDown();
}, 500, 100, TimeUnit.MILLISECONDS);
lock.await();
future.cancel(true);
}
@Test
public void whenUsingForkJoinPool_thenSumOfTreeElementsIsCalculatedCorrectly() {
TreeNode tree = new TreeNode(5,
new TreeNode(3), new TreeNode(2,
new TreeNode(2), new TreeNode(8)));
ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
int sum = forkJoinPool.invoke(new CountingTask(tree));
assertEquals(20, sum);
}
}

View File

@ -0,0 +1,56 @@
package com.baeldung.threadpool;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class GuavaThreadPoolTest {
@Test
public void whenExecutingTaskWithDirectExecutor_thenTheTaskIsExecutedInTheCurrentThread() {
Executor executor = MoreExecutors.directExecutor();
AtomicBoolean executed = new AtomicBoolean();
executor.execute(() -> {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
executed.set(true);
});
assertTrue(executed.get());
}
@Test
public void whenJoiningFuturesWithAllAsList_thenCombinedFutureCompletesAfterAllFuturesComplete() throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newCachedThreadPool();
ListeningExecutorService listeningExecutorService = MoreExecutors.listeningDecorator(executorService);
ListenableFuture<String> future1 = listeningExecutorService.submit(() -> "Hello");
ListenableFuture<String> future2 = listeningExecutorService.submit(() -> "World");
String greeting = Futures.allAsList(future1, future2).get()
.stream()
.collect(Collectors.joining(" "));
assertEquals("Hello World", greeting);
}
}

View File

@ -6,9 +6,15 @@
<groupId>com.baeldung</groupId>
<artifactId>hystrix</artifactId>
<version>1.0</version>
<name>hystrix</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.RELEASE</version>
<relativePath></relativePath>
</parent>
<properties>
<!-- General -->
@ -32,12 +38,35 @@
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-core</artifactId>
<version>${hystrix-core.version}</version>
</dependency>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-metrics-event-stream</artifactId>
<version>1.3.16</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.netflix.hystrix/hystrix-dashboard -->
<!--<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-dashboard</artifactId>
<version>1.4.3</version>
</dependency>-->
<dependency>
<groupId>com.netflix.rxjava</groupId>
<artifactId>rxjava-core</artifactId>
@ -62,6 +91,10 @@
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>

View File

@ -0,0 +1,20 @@
package com.baeldung.hystrix;
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class AppConfig {
public static void main(String[] args) {
SpringApplication.run(AppConfig.class, args);
}
@Bean
public ServletRegistrationBean adminServletRegistrationBean() {
return new ServletRegistrationBean(new HystrixMetricsStreamServlet(), "/hystrix.stream");
}
}

View File

@ -0,0 +1,81 @@
package com.baeldung.hystrix;
import com.netflix.hystrix.*;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
@Aspect
public class HystrixAspect {
private HystrixCommand.Setter config;
private HystrixCommandProperties.Setter commandProperties;
private HystrixThreadPoolProperties.Setter threadPoolProperties;
@Around("@annotation(com.baeldung.hystrix.HystrixCircuitBreaker)")
public Object circuitBreakerAround(final ProceedingJoinPoint aJoinPoint) {
return new RemoteServiceCommand(config, aJoinPoint).execute();
}
@PostConstruct
private void setup() {
this.config = HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupKey));
this.config = config.andCommandKey(HystrixCommandKey.Factory.asKey(key));
this.commandProperties = HystrixCommandProperties.Setter();
this.commandProperties.withExecutionTimeoutInMilliseconds(executionTimeout);
this.commandProperties.withCircuitBreakerSleepWindowInMilliseconds(sleepWindow);
this.threadPoolProperties= HystrixThreadPoolProperties.Setter();
this.threadPoolProperties.withMaxQueueSize(maxThreadCount).withCoreSize(coreThreadCount).withMaxQueueSize(queueCount);
this.config.andCommandPropertiesDefaults(commandProperties);
this.config.andThreadPoolPropertiesDefaults(threadPoolProperties);
}
private static class RemoteServiceCommand extends HystrixCommand<String> {
private final ProceedingJoinPoint joinPoint;
RemoteServiceCommand(final Setter config, final ProceedingJoinPoint joinPoint) {
super(config);
this.joinPoint = joinPoint;
}
@Override
protected String run() throws Exception {
try {
return (String) joinPoint.proceed();
} catch (final Throwable th) {
throw new Exception(th);
}
}
}
@Value("${remoteservice.command.execution.timeout}")
private int executionTimeout;
@Value("${remoteservice.command.sleepwindow}")
private int sleepWindow;
@Value("${remoteservice.command.threadpool.maxsize}")
private int maxThreadCount;
@Value("${remoteservice.command.threadpool.coresize}")
private int coreThreadCount;
@Value("${remoteservice.command.task.queue.size}")
private int queueCount;
@Value("${remoteservice.command.group.key}")
private String groupKey;
@Value("${remoteservice.command.key}")
private String key;
}

View File

@ -0,0 +1,11 @@
package com.baeldung.hystrix;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface HystrixCircuitBreaker {
}

View File

@ -0,0 +1,17 @@
package com.baeldung.hystrix;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HystrixController {
@Autowired
private SpringExistingClient client;
@RequestMapping("/")
public String index() throws InterruptedException{
return client.invokeRemoteService();
}
}

View File

@ -1,15 +0,0 @@
package com.baeldung.hystrix;
public class RemoteServiceSimulator {
public String checkSomething(final long timeout) throws InterruptedException {
System.out.print(String.format("Waiting %sms. ", timeout));
// to simulate a real world delay in processing.
Thread.sleep(timeout);
return "Done waiting.";
}
}

View File

@ -1,7 +1,7 @@
package com.baeldung.hystrix;
class RemoteServiceTestSimulator {
public class RemoteServiceTestSimulator {
private long wait;

View File

@ -0,0 +1,17 @@
package com.baeldung.hystrix;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component("springClient")
public class SpringExistingClient {
@Value("${remoteservice.timeout}")
private int remoteServiceDelay;
@HystrixCircuitBreaker
public String invokeRemoteService() throws InterruptedException{
return new RemoteServiceTestSimulator(remoteServiceDelay).execute();
}
}

View File

@ -0,0 +1,8 @@
remoteservice.command.group.key=RemoteServiceGroup
remoteservice.command.key=RemoteServiceKey
remoteservice.command.execution.timeout=10000
remoteservice.command.threadpool.coresize=5
remoteservice.command.threadpool.maxsize=10
remoteservice.command.task.queue.size=5
remoteservice.command.sleepwindow=5000
remoteservice.timeout=5000

View File

@ -9,13 +9,15 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.util.concurrent.ExecutionException;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
public class HystrixTimeoutTest {
private static HystrixCommand.Setter config;
private static HystrixCommandProperties.Setter commandProperties = HystrixCommandProperties.Setter();
private HystrixCommand.Setter config;
private HystrixCommandProperties.Setter commandProperties ;
@Rule
@ -23,6 +25,7 @@ public class HystrixTimeoutTest {
@Before
public void setup() {
commandProperties = HystrixCommandProperties.Setter();
config = HystrixCommand
.Setter
.withGroupKey(HystrixCommandGroupKey.Factory.asKey("RemoteServiceGroup1"));
@ -34,29 +37,86 @@ public class HystrixTimeoutTest {
}
@Test
public void givenTimeoutEqualTo100_andDefaultSettings_thenReturnSuccess() throws InterruptedException {
public void givenServiceTimeoutEqualTo100_andDefaultSettings_thenReturnSuccess() throws InterruptedException {
assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(100)).execute(), equalTo("Success"));
}
@Test
public void givenTimeoutEqualTo10000_andDefaultSettings_thenExpectHystrixRuntimeException() throws InterruptedException {
public void givenServiceTimeoutEqualTo10000_andDefaultSettings_thenExpectHRE() throws InterruptedException {
exception.expect(HystrixRuntimeException.class);
new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(10_000)).execute();
}
@Test
public void givenTimeoutEqualTo5000_andExecutionTimeoutEqualTo10000_thenReturnSuccess() throws InterruptedException {
public void givenServiceTimeoutEqualTo5000_andExecutionTimeoutEqualTo10000_thenReturnSuccess()
throws InterruptedException {
commandProperties.withExecutionTimeoutInMilliseconds(10_000);
config.andCommandPropertiesDefaults(commandProperties);
assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(5_000)).execute(), equalTo("Success"));
assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(500)).execute(),
equalTo("Success"));
}
@Test
public void givenTimeoutEqualTo15000_andExecutionTimeoutEqualTo10000_thenExpectHystrixRuntimeException() throws InterruptedException {
public void givenServiceTimeoutEqualTo15000_andExecutionTimeoutEqualTo5000_thenExpectHRE()
throws InterruptedException {
exception.expect(HystrixRuntimeException.class);
commandProperties.withExecutionTimeoutInMilliseconds(10_000);
commandProperties.withExecutionTimeoutInMilliseconds(5_000);
config.andCommandPropertiesDefaults(commandProperties);
new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(15_000)).execute();
}
@Test
public void givenServiceTimeoutEqual_andExecutionTimeout_andThreadPool_thenReturnSuccess()
throws InterruptedException {
commandProperties.withExecutionTimeoutInMilliseconds(10_000);
config.andCommandPropertiesDefaults(commandProperties);
config.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter()
.withMaxQueueSize(10)
.withCoreSize(3)
.withQueueSizeRejectionThreshold(10));
assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(500)).execute(),
equalTo("Success"));
}
@Test
public void givenCircuitBreakerSetup_thenReturnSuccess() throws InterruptedException {
commandProperties.withExecutionTimeoutInMilliseconds(1000);
commandProperties.withCircuitBreakerSleepWindowInMilliseconds(4000);
commandProperties.withExecutionIsolationStrategy(
HystrixCommandProperties.ExecutionIsolationStrategy.THREAD);
commandProperties.withCircuitBreakerEnabled(true);
commandProperties.withCircuitBreakerRequestVolumeThreshold(1);
config.andCommandPropertiesDefaults(commandProperties);
config.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter()
.withMaxQueueSize(1)
.withCoreSize(1)
.withQueueSizeRejectionThreshold(1));
assertThat(this.invokeRemoteService(10000), equalTo(null));
assertThat(this.invokeRemoteService(10000), equalTo(null));
Thread.sleep(5000);
assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(500)).execute(),
equalTo("Success"));
assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(500)).execute(),
equalTo("Success"));
assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(500)).execute(),
equalTo("Success"));
}
public String invokeRemoteService(long timeout) throws InterruptedException{
String response = null;
try{
response = new RemoteServiceTestCommand(config,
new RemoteServiceTestSimulator(timeout)).execute();
}catch(HystrixRuntimeException ex){
System.out.println("ex = " + ex);
}
return response;
}
}

View File

@ -29,6 +29,11 @@
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
@ -50,6 +55,11 @@
<artifactId>spring-data-jpa</artifactId>
<version>${spring-data-jpa.version}</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
<!-- validation -->
@ -186,6 +196,7 @@
<hibernate.version>4.3.11.Final</hibernate.version>
<mysql-connector-java.version>5.1.38</mysql-connector-java.version>
<spring-data-jpa.version>1.8.2.RELEASE</spring-data-jpa.version>
<h2.version>1.4.192</h2.version>
<!-- logging -->
<org.slf4j.version>1.7.13</org.slf4j.version>

View File

@ -78,6 +78,8 @@ public class PersistenceJPAConfig {
final Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", env.getProperty("hibernate.cache.use_second_level_cache"));
hibernateProperties.setProperty("hibernate.cache.use_query_cache", env.getProperty("hibernate.cache.use_query_cache"));
// hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true");
return hibernateProperties;
}

View File

@ -0,0 +1,84 @@
package org.baeldung.config;
import com.google.common.base.Preconditions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration
@EnableTransactionManagement
@PropertySource({ "classpath:persistence-h2.properties" })
@ComponentScan({ "org.baeldung.persistence" })
@EnableJpaRepositories(basePackages = "org.baeldung.persistence.dao")
public class PersistenceJPAConfigL2Cache {
@Autowired
private Environment env;
public PersistenceJPAConfigL2Cache() {
super();
}
// beans
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] { "org.baeldung.persistence.model" });
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
return em;
}
@Bean
public DataSource dataSource() {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName")));
dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url")));
dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user")));
return dataSource;
}
@Bean
public PlatformTransactionManager transactionManager(final EntityManagerFactory emf) {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
final Properties additionalProperties() {
final Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", env.getProperty("hibernate.cache.use_second_level_cache"));
hibernateProperties.setProperty("hibernate.cache.use_query_cache", env.getProperty("hibernate.cache.use_query_cache"));
hibernateProperties.setProperty("hibernate.cache.region.factory_class", env.getProperty("hibernate.cache.region.factory_class"));
return hibernateProperties;
}
}

View File

@ -1,17 +1,13 @@
package org.baeldung.persistence.model;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
@Entity
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Foo implements Serializable {
private static final long serialVersionUID = 1L;

View File

@ -21,6 +21,8 @@
<props>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop>
<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
</props>
</property>
</bean>

View File

@ -0,0 +1,13 @@
# jdbc.X
jdbc.driverClassName=org.h2.Driver
jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
jdbc.user=sa
# jdbc.pass=
# hibernate.X
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.show_sql=false
hibernate.hbm2ddl.auto=create-drop
hibernate.cache.use_second_level_cache=true
hibernate.cache.use_query_cache=true
hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory

View File

@ -9,3 +9,5 @@ jdbc.pass=tutorialmy5ql
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.show_sql=false
hibernate.hbm2ddl.auto=create-drop
hibernate.cache.use_second_level_cache=false
hibernate.cache.use_query_cache=false

View File

@ -8,3 +8,5 @@ jdbc.pass=tutorialmy5ql
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.show_sql=false
hibernate.hbm2ddl.auto=create-drop
hibernate.cache.use_second_level_cache=false
hibernate.cache.use_query_cache=false

View File

@ -1,16 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="punit" >
<class>org.baeldung.persistence.model.Foo</class>
<class>org.baeldung.persistence.model.Bar</class>
<properties>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/HIBERTEST"/>
<property name="javax.persistence.ddl-generation" value="drop-and-create-tables"/>
<property name="javax.persistence.logging.level" value="INFO"/>
<property name = "hibernate.show_sql" value = "true" />
</properties>
</persistence-unit>
<persistence-unit name="punit" >
<class>org.baeldung.persistence.model.Foo</class>
<class>org.baeldung.persistence.model.Bar</class>
<properties>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/HIBERTEST"/>
<property name="javax.persistence.ddl-generation" value="drop-and-create-tables"/>
<property name="javax.persistence.logging.level" value="INFO"/>
<property name = "hibernate.show_sql" value = "true" />
<property name = "hibernate.cache.use_second_level_cache" value = "false" />
<property name = "hibernate.cache.use_query_cache" value = "false" />
</properties>
</persistence-unit>
</persistence>

View File

@ -0,0 +1,84 @@
package org.baeldung.persistence.service;
import net.sf.ehcache.CacheManager;
import org.baeldung.config.PersistenceJPAConfigL2Cache;
import org.baeldung.persistence.model.Bar;
import org.baeldung.persistence.model.Foo;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
import static org.hamcrest.Matchers.greaterThan;
import static org.junit.Assert.assertThat;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { PersistenceJPAConfigL2Cache.class }, loader = AnnotationConfigContextLoader.class)
public class SecondLevelCacheIntegrationTest {
@PersistenceContext
private EntityManager entityManager;
@Autowired
private FooService fooService;
@Autowired
private PlatformTransactionManager platformTransactionManager;
@Before
public final void before() {
entityManager.getEntityManagerFactory().getCache().evictAll();
}
@Test
public final void givenEntityIsLoaded_thenItIsCached() {
final Foo foo = new Foo(randomAlphabetic(6));
fooService.create(foo);
fooService.findOne(foo.getId());
final int size = CacheManager.ALL_CACHE_MANAGERS.get(0)
.getCache("org.baeldung.persistence.model.Foo").getSize();
assertThat(size, greaterThan(0));
}
@Test
public final void givenBarIsUpdatedInNativeQuery_thenFoosAreNotEvicted() {
final Foo foo = new Foo(randomAlphabetic(6));
fooService.create(foo);
fooService.findOne(foo.getId());
new TransactionTemplate(platformTransactionManager).execute(status -> {
final Bar bar = new Bar(randomAlphabetic(6));
entityManager.persist(bar);
final Query nativeQuery = entityManager.createNativeQuery("update BAR set NAME = :updatedName where ID = :id");
nativeQuery.setParameter("updatedName", "newName");
nativeQuery.setParameter("id", bar.getId());
nativeQuery.unwrap(org.hibernate.SQLQuery.class).addSynchronizedEntityClass(Bar.class);
return nativeQuery.executeUpdate();
});
final int size = CacheManager.ALL_CACHE_MANAGERS.get(0)
.getCache("org.baeldung.persistence.model.Foo").getSize();
assertThat(size, greaterThan(0));
}
@Test
public final void givenCacheableQueryIsExecuted_thenItIsCached() {
new TransactionTemplate(platformTransactionManager).execute(status -> {
return entityManager.createQuery("select f from Foo f")
.setHint("org.hibernate.cacheable", true)
.getResultList();
});
final int size = CacheManager.ALL_CACHE_MANAGERS.get(0)
.getCache("org.hibernate.cache.internal.StandardQueryCache").getSize();
assertThat(size, greaterThan(0));
}
}

View File

@ -0,0 +1,53 @@
package org.baeldung.config;
import java.text.SimpleDateFormat;
import java.util.List;
import org.baeldung.config.converter.KryoHttpMessageConverter;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter;
import org.springframework.http.converter.xml.MarshallingHttpMessageConverter;
import org.springframework.oxm.xstream.XStreamMarshaller;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
@EnableWebMvc
@ComponentScan({ "org.baeldung.web" })
public class WebConfig extends WebMvcConfigurerAdapter {
public WebConfig() {
super();
}
//
@Override
public void configureMessageConverters(final List<HttpMessageConverter<?>> messageConverters) {
messageConverters.add(createXmlHttpMessageConverter());
// messageConverters.add(new MappingJackson2HttpMessageConverter());
final Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.indentOutput(true).dateFormat(new SimpleDateFormat("dd-MM-yyyy hh:mm"));
messageConverters.add(new MappingJackson2HttpMessageConverter(builder.build()));
// messageConverters.add(new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build()));
messageConverters.add(new ProtobufHttpMessageConverter());
messageConverters.add(new KryoHttpMessageConverter());
super.configureMessageConverters(messageConverters);
}
private HttpMessageConverter<Object> createXmlHttpMessageConverter() {
final MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter();
final XStreamMarshaller xstreamMarshaller = new XStreamMarshaller();
xmlConverter.setMarshaller(xstreamMarshaller);
xmlConverter.setUnmarshaller(xstreamMarshaller);
return xmlConverter;
}
}

View File

@ -0,0 +1,57 @@
package org.baeldung.config.converter;
import java.io.IOException;
import org.baeldung.web.dto.Foo;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
/**
* An {@code HttpMessageConverter} that can read and write Kryo messages.
*/
public class KryoHttpMessageConverter extends AbstractHttpMessageConverter<Object> {
public static final MediaType KRYO = new MediaType("application", "x-kryo");
private static final ThreadLocal<Kryo> kryoThreadLocal = new ThreadLocal<Kryo>() {
@Override
protected Kryo initialValue() {
final Kryo kryo = new Kryo();
kryo.register(Foo.class, 1);
return kryo;
}
};
public KryoHttpMessageConverter() {
super(KRYO);
}
@Override
protected boolean supports(final Class<?> clazz) {
return Object.class.isAssignableFrom(clazz);
}
@Override
protected Object readInternal(final Class<? extends Object> clazz, final HttpInputMessage inputMessage) throws IOException {
final Input input = new Input(inputMessage.getBody());
return kryoThreadLocal.get().readClassAndObject(input);
}
@Override
protected void writeInternal(final Object object, final HttpOutputMessage outputMessage) throws IOException {
final Output output = new Output(outputMessage.getBody());
kryoThreadLocal.get().writeClassAndObject(output, object);
output.flush();
}
@Override
protected MediaType getDefaultContentType(final Object object) {
return KRYO;
}
}

View File

@ -0,0 +1,47 @@
package org.baeldung.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping(value = "/ex")
public class BarMappingExamplesController {
public BarMappingExamplesController() {
super();
}
// API
// with @RequestParam
@RequestMapping(value = "/bars")
@ResponseBody
public String getBarBySimplePathWithRequestParam(@RequestParam("id") final long id) {
return "Get a specific Bar with id=" + id;
}
@RequestMapping(value = "/bars", params = "id")
@ResponseBody
public String getBarBySimplePathWithExplicitRequestParam(@RequestParam("id") final long id) {
return "Get a specific Bar with id=" + id;
}
@RequestMapping(value = "/bars", params = { "id", "second" })
@ResponseBody
public String getBarBySimplePathWithExplicitRequestParams(@RequestParam("id") final long id) {
return "Get a specific Bar with id=" + id;
}
// with @PathVariable
@RequestMapping(value = "/bars/{numericId:[\\d]+}")
@ResponseBody
public String getBarsBySimplePathWithPathVariable(@PathVariable final long numericId) {
return "Get a specific Bar with id=" + numericId;
}
}

View File

@ -0,0 +1,16 @@
package org.baeldung.web.controller;
import org.baeldung.web.dto.Company;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class CompanyController {
@RequestMapping(value = "/companyRest", produces = MediaType.APPLICATION_JSON_VALUE)
public Company getCompanyRest() {
final Company company = new Company(1, "Xpto");
return company;
}
}

View File

@ -0,0 +1,47 @@
package org.baeldung.web.controller;
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
import static org.apache.commons.lang3.RandomStringUtils.randomNumeric;
import org.baeldung.web.dto.Foo;
import org.baeldung.web.dto.FooProtos;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
@Controller
public class FooController {
public FooController() {
super();
}
// API - read
@RequestMapping(method = RequestMethod.GET, value = "/foos/{id}")
@ResponseBody
public Foo findById(@PathVariable final long id) {
return new Foo(Long.parseLong(randomNumeric(2)), randomAlphabetic(4));
}
// API - write
@RequestMapping(method = RequestMethod.PUT, value = "/foos/{id}")
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public Foo updateFoo(@PathVariable("id") final String id, @RequestBody final Foo foo) {
System.out.println(foo);
return foo;
}
@RequestMapping(method = RequestMethod.GET, value = "/foos/{id}", produces = { "application/x-protobuf" })
@ResponseBody
public FooProtos.Foo findProtoById(@PathVariable final long id) {
return FooProtos.Foo.newBuilder().setId(1).setName("Foo Name").build();
}
}

View File

@ -0,0 +1,101 @@
package org.baeldung.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping(value = "/ex")
public class FooMappingExamplesController {
public FooMappingExamplesController() {
super();
}
// API
// mapping examples
@RequestMapping(value = "/foos")
@ResponseBody
public String getFoosBySimplePath() {
return "Simple Get some Foos";
}
// with @PathVariable
@RequestMapping(value = "/foos/{id}")
@ResponseBody
public String getFoosBySimplePathWithPathVariable(@PathVariable final long id) {
return "Get a specific Foo with id=" + id;
}
@RequestMapping(value = "/foos/{fooid}/bar/{barid}")
@ResponseBody
public String getFoosBySimplePathWithPathVariables(@PathVariable final long fooid, @PathVariable final long barid) {
return "Get a specific Bar with id=" + barid + " from a Foo with id=" + fooid;
}
// other HTTP verbs
@RequestMapping(value = "/foos", method = RequestMethod.POST)
@ResponseBody
public String postFoos() {
return "Post some Foos";
}
// with headers
@RequestMapping(value = "/foos", headers = "key=val")
@ResponseBody
public String getFoosWithHeader() {
return "Get some Foos with Header";
}
@RequestMapping(value = "/foos", headers = { "key1=val1", "key2=val2" })
@ResponseBody
public String getFoosWithHeaders() {
return "Get some Foos with Header";
}
// @RequestMapping(value = "/foos", method = RequestMethod.GET, headers = "Accept=application/json")
// @ResponseBody
// public String getFoosAsJsonFromBrowser() {
// return "Get some Foos with Header Old";
// }
@RequestMapping(value = "/foos", produces = { "application/json", "application/xml" })
@ResponseBody
public String getFoosAsJsonFromREST() {
return "Get some Foos with Header New";
}
// advanced - multiple mappings
@RequestMapping(value = { "/advanced/bars", "/advanced/foos" })
@ResponseBody
public String getFoosOrBarsByPath() {
return "Advanced - Get some Foos or Bars";
}
@RequestMapping(value = "*")
@ResponseBody
public String getFallback() {
return "Fallback for GET Requests";
}
@RequestMapping(value = "*", method = { RequestMethod.GET, RequestMethod.POST })
@ResponseBody
public String allFallback() {
return "Fallback for All Requests";
}
@RequestMapping(value = "/foos/multiple", method = { RequestMethod.PUT, RequestMethod.POST })
@ResponseBody
public String putAndPostFoos() {
return "Advanced - PUT and POST within single method";
}
}

View File

@ -0,0 +1,33 @@
package org.baeldung.web.controller;
import java.util.Date;
import org.baeldung.web.dto.Item;
import org.baeldung.web.dto.ItemManager;
import org.baeldung.web.dto.Views;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.annotation.JsonView;
@RestController
public class ItemController {
@JsonView(Views.Public.class)
@RequestMapping("/items/{id}")
public Item getItemPublic(@PathVariable final int id) {
return ItemManager.getById(id);
}
@JsonView(Views.Internal.class)
@RequestMapping("/items/internal/{id}")
public Item getItemInternal(@PathVariable final int id) {
return ItemManager.getById(id);
}
@RequestMapping("/date")
public Date getCurrentDate() {
return new Date();
}
}

View File

@ -0,0 +1,73 @@
package org.baeldung.web.controller;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.baeldung.web.dto.Foo;
import org.springframework.web.bind.annotation.RequestBody;
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;
// used to test HttpClientPostingTest
@RestController
public class SimplePostController {
@RequestMapping(value = "/users", method = RequestMethod.POST)
public String postUser(@RequestParam final String username, @RequestParam final String password) {
return "Success" + username;
}
@RequestMapping(value = "/users/detail", method = RequestMethod.POST)
public String postUserDetail(@RequestBody final Foo entity) {
return "Success" + entity.getId();
}
@RequestMapping(value = "/users/multipart", method = RequestMethod.POST)
public String uploadFile(@RequestParam final String username, @RequestParam final String password, @RequestParam("file") final MultipartFile file) {
if (!file.isEmpty()) {
try {
final DateFormat dateFormat = new SimpleDateFormat("yyyy_MM_dd_HH.mm.ss");
final String fileName = dateFormat.format(new Date());
final File fileServer = new File(fileName);
fileServer.createNewFile();
final byte[] bytes = file.getBytes();
final BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(fileServer));
stream.write(bytes);
stream.close();
return "You successfully uploaded " + username;
} catch (final Exception e) {
return "You failed to upload " + e.getMessage();
}
} else {
return "You failed to upload because the file was empty.";
}
}
@RequestMapping(value = "/users/upload", method = RequestMethod.POST)
public String postMultipart(@RequestParam("file") final MultipartFile file) {
if (!file.isEmpty()) {
try {
final DateFormat dateFormat = new SimpleDateFormat("yyyy_MM_dd_HH.mm.ss");
final String fileName = dateFormat.format(new Date());
final File fileServer = new File(fileName);
fileServer.createNewFile();
final byte[] bytes = file.getBytes();
final BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(fileServer));
stream.write(bytes);
stream.close();
return "You successfully uploaded ";
} catch (final Exception e) {
return "You failed to upload " + e.getMessage();
}
} else {
return "You failed to upload because the file was empty.";
}
}
}

View File

@ -0,0 +1,13 @@
package org.baeldung.web.controller.advice;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.AbstractJsonpResponseBodyAdvice;
@ControllerAdvice
public class JsonpControllerAdvice extends AbstractJsonpResponseBodyAdvice {
public JsonpControllerAdvice() {
super("callback");
}
}

View File

@ -0,0 +1,52 @@
package org.baeldung.web.controller.redirect;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.view.RedirectView;
@Controller
@RequestMapping("/")
public class RedirectController {
@RequestMapping(value = "/redirectWithXMLConfig", method = RequestMethod.GET)
public ModelAndView redirectWithUsingXMLConfig(final ModelMap model) {
model.addAttribute("attribute", "redirectWithXMLConfig");
return new ModelAndView("RedirectedUrl", model);
}
@RequestMapping(value = "/redirectWithRedirectPrefix", method = RequestMethod.GET)
public ModelAndView redirectWithUsingRedirectPrefix(final ModelMap model) {
model.addAttribute("attribute", "redirectWithRedirectPrefix");
return new ModelAndView("redirect:/redirectedUrl", model);
}
@RequestMapping(value = "/redirectWithRedirectAttributes", method = RequestMethod.GET)
public RedirectView redirectWithRedirectAttributes(final RedirectAttributes redirectAttributes) {
redirectAttributes.addFlashAttribute("flashAttribute", "redirectWithRedirectAttributes");
redirectAttributes.addAttribute("attribute", "redirectWithRedirectAttributes");
return new RedirectView("redirectedUrl");
}
@RequestMapping(value = "/redirectWithRedirectView", method = RequestMethod.GET)
public RedirectView redirectWithUsingRedirectView(final ModelMap model) {
model.addAttribute("attribute", "redirectWithRedirectView");
return new RedirectView("redirectedUrl");
}
@RequestMapping(value = "/forwardWithForwardPrefix", method = RequestMethod.GET)
public ModelAndView forwardWithUsingForwardPrefix(final ModelMap model) {
model.addAttribute("attribute", "redirectWithForwardPrefix");
return new ModelAndView("forward:/redirectedUrl", model);
}
@RequestMapping(value = "/redirectedUrl", method = RequestMethod.GET)
public ModelAndView redirection(final ModelMap model, @ModelAttribute("flashAttribute") final Object flashAttribute) {
model.addAttribute("redirectionAttribute", flashAttribute);
return new ModelAndView("redirection", model);
}
}

View File

@ -0,0 +1,24 @@
package org.baeldung.web.controller.status;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class ExampleController {
@RequestMapping(value = "/controller", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity sendViaResponseEntity() {
return new ResponseEntity(HttpStatus.NOT_ACCEPTABLE);
}
@RequestMapping(value = "/exception", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity sendViaException() {
throw new ForbiddenException();
}
}

View File

@ -0,0 +1,9 @@
package org.baeldung.web.controller.status;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(value = HttpStatus.FORBIDDEN, reason="To show an example of a custom message")
public class ForbiddenException extends RuntimeException {
}

View File

@ -0,0 +1,38 @@
package org.baeldung.web.dto;
public class Company {
private long id;
private String name;
public Company() {
super();
}
public Company(final long id, final String name) {
this.id = id;
this.name = name;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
public long getId() {
return id;
}
public void setId(final long id) {
this.id = id;
}
@Override
public String toString() {
return "Company [id=" + id + ", name=" + name + "]";
}
}

View File

@ -0,0 +1,39 @@
package org.baeldung.web.dto;
import com.thoughtworks.xstream.annotations.XStreamAlias;
@XStreamAlias("Foo")
public class Foo {
private long id;
private String name;
public Foo() {
super();
}
public Foo(final long id, final String name) {
super();
this.id = id;
this.name = name;
}
// API
public long getId() {
return id;
}
public void setId(final long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
}

View File

@ -0,0 +1,620 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: FooProtos.proto
package org.baeldung.web.dto;
public final class FooProtos {
private FooProtos() {}
public static void registerAllExtensions(
com.google.protobuf.ExtensionRegistry registry) {
}
public interface FooOrBuilder extends
// @@protoc_insertion_point(interface_extends:baeldung.Foo)
com.google.protobuf.MessageOrBuilder {
/**
* <code>required int64 id = 1;</code>
*/
boolean hasId();
/**
* <code>required int64 id = 1;</code>
*/
long getId();
/**
* <code>required string name = 2;</code>
*/
boolean hasName();
/**
* <code>required string name = 2;</code>
*/
java.lang.String getName();
/**
* <code>required string name = 2;</code>
*/
com.google.protobuf.ByteString
getNameBytes();
}
/**
* Protobuf type {@code baeldung.Foo}
*/
public static final class Foo extends
com.google.protobuf.GeneratedMessage implements
// @@protoc_insertion_point(message_implements:baeldung.Foo)
FooOrBuilder {
// Use Foo.newBuilder() to construct.
private Foo(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
super(builder);
this.unknownFields = builder.getUnknownFields();
}
private Foo(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
private static final Foo defaultInstance;
public static Foo getDefaultInstance() {
return defaultInstance;
}
public Foo getDefaultInstanceForType() {
return defaultInstance;
}
private final com.google.protobuf.UnknownFieldSet unknownFields;
@java.lang.Override
public final com.google.protobuf.UnknownFieldSet
getUnknownFields() {
return this.unknownFields;
}
private Foo(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
initFields();
int mutable_bitField0_ = 0;
com.google.protobuf.UnknownFieldSet.Builder unknownFields =
com.google.protobuf.UnknownFieldSet.newBuilder();
try {
boolean done = false;
while (!done) {
int tag = input.readTag();
switch (tag) {
case 0:
done = true;
break;
default: {
if (!parseUnknownField(input, unknownFields,
extensionRegistry, tag)) {
done = true;
}
break;
}
case 8: {
bitField0_ |= 0x00000001;
id_ = input.readInt64();
break;
}
case 18: {
com.google.protobuf.ByteString bs = input.readBytes();
bitField0_ |= 0x00000002;
name_ = bs;
break;
}
}
}
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
throw e.setUnfinishedMessage(this);
} catch (java.io.IOException e) {
throw new com.google.protobuf.InvalidProtocolBufferException(
e.getMessage()).setUnfinishedMessage(this);
} finally {
this.unknownFields = unknownFields.build();
makeExtensionsImmutable();
}
}
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
return org.baeldung.web.dto.FooProtos.internal_static_baeldung_Foo_descriptor;
}
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
internalGetFieldAccessorTable() {
return org.baeldung.web.dto.FooProtos.internal_static_baeldung_Foo_fieldAccessorTable
.ensureFieldAccessorsInitialized(
org.baeldung.web.dto.FooProtos.Foo.class, org.baeldung.web.dto.FooProtos.Foo.Builder.class);
}
public static com.google.protobuf.Parser<Foo> PARSER =
new com.google.protobuf.AbstractParser<Foo>() {
public Foo parsePartialFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return new Foo(input, extensionRegistry);
}
};
@java.lang.Override
public com.google.protobuf.Parser<Foo> getParserForType() {
return PARSER;
}
private int bitField0_;
public static final int ID_FIELD_NUMBER = 1;
private long id_;
/**
* <code>required int64 id = 1;</code>
*/
public boolean hasId() {
return ((bitField0_ & 0x00000001) == 0x00000001);
}
/**
* <code>required int64 id = 1;</code>
*/
public long getId() {
return id_;
}
public static final int NAME_FIELD_NUMBER = 2;
private java.lang.Object name_;
/**
* <code>required string name = 2;</code>
*/
public boolean hasName() {
return ((bitField0_ & 0x00000002) == 0x00000002);
}
/**
* <code>required string name = 2;</code>
*/
public java.lang.String getName() {
java.lang.Object ref = name_;
if (ref instanceof java.lang.String) {
return (java.lang.String) ref;
} else {
com.google.protobuf.ByteString bs =
(com.google.protobuf.ByteString) ref;
java.lang.String s = bs.toStringUtf8();
if (bs.isValidUtf8()) {
name_ = s;
}
return s;
}
}
/**
* <code>required string name = 2;</code>
*/
public com.google.protobuf.ByteString
getNameBytes() {
java.lang.Object ref = name_;
if (ref instanceof java.lang.String) {
com.google.protobuf.ByteString b =
com.google.protobuf.ByteString.copyFromUtf8(
(java.lang.String) ref);
name_ = b;
return b;
} else {
return (com.google.protobuf.ByteString) ref;
}
}
private void initFields() {
id_ = 0L;
name_ = "";
}
private byte memoizedIsInitialized = -1;
public final boolean isInitialized() {
byte isInitialized = memoizedIsInitialized;
if (isInitialized == 1) return true;
if (isInitialized == 0) return false;
if (!hasId()) {
memoizedIsInitialized = 0;
return false;
}
if (!hasName()) {
memoizedIsInitialized = 0;
return false;
}
memoizedIsInitialized = 1;
return true;
}
public void writeTo(com.google.protobuf.CodedOutputStream output)
throws java.io.IOException {
getSerializedSize();
if (((bitField0_ & 0x00000001) == 0x00000001)) {
output.writeInt64(1, id_);
}
if (((bitField0_ & 0x00000002) == 0x00000002)) {
output.writeBytes(2, getNameBytes());
}
getUnknownFields().writeTo(output);
}
private int memoizedSerializedSize = -1;
public int getSerializedSize() {
int size = memoizedSerializedSize;
if (size != -1) return size;
size = 0;
if (((bitField0_ & 0x00000001) == 0x00000001)) {
size += com.google.protobuf.CodedOutputStream
.computeInt64Size(1, id_);
}
if (((bitField0_ & 0x00000002) == 0x00000002)) {
size += com.google.protobuf.CodedOutputStream
.computeBytesSize(2, getNameBytes());
}
size += getUnknownFields().getSerializedSize();
memoizedSerializedSize = size;
return size;
}
private static final long serialVersionUID = 0L;
@java.lang.Override
protected java.lang.Object writeReplace()
throws java.io.ObjectStreamException {
return super.writeReplace();
}
public static org.baeldung.web.dto.FooProtos.Foo parseFrom(
com.google.protobuf.ByteString data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static org.baeldung.web.dto.FooProtos.Foo parseFrom(
com.google.protobuf.ByteString data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static org.baeldung.web.dto.FooProtos.Foo parseFrom(byte[] data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static org.baeldung.web.dto.FooProtos.Foo parseFrom(
byte[] data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static org.baeldung.web.dto.FooProtos.Foo parseFrom(java.io.InputStream input)
throws java.io.IOException {
return PARSER.parseFrom(input);
}
public static org.baeldung.web.dto.FooProtos.Foo parseFrom(
java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return PARSER.parseFrom(input, extensionRegistry);
}
public static org.baeldung.web.dto.FooProtos.Foo parseDelimitedFrom(java.io.InputStream input)
throws java.io.IOException {
return PARSER.parseDelimitedFrom(input);
}
public static org.baeldung.web.dto.FooProtos.Foo parseDelimitedFrom(
java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return PARSER.parseDelimitedFrom(input, extensionRegistry);
}
public static org.baeldung.web.dto.FooProtos.Foo parseFrom(
com.google.protobuf.CodedInputStream input)
throws java.io.IOException {
return PARSER.parseFrom(input);
}
public static org.baeldung.web.dto.FooProtos.Foo parseFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return PARSER.parseFrom(input, extensionRegistry);
}
public static Builder newBuilder() { return Builder.create(); }
public Builder newBuilderForType() { return newBuilder(); }
public static Builder newBuilder(org.baeldung.web.dto.FooProtos.Foo prototype) {
return newBuilder().mergeFrom(prototype);
}
public Builder toBuilder() { return newBuilder(this); }
@java.lang.Override
protected Builder newBuilderForType(
com.google.protobuf.GeneratedMessage.BuilderParent parent) {
Builder builder = new Builder(parent);
return builder;
}
/**
* Protobuf type {@code baeldung.Foo}
*/
public static final class Builder extends
com.google.protobuf.GeneratedMessage.Builder<Builder> implements
// @@protoc_insertion_point(builder_implements:baeldung.Foo)
org.baeldung.web.dto.FooProtos.FooOrBuilder {
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
return org.baeldung.web.dto.FooProtos.internal_static_baeldung_Foo_descriptor;
}
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
internalGetFieldAccessorTable() {
return org.baeldung.web.dto.FooProtos.internal_static_baeldung_Foo_fieldAccessorTable
.ensureFieldAccessorsInitialized(
org.baeldung.web.dto.FooProtos.Foo.class, org.baeldung.web.dto.FooProtos.Foo.Builder.class);
}
// Construct using org.baeldung.web.dto.FooProtos.Foo.newBuilder()
private Builder() {
maybeForceBuilderInitialization();
}
private Builder(
com.google.protobuf.GeneratedMessage.BuilderParent parent) {
super(parent);
maybeForceBuilderInitialization();
}
private void maybeForceBuilderInitialization() {
if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
}
}
private static Builder create() {
return new Builder();
}
public Builder clear() {
super.clear();
id_ = 0L;
bitField0_ = (bitField0_ & ~0x00000001);
name_ = "";
bitField0_ = (bitField0_ & ~0x00000002);
return this;
}
public Builder clone() {
return create().mergeFrom(buildPartial());
}
public com.google.protobuf.Descriptors.Descriptor
getDescriptorForType() {
return org.baeldung.web.dto.FooProtos.internal_static_baeldung_Foo_descriptor;
}
public org.baeldung.web.dto.FooProtos.Foo getDefaultInstanceForType() {
return org.baeldung.web.dto.FooProtos.Foo.getDefaultInstance();
}
public org.baeldung.web.dto.FooProtos.Foo build() {
org.baeldung.web.dto.FooProtos.Foo result = buildPartial();
if (!result.isInitialized()) {
throw newUninitializedMessageException(result);
}
return result;
}
public org.baeldung.web.dto.FooProtos.Foo buildPartial() {
org.baeldung.web.dto.FooProtos.Foo result = new org.baeldung.web.dto.FooProtos.Foo(this);
int from_bitField0_ = bitField0_;
int to_bitField0_ = 0;
if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
to_bitField0_ |= 0x00000001;
}
result.id_ = id_;
if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
to_bitField0_ |= 0x00000002;
}
result.name_ = name_;
result.bitField0_ = to_bitField0_;
onBuilt();
return result;
}
public Builder mergeFrom(com.google.protobuf.Message other) {
if (other instanceof org.baeldung.web.dto.FooProtos.Foo) {
return mergeFrom((org.baeldung.web.dto.FooProtos.Foo)other);
} else {
super.mergeFrom(other);
return this;
}
}
public Builder mergeFrom(org.baeldung.web.dto.FooProtos.Foo other) {
if (other == org.baeldung.web.dto.FooProtos.Foo.getDefaultInstance()) return this;
if (other.hasId()) {
setId(other.getId());
}
if (other.hasName()) {
bitField0_ |= 0x00000002;
name_ = other.name_;
onChanged();
}
this.mergeUnknownFields(other.getUnknownFields());
return this;
}
public final boolean isInitialized() {
if (!hasId()) {
return false;
}
if (!hasName()) {
return false;
}
return true;
}
public Builder mergeFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
org.baeldung.web.dto.FooProtos.Foo parsedMessage = null;
try {
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
parsedMessage = (org.baeldung.web.dto.FooProtos.Foo) e.getUnfinishedMessage();
throw e;
} finally {
if (parsedMessage != null) {
mergeFrom(parsedMessage);
}
}
return this;
}
private int bitField0_;
private long id_ ;
/**
* <code>required int64 id = 1;</code>
*/
public boolean hasId() {
return ((bitField0_ & 0x00000001) == 0x00000001);
}
/**
* <code>required int64 id = 1;</code>
*/
public long getId() {
return id_;
}
/**
* <code>required int64 id = 1;</code>
*/
public Builder setId(long value) {
bitField0_ |= 0x00000001;
id_ = value;
onChanged();
return this;
}
/**
* <code>required int64 id = 1;</code>
*/
public Builder clearId() {
bitField0_ = (bitField0_ & ~0x00000001);
id_ = 0L;
onChanged();
return this;
}
private java.lang.Object name_ = "";
/**
* <code>required string name = 2;</code>
*/
public boolean hasName() {
return ((bitField0_ & 0x00000002) == 0x00000002);
}
/**
* <code>required string name = 2;</code>
*/
public java.lang.String getName() {
java.lang.Object ref = name_;
if (!(ref instanceof java.lang.String)) {
com.google.protobuf.ByteString bs =
(com.google.protobuf.ByteString) ref;
java.lang.String s = bs.toStringUtf8();
if (bs.isValidUtf8()) {
name_ = s;
}
return s;
} else {
return (java.lang.String) ref;
}
}
/**
* <code>required string name = 2;</code>
*/
public com.google.protobuf.ByteString
getNameBytes() {
java.lang.Object ref = name_;
if (ref instanceof String) {
com.google.protobuf.ByteString b =
com.google.protobuf.ByteString.copyFromUtf8(
(java.lang.String) ref);
name_ = b;
return b;
} else {
return (com.google.protobuf.ByteString) ref;
}
}
/**
* <code>required string name = 2;</code>
*/
public Builder setName(
java.lang.String value) {
if (value == null) {
throw new NullPointerException();
}
bitField0_ |= 0x00000002;
name_ = value;
onChanged();
return this;
}
/**
* <code>required string name = 2;</code>
*/
public Builder clearName() {
bitField0_ = (bitField0_ & ~0x00000002);
name_ = getDefaultInstance().getName();
onChanged();
return this;
}
/**
* <code>required string name = 2;</code>
*/
public Builder setNameBytes(
com.google.protobuf.ByteString value) {
if (value == null) {
throw new NullPointerException();
}
bitField0_ |= 0x00000002;
name_ = value;
onChanged();
return this;
}
// @@protoc_insertion_point(builder_scope:baeldung.Foo)
}
static {
defaultInstance = new Foo(true);
defaultInstance.initFields();
}
// @@protoc_insertion_point(class_scope:baeldung.Foo)
}
private static final com.google.protobuf.Descriptors.Descriptor
internal_static_baeldung_Foo_descriptor;
private static
com.google.protobuf.GeneratedMessage.FieldAccessorTable
internal_static_baeldung_Foo_fieldAccessorTable;
public static com.google.protobuf.Descriptors.FileDescriptor
getDescriptor() {
return descriptor;
}
private static com.google.protobuf.Descriptors.FileDescriptor
descriptor;
static {
java.lang.String[] descriptorData = {
"\n\017FooProtos.proto\022\010baeldung\"\037\n\003Foo\022\n\n\002id" +
"\030\001 \002(\003\022\014\n\004name\030\002 \002(\tB!\n\024org.baeldung.web" +
".dtoB\tFooProtos"
};
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() {
public com.google.protobuf.ExtensionRegistry assignDescriptors(
com.google.protobuf.Descriptors.FileDescriptor root) {
descriptor = root;
return null;
}
};
com.google.protobuf.Descriptors.FileDescriptor
.internalBuildGeneratedFileFrom(descriptorData,
new com.google.protobuf.Descriptors.FileDescriptor[] {
}, assigner);
internal_static_baeldung_Foo_descriptor =
getDescriptor().getMessageTypes().get(0);
internal_static_baeldung_Foo_fieldAccessorTable = new
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_baeldung_Foo_descriptor,
new java.lang.String[] { "Id", "Name", });
}
// @@protoc_insertion_point(outer_class_scope)
}

View File

@ -0,0 +1,36 @@
package org.baeldung.web.dto;
import com.fasterxml.jackson.annotation.JsonView;
public class Item {
@JsonView(Views.Public.class)
public int id;
@JsonView(Views.Public.class)
public String itemName;
@JsonView(Views.Internal.class)
public String ownerName;
public Item() {
super();
}
public Item(final int id, final String itemName, final String ownerName) {
this.id = id;
this.itemName = itemName;
this.ownerName = ownerName;
}
public int getId() {
return id;
}
public String getItemName() {
return itemName;
}
public String getOwnerName() {
return ownerName;
}
}

View File

@ -0,0 +1,9 @@
package org.baeldung.web.dto;
public class ItemManager {
public static Item getById(final int id) {
final Item item = new Item(2, "book", "John");
return item;
}
}

View File

@ -0,0 +1,9 @@
package org.baeldung.web.dto;
public class Views {
public static class Public {
}
public static class Internal extends Public {
}
}

View File

@ -0,0 +1,20 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n
</pattern>
</encoder>
</appender>
<logger name="org.springframework" level="WARN" />
<logger name="org.springframework.transaction" level="WARN" />
<!-- in order to debug some marshalling issues, this needs to be TRACE -->
<logger name="org.springframework.web.servlet.mvc" level="WARN" />
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"
>
<context:component-scan base-package="org.baeldung.web" />
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" />
<bean class="org.springframework.web.servlet.view.XmlViewResolver">
<property name="location">
<value>/WEB-INF/spring-views.xml</value>
</property>
<property name="order" value="0" />
</bean>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- max upload size in bytes -->
<property name="maxUploadSize" value="20971520" /> <!-- 20MB -->
<!-- max size of file in memory (in bytes) -->
<property name="maxInMemorySize" value="1048576" /> <!-- 1MB -->
</bean>
</beans>

View File

@ -0,0 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Company Data</title>
<script src="https://code.jquery.com/jquery-3.1.0.js"
integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="
crossorigin="anonymous"></script>
<script>
$(document).ready(function(){
$('#REST-button').click(function() {
$.ajax({
url: 'http://localhost:8080/spring-rest/companyRest?callback=getCompanyData',
data: {
format: 'json'
},
type: 'GET',
jsonpCallback:'getCompanyData',
dataType: 'jsonp',
error: function() {
$('#infoREST').html('<p>An error has occurred</p>');
},
success: function(data) {
console.log("sucess");
}
});
});
});
function getCompanyData(data) {
document.write("<b>ID:</b> "+data.id+"<br/>");
document.write("<b>NAME:</b> "+data.name+"<br/>");
document.write("<br/>");
}
</script>
</head>
<body>
<!-- Using REST URL-->
<button id="REST-button">Test REST JSON-P!</button>
<div id="infoREST"></div>
</body>
</html>

View File

@ -0,0 +1,10 @@
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"
>
<bean id="RedirectedUrl" class="org.springframework.web.servlet.view.RedirectView">
<property name="url" value="redirectedUrl" />
</bean>
</beans>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"
>
<display-name>Spring MVC Application</display-name>
<!-- Spring root -->
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>org.baeldung.config</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Spring child -->
<servlet>
<servlet-name>api</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>api</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file/>
</welcome-file-list>
</web-app>

View File

@ -0,0 +1,67 @@
package org.baeldung.web.controller.redirect;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.flash;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.context.WebApplicationContext;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/api-servlet.xml")
@WebAppConfiguration
public class RedirectControllerTest {
private MockMvc mockMvc;
@Autowired
protected WebApplicationContext wac;
@Before
public void setup() {
mockMvc = webAppContextSetup(wac).build();
}
@Test
public void whenRedirectOnUrlWithUsingXMLConfig_thenStatusRedirectionAndRedirectedOnUrl() throws Exception {
mockMvc.perform(get("/redirectWithXMLConfig")).andExpect(status().is3xxRedirection()).andExpect(view().name("RedirectedUrl")).andExpect(model().attribute("attribute", is("redirectWithXMLConfig")))
.andExpect(redirectedUrl("redirectedUrl?attribute=redirectWithXMLConfig"));
}
@Test
public void whenRedirectOnUrlWithUsingRedirectPrefix_thenStatusRedirectionAndRedirectedOnUrl() throws Exception {
mockMvc.perform(get("/redirectWithRedirectPrefix")).andExpect(status().is3xxRedirection()).andExpect(view().name("redirect:/redirectedUrl")).andExpect(model().attribute("attribute", is("redirectWithRedirectPrefix")))
.andExpect(redirectedUrl("/redirectedUrl?attribute=redirectWithRedirectPrefix"));
}
@Test
public void whenRedirectOnUrlWithUsingRedirectAttributes_thenStatusRedirectionAndRedirectedOnUrlAndAddedAttributeToFlashScope() throws Exception {
mockMvc.perform(get("/redirectWithRedirectAttributes")).andExpect(status().is3xxRedirection()).andExpect(flash().attribute("flashAttribute", is("redirectWithRedirectAttributes")))
.andExpect(model().attribute("attribute", is("redirectWithRedirectAttributes"))).andExpect(model().attribute("flashAttribute", is(nullValue()))).andExpect(redirectedUrl("redirectedUrl?attribute=redirectWithRedirectAttributes"));
}
@Test
public void whenRedirectOnUrlWithUsingRedirectView_thenStatusRedirectionAndRedirectedOnUrlAndAddedAttributeToFlashScope() throws Exception {
mockMvc.perform(get("/redirectWithRedirectView")).andExpect(status().is3xxRedirection()).andExpect(model().attribute("attribute", is("redirectWithRedirectView"))).andExpect(redirectedUrl("redirectedUrl?attribute=redirectWithRedirectView"));
}
@Test
public void whenRedirectOnUrlWithUsingForwardPrefix_thenStatusOkAndForwardedOnUrl() throws Exception {
mockMvc.perform(get("/forwardWithForwardPrefix")).andExpect(status().isOk()).andExpect(view().name("forward:/redirectedUrl")).andExpect(model().attribute("attribute", is("redirectWithForwardPrefix"))).andExpect(forwardedUrl("/redirectedUrl"));
}
}

View File

@ -0,0 +1,44 @@
package org.baeldung.web.controller.status;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.baeldung.config.WebConfig;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = WebConfig.class)
@WebAppConfiguration
public class ExampleControllerTest {
private MockMvc mockMvc;
@Autowired
private WebApplicationContext webApplicationContext;
@Before
public void setUp() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
@Test
public void whenGetRequestSentToController_thenReturnsStatusNotAcceptable() throws Exception {
mockMvc.perform(get("/controller"))
.andExpect(status().isNotAcceptable());
}
@Test
public void whenGetRequestSentToException_thenReturnsStatusForbidden() throws Exception {
mockMvc.perform(get("/exception"))
.andExpect(status().isForbidden());
}
}

View File

@ -0,0 +1,148 @@
package org.baeldung.web.test;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.baeldung.config.converter.KryoHttpMessageConverter;
import org.baeldung.web.dto.Foo;
import org.baeldung.web.dto.FooProtos;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter;
import org.springframework.http.converter.xml.MarshallingHttpMessageConverter;
import org.springframework.oxm.xstream.XStreamMarshaller;
import org.springframework.web.client.RestTemplate;
/**
* Integration Test class. Tests methods hits the server's rest services.
*/
public class SpringHttpMessageConvertersIntegrationTestsCase {
private static String BASE_URI = "http://localhost:8080/spring-rest/";
/**
* Without specifying Accept Header, uses the default response from the
* server (in this case json)
*/
@Test
public void whenRetrievingAFoo_thenCorrect() {
final String URI = BASE_URI + "foos/{id}";
final RestTemplate restTemplate = new RestTemplate();
final Foo resource = restTemplate.getForObject(URI, Foo.class, "1");
assertThat(resource, notNullValue());
}
@Test
public void givenConsumingXml_whenReadingTheFoo_thenCorrect() {
final String URI = BASE_URI + "foos/{id}";
final RestTemplate restTemplate = new RestTemplate();
restTemplate.setMessageConverters(getMessageConverters());
final HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_XML));
final HttpEntity<String> entity = new HttpEntity<String>(headers);
final ResponseEntity<Foo> response = restTemplate.exchange(URI, HttpMethod.GET, entity, Foo.class, "1");
final Foo resource = response.getBody();
assertThat(resource, notNullValue());
}
@Test
public void givenConsumingJson_whenReadingTheFoo_thenCorrect() {
final String URI = BASE_URI + "foos/{id}";
final RestTemplate restTemplate = new RestTemplate();
restTemplate.setMessageConverters(getMessageConverters());
final HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
final HttpEntity<String> entity = new HttpEntity<String>(headers);
final ResponseEntity<Foo> response = restTemplate.exchange(URI, HttpMethod.GET, entity, Foo.class, "1");
final Foo resource = response.getBody();
assertThat(resource, notNullValue());
}
@Test
public void givenConsumingXml_whenWritingTheFoo_thenCorrect() {
final String URI = BASE_URI + "foos/{id}";
final RestTemplate restTemplate = new RestTemplate();
restTemplate.setMessageConverters(getMessageConverters());
final Foo resource = new Foo(4, "jason");
final HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
headers.setContentType((MediaType.APPLICATION_XML));
final HttpEntity<Foo> entity = new HttpEntity<Foo>(resource, headers);
final ResponseEntity<Foo> response = restTemplate.exchange(URI, HttpMethod.PUT, entity, Foo.class, resource.getId());
final Foo fooResponse = response.getBody();
Assert.assertEquals(resource.getId(), fooResponse.getId());
}
@Test
public void givenConsumingProtobuf_whenReadingTheFoo_thenCorrect() {
final String URI = BASE_URI + "foos/{id}";
final RestTemplate restTemplate = new RestTemplate();
restTemplate.setMessageConverters(Arrays.asList(new ProtobufHttpMessageConverter()));
final HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(ProtobufHttpMessageConverter.PROTOBUF));
final HttpEntity<String> entity = new HttpEntity<String>(headers);
final ResponseEntity<FooProtos.Foo> response = restTemplate.exchange(URI, HttpMethod.GET, entity, FooProtos.Foo.class, "1");
final FooProtos.Foo resource = response.getBody();
assertThat(resource, notNullValue());
}
@Test
public void givenConsumingKryo_whenReadingTheFoo_thenCorrect() {
final String URI = BASE_URI + "foos/{id}";
final RestTemplate restTemplate = new RestTemplate();
restTemplate.setMessageConverters(Arrays.asList(new KryoHttpMessageConverter()));
final HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(KryoHttpMessageConverter.KRYO));
final HttpEntity<String> entity = new HttpEntity<String>(headers);
final ResponseEntity<Foo> response = restTemplate.exchange(URI, HttpMethod.GET, entity, Foo.class, "1");
final Foo resource = response.getBody();
assertThat(resource, notNullValue());
}
// UTIL
private List<HttpMessageConverter<?>> getMessageConverters() {
final List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
final MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter();
final XStreamMarshaller xstreamMarshaller = new XStreamMarshaller();
xmlConverter.setMarshaller(xstreamMarshaller);
xmlConverter.setUnmarshaller(xstreamMarshaller);
converters.add(xmlConverter);
converters.add(new MappingJackson2HttpMessageConverter());
return converters;
}
}

View File

@ -0,0 +1,13 @@
*.class
#folders#
/target
/neoDb*
/data
/src/main/webapp/WEB-INF/classes
*/META-INF/*
# Packaged files #
*.jar
*.war
*.ear