[JAVA-22] Moved articles not in ebook from spring-boot-rest to spring-boot-mvc-2

This commit is contained in:
Donato Rimenti
2020-03-18 10:34:00 +01:00
parent 375701df9c
commit b7082ef2a7
21 changed files with 1080 additions and 5 deletions

View File

@@ -0,0 +1,123 @@
package com.baeldung.etag;
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.assertj.core.util.Preconditions;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import io.restassured.response.Response;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@ComponentScan(basePackageClasses = WebConfig.class)
@EnableAutoConfiguration
public class EtagIntegrationTest {
@LocalServerPort
private int port;
@Test
public void givenResourceExists_whenRetrievingResource_thenEtagIsAlsoReturned() {
// Given
final String uriOfResource = createAsUri();
// When
final Response findOneResponse = RestAssured.given().header("Accept", "application/json").get(uriOfResource);
// Then
assertNotNull(findOneResponse.getHeader(HttpHeaders.ETAG));
}
@Test
public void givenResourceWasRetrieved_whenRetrievingAgainWithEtag_thenNotModifiedReturned() {
// Given
final String uriOfResource = createAsUri();
final Response findOneResponse = RestAssured.given().header("Accept", "application/json").get(uriOfResource);
final String etagValue = findOneResponse.getHeader(HttpHeaders.ETAG);
// When
final Response secondFindOneResponse = RestAssured.given().header("Accept", "application/json")
.headers("If-None-Match", etagValue).get(uriOfResource);
// Then
assertTrue(secondFindOneResponse.getStatusCode() == 304);
}
@Test
public void givenResourceWasRetrievedThenModified_whenRetrievingAgainWithEtag_thenResourceIsReturned() {
// Given
final String uriOfResource = createAsUri();
final Response firstFindOneResponse = RestAssured.given().header("Accept", "application/json")
.get(uriOfResource);
final String etagValue = firstFindOneResponse.getHeader(HttpHeaders.ETAG);
final long createdId = firstFindOneResponse.jsonPath().getLong("id");
Foo updatedFoo = new Foo("updated value");
updatedFoo.setId(createdId);
Response updatedResponse = RestAssured.given().contentType(ContentType.JSON).body(updatedFoo)
.put(uriOfResource);
assertThat(updatedResponse.getStatusCode() == 200);
// When
final Response secondFindOneResponse = RestAssured.given().header("Accept", "application/json")
.headers("If-None-Match", etagValue).get(uriOfResource);
// Then
assertTrue(secondFindOneResponse.getStatusCode() == 200);
}
@Test
@Ignore("Not Yet Implemented By Spring - https://jira.springsource.org/browse/SPR-10164")
public void givenResourceExists_whenRetrievedWithIfMatchIncorrectEtag_then412IsReceived() {
// Given
final String uriOfResource = createAsUri();
// When
final Response findOneResponse = RestAssured.given().header("Accept", "application/json")
.headers("If-Match", randomAlphabetic(8)).get(uriOfResource);
// Then
assertTrue(findOneResponse.getStatusCode() == 412);
}
private final String createAsUri() {
final Response response = createAsResponse(new Foo(randomAlphabetic(6)));
Preconditions.checkState(response.getStatusCode() == 201, "create operation: " + response.getStatusCode());
return getURL() + "/" + response.getBody().as(Foo.class).getId();
}
private Response createAsResponse(final Foo resource) {
String resourceAsString;
try {
resourceAsString = new ObjectMapper().writeValueAsString(resource);
} catch (JsonProcessingException e) {
throw new AssertionError("Error during serialization");
}
return RestAssured.given().contentType(MediaType.APPLICATION_JSON.toString()).body(resourceAsString)
.post(getURL());
}
private String getURL() {
return "http://localhost:" + port + "/foos";
}
}

View File

@@ -0,0 +1,82 @@
package com.baeldung.mime;
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.baeldung.etag.Foo;
import com.baeldung.etag.WebConfig;
import io.restassured.RestAssured;
import io.restassured.response.Response;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes= WebConfig.class, webEnvironment = WebEnvironment.RANDOM_PORT)
@ComponentScan({"com.baeldung.mime", "com.baeldung.etag"})
@EnableAutoConfiguration
@ActiveProfiles("test")
public class FooLiveTest {
@LocalServerPort
private int port;
@Autowired
protected IMarshaller marshaller;
// API
public final void create() {
create(new Foo(randomAlphabetic(6)));
}
public final String createAsUri() {
return createAsUri(new Foo(randomAlphabetic(6)));
}
protected final void create(final Foo resource) {
createAsUri(resource);
}
private final String createAsUri(final Foo resource) {
final Response response = createAsResponse(resource);
return getURL() + "/" + response.getBody().as(Foo.class).getId();
}
private final Response createAsResponse(final Foo resource) {
final String resourceAsString = marshaller.encode(resource);
return RestAssured.given()
.contentType(marshaller.getMime())
.body(resourceAsString)
.post(getURL());
}
//
protected String getURL() {
return "http://localhost:" + port + "/foos";
}
@Test
public void givenResourceExists_whenRetrievingResource_thenEtagIsAlsoReturned() {
// Given
final String uriOfResource = createAsUri();
// When
final Response findOneResponse = RestAssured.given().header("Accept", "application/json").get(uriOfResource);
// Then
assertEquals(findOneResponse.getStatusCode(), 200);
}
}

View File

@@ -0,0 +1,15 @@
package com.baeldung.mime;
import java.util.List;
public interface IMarshaller {
<T> String encode(final T entity);
<T> T decode(final String entityAsString, final Class<T> clazz);
<T> List<T> decodeList(final String entitiesAsString, final Class<T> clazz);
String getMime();
}

View File

@@ -0,0 +1,75 @@
package com.baeldung.mime;
import java.io.IOException;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import com.baeldung.etag.Foo;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
public final class JacksonMarshaller implements IMarshaller {
private final Logger logger = LoggerFactory.getLogger(JacksonMarshaller.class);
private final ObjectMapper objectMapper;
public JacksonMarshaller() {
super();
objectMapper = new ObjectMapper();
}
// API
@Override
public final <T> String encode(final T resource) {
String entityAsJSON = null;
try {
entityAsJSON = objectMapper.writeValueAsString(resource);
} catch (final IOException ioEx) {
logger.error("", ioEx);
}
return entityAsJSON;
}
@Override
public final <T> T decode(final String resourceAsString, final Class<T> clazz) {
T entity = null;
try {
entity = objectMapper.readValue(resourceAsString, clazz);
} catch (final IOException ioEx) {
logger.error("", ioEx);
}
return entity;
}
@SuppressWarnings("unchecked")
@Override
public final <T> List<T> decodeList(final String resourcesAsString, final Class<T> clazz) {
List<T> entities = null;
try {
if (clazz.equals(Foo.class)) {
entities = objectMapper.readValue(resourcesAsString, new TypeReference<List<T>>() {
// ...
});
} else {
entities = objectMapper.readValue(resourcesAsString, List.class);
}
} catch (final IOException ioEx) {
logger.error("", ioEx);
}
return entities;
}
@Override
public final String getMime() {
return MediaType.APPLICATION_JSON.toString();
}
}

View File

@@ -0,0 +1,48 @@
package com.baeldung.mime;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
@Component
@Profile("test")
public class TestMarshallerFactory implements FactoryBean<IMarshaller> {
@Autowired
private Environment env;
public TestMarshallerFactory() {
super();
}
// API
@Override
public IMarshaller getObject() {
final String testMime = env.getProperty("test.mime");
if (testMime != null) {
switch (testMime) {
case "json":
return new JacksonMarshaller();
case "xml":
return new XStreamMarshaller();
default:
throw new IllegalStateException();
}
}
return new JacksonMarshaller();
}
@Override
public Class<IMarshaller> getObjectType() {
return IMarshaller.class;
}
@Override
public boolean isSingleton() {
return true;
}
}

View File

@@ -0,0 +1,46 @@
package com.baeldung.mime;
import java.util.List;
import org.springframework.http.MediaType;
import com.baeldung.etag.Foo;
import com.thoughtworks.xstream.XStream;
public final class XStreamMarshaller implements IMarshaller {
private XStream xstream;
public XStreamMarshaller() {
super();
xstream = new XStream();
xstream.autodetectAnnotations(true);
xstream.processAnnotations(Foo.class);
}
// API
@Override
public final <T> String encode(final T resource) {
return xstream.toXML(resource);
}
@SuppressWarnings("unchecked")
@Override
public final <T> T decode(final String resourceAsString, final Class<T> clazz) {
return (T) xstream.fromXML(resourceAsString);
}
@SuppressWarnings("unchecked")
@Override
public <T> List<T> decodeList(final String resourcesAsString, final Class<T> clazz) {
return this.decode(resourcesAsString, List.class);
}
@Override
public final String getMime() {
return MediaType.APPLICATION_XML.toString();
}
}

View File

@@ -0,0 +1,73 @@
package com.baeldung.students;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import com.fasterxml.jackson.databind.ObjectMapper;
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class StudentControllerIntegrationTest {
private static final String STUDENTS_PATH = "/students/";
@Autowired
private MockMvc mockMvc;
@Test
public void whenReadAll_thenStatusIsOk() throws Exception {
this.mockMvc.perform(get(STUDENTS_PATH))
.andExpect(status().isOk());
}
@Test
public void whenReadOne_thenStatusIsOk() throws Exception {
this.mockMvc.perform(get(STUDENTS_PATH + 1))
.andExpect(status().isOk());
}
@Test
public void whenCreate_thenStatusIsCreated() throws Exception {
Student student = new Student(10, "Albert", "Einstein");
this.mockMvc.perform(post(STUDENTS_PATH).content(asJsonString(student))
.contentType(MediaType.APPLICATION_JSON_VALUE))
.andExpect(status().isCreated());
}
@Test
public void whenUpdate_thenStatusIsOk() throws Exception {
Student student = new Student(1, "Nikola", "Tesla");
this.mockMvc.perform(put(STUDENTS_PATH + 1)
.content(asJsonString(student))
.contentType(MediaType.APPLICATION_JSON_VALUE))
.andExpect(status().isOk());
}
@Test
public void whenDelete_thenStatusIsNoContent() throws Exception {
this.mockMvc.perform(delete(STUDENTS_PATH + 3))
.andExpect(status().isNoContent());
}
private String asJsonString(final Object obj) {
try {
return new ObjectMapper().writeValueAsString(obj);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}