diff --git a/spring-rest/src/main/java/org/baeldung/config/WebConfig.java b/spring-rest/src/main/java/org/baeldung/config/WebConfig.java new file mode 100644 index 0000000000..d5cd6e1eae --- /dev/null +++ b/spring-rest/src/main/java/org/baeldung/config/WebConfig.java @@ -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> 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 createXmlHttpMessageConverter() { + final MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter(); + + final XStreamMarshaller xstreamMarshaller = new XStreamMarshaller(); + xmlConverter.setMarshaller(xstreamMarshaller); + xmlConverter.setUnmarshaller(xstreamMarshaller); + + return xmlConverter; + } + +} diff --git a/spring-rest/src/main/java/org/baeldung/config/converter/KryoHttpMessageConverter.java b/spring-rest/src/main/java/org/baeldung/config/converter/KryoHttpMessageConverter.java new file mode 100644 index 0000000000..7e63a3ba9e --- /dev/null +++ b/spring-rest/src/main/java/org/baeldung/config/converter/KryoHttpMessageConverter.java @@ -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 { + + public static final MediaType KRYO = new MediaType("application", "x-kryo"); + + private static final ThreadLocal kryoThreadLocal = new ThreadLocal() { + @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 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; + } +} diff --git a/spring-rest/src/main/java/org/baeldung/web/controller/BarMappingExamplesController.java b/spring-rest/src/main/java/org/baeldung/web/controller/BarMappingExamplesController.java new file mode 100644 index 0000000000..1c3a1086ca --- /dev/null +++ b/spring-rest/src/main/java/org/baeldung/web/controller/BarMappingExamplesController.java @@ -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; + } + +} diff --git a/spring-rest/src/main/java/org/baeldung/web/controller/CompanyController.java b/spring-rest/src/main/java/org/baeldung/web/controller/CompanyController.java new file mode 100644 index 0000000000..d640ac671d --- /dev/null +++ b/spring-rest/src/main/java/org/baeldung/web/controller/CompanyController.java @@ -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; + } +} diff --git a/spring-rest/src/main/java/org/baeldung/web/controller/FooController.java b/spring-rest/src/main/java/org/baeldung/web/controller/FooController.java new file mode 100644 index 0000000000..386c64bb09 --- /dev/null +++ b/spring-rest/src/main/java/org/baeldung/web/controller/FooController.java @@ -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(); + } +} diff --git a/spring-rest/src/main/java/org/baeldung/web/controller/FooMappingExamplesController.java b/spring-rest/src/main/java/org/baeldung/web/controller/FooMappingExamplesController.java new file mode 100644 index 0000000000..5fb92d6d87 --- /dev/null +++ b/spring-rest/src/main/java/org/baeldung/web/controller/FooMappingExamplesController.java @@ -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"; + } + +} diff --git a/spring-rest/src/main/java/org/baeldung/web/controller/ItemController.java b/spring-rest/src/main/java/org/baeldung/web/controller/ItemController.java new file mode 100644 index 0000000000..cfde4b23b1 --- /dev/null +++ b/spring-rest/src/main/java/org/baeldung/web/controller/ItemController.java @@ -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(); + } +} \ No newline at end of file diff --git a/spring-rest/src/main/java/org/baeldung/web/controller/SimplePostController.java b/spring-rest/src/main/java/org/baeldung/web/controller/SimplePostController.java new file mode 100644 index 0000000000..f8407acb47 --- /dev/null +++ b/spring-rest/src/main/java/org/baeldung/web/controller/SimplePostController.java @@ -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."; + } + } +} diff --git a/spring-rest/src/main/java/org/baeldung/web/controller/advice/JsonpControllerAdvice.java b/spring-rest/src/main/java/org/baeldung/web/controller/advice/JsonpControllerAdvice.java new file mode 100644 index 0000000000..7d62cc0c66 --- /dev/null +++ b/spring-rest/src/main/java/org/baeldung/web/controller/advice/JsonpControllerAdvice.java @@ -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"); + } + +} diff --git a/spring-rest/src/main/java/org/baeldung/web/controller/redirect/RedirectController.java b/spring-rest/src/main/java/org/baeldung/web/controller/redirect/RedirectController.java new file mode 100644 index 0000000000..472c0c8bf5 --- /dev/null +++ b/spring-rest/src/main/java/org/baeldung/web/controller/redirect/RedirectController.java @@ -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); + } +} \ No newline at end of file diff --git a/spring-rest/src/main/java/org/baeldung/web/controller/status/ExampleController.java b/spring-rest/src/main/java/org/baeldung/web/controller/status/ExampleController.java new file mode 100644 index 0000000000..ceda138768 --- /dev/null +++ b/spring-rest/src/main/java/org/baeldung/web/controller/status/ExampleController.java @@ -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(); + } +} diff --git a/spring-rest/src/main/java/org/baeldung/web/controller/status/ForbiddenException.java b/spring-rest/src/main/java/org/baeldung/web/controller/status/ForbiddenException.java new file mode 100644 index 0000000000..1d4aff2ebf --- /dev/null +++ b/spring-rest/src/main/java/org/baeldung/web/controller/status/ForbiddenException.java @@ -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 { + +} diff --git a/spring-rest/src/main/java/org/baeldung/web/dto/Company.java b/spring-rest/src/main/java/org/baeldung/web/dto/Company.java new file mode 100644 index 0000000000..c7d0718140 --- /dev/null +++ b/spring-rest/src/main/java/org/baeldung/web/dto/Company.java @@ -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 + "]"; + } + +} diff --git a/spring-rest/src/main/java/org/baeldung/web/dto/Foo.java b/spring-rest/src/main/java/org/baeldung/web/dto/Foo.java new file mode 100644 index 0000000000..774d547464 --- /dev/null +++ b/spring-rest/src/main/java/org/baeldung/web/dto/Foo.java @@ -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; + } + +} \ No newline at end of file diff --git a/spring-rest/src/main/java/org/baeldung/web/dto/FooProtos.java b/spring-rest/src/main/java/org/baeldung/web/dto/FooProtos.java new file mode 100644 index 0000000000..61251ea33a --- /dev/null +++ b/spring-rest/src/main/java/org/baeldung/web/dto/FooProtos.java @@ -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 { + + /** + * required int64 id = 1; + */ + boolean hasId(); + /** + * required int64 id = 1; + */ + long getId(); + + /** + * required string name = 2; + */ + boolean hasName(); + /** + * required string name = 2; + */ + java.lang.String getName(); + /** + * required string name = 2; + */ + 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 PARSER = + new com.google.protobuf.AbstractParser() { + 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 getParserForType() { + return PARSER; + } + + private int bitField0_; + public static final int ID_FIELD_NUMBER = 1; + private long id_; + /** + * required int64 id = 1; + */ + public boolean hasId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required int64 id = 1; + */ + public long getId() { + return id_; + } + + public static final int NAME_FIELD_NUMBER = 2; + private java.lang.Object name_; + /** + * required string name = 2; + */ + public boolean hasName() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string name = 2; + */ + 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; + } + } + /** + * required string name = 2; + */ + 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 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_ ; + /** + * required int64 id = 1; + */ + public boolean hasId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required int64 id = 1; + */ + public long getId() { + return id_; + } + /** + * required int64 id = 1; + */ + public Builder setId(long value) { + bitField0_ |= 0x00000001; + id_ = value; + onChanged(); + return this; + } + /** + * required int64 id = 1; + */ + public Builder clearId() { + bitField0_ = (bitField0_ & ~0x00000001); + id_ = 0L; + onChanged(); + return this; + } + + private java.lang.Object name_ = ""; + /** + * required string name = 2; + */ + public boolean hasName() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string name = 2; + */ + 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; + } + } + /** + * required string name = 2; + */ + 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; + } + } + /** + * required string name = 2; + */ + public Builder setName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + name_ = value; + onChanged(); + return this; + } + /** + * required string name = 2; + */ + public Builder clearName() { + bitField0_ = (bitField0_ & ~0x00000002); + name_ = getDefaultInstance().getName(); + onChanged(); + return this; + } + /** + * required string name = 2; + */ + 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) +} diff --git a/spring-rest/src/main/java/org/baeldung/web/dto/Item.java b/spring-rest/src/main/java/org/baeldung/web/dto/Item.java new file mode 100644 index 0000000000..536c72020f --- /dev/null +++ b/spring-rest/src/main/java/org/baeldung/web/dto/Item.java @@ -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; + } +} \ No newline at end of file diff --git a/spring-rest/src/main/java/org/baeldung/web/dto/ItemManager.java b/spring-rest/src/main/java/org/baeldung/web/dto/ItemManager.java new file mode 100644 index 0000000000..74ffada300 --- /dev/null +++ b/spring-rest/src/main/java/org/baeldung/web/dto/ItemManager.java @@ -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; + } +} diff --git a/spring-rest/src/main/java/org/baeldung/web/dto/Views.java b/spring-rest/src/main/java/org/baeldung/web/dto/Views.java new file mode 100644 index 0000000000..6231e12bcc --- /dev/null +++ b/spring-rest/src/main/java/org/baeldung/web/dto/Views.java @@ -0,0 +1,9 @@ +package org.baeldung.web.dto; + +public class Views { + public static class Public { + } + + public static class Internal extends Public { + } +} diff --git a/spring-rest/src/main/resources/logback.xml b/spring-rest/src/main/resources/logback.xml new file mode 100644 index 0000000000..1146dade63 --- /dev/null +++ b/spring-rest/src/main/resources/logback.xml @@ -0,0 +1,20 @@ + + + + + web - %date [%thread] %-5level %logger{36} - %message%n + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-rest/src/main/webapp/WEB-INF/api-servlet.xml b/spring-rest/src/main/webapp/WEB-INF/api-servlet.xml new file mode 100644 index 0000000000..5afc637ece --- /dev/null +++ b/spring-rest/src/main/webapp/WEB-INF/api-servlet.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + /WEB-INF/spring-views.xml + + + + + + + + + + + + + + + + + diff --git a/spring-rest/src/main/webapp/WEB-INF/company.html b/spring-rest/src/main/webapp/WEB-INF/company.html new file mode 100644 index 0000000000..d2072bfd3c --- /dev/null +++ b/spring-rest/src/main/webapp/WEB-INF/company.html @@ -0,0 +1,44 @@ + + + + + Company Data + + + + + + + +
+ + + \ No newline at end of file diff --git a/spring-rest/src/main/webapp/WEB-INF/spring-views.xml b/spring-rest/src/main/webapp/WEB-INF/spring-views.xml new file mode 100644 index 0000000000..2944828d6d --- /dev/null +++ b/spring-rest/src/main/webapp/WEB-INF/spring-views.xml @@ -0,0 +1,10 @@ + + + + + + + \ No newline at end of file diff --git a/spring-rest/src/main/webapp/WEB-INF/web.xml b/spring-rest/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..01e7620c44 --- /dev/null +++ b/spring-rest/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,41 @@ + + + + Spring MVC Application + + + + contextClass + + org.springframework.web.context.support.AnnotationConfigWebApplicationContext + + + + contextConfigLocation + org.baeldung.config + + + + org.springframework.web.context.ContextLoaderListener + + + + + api + org.springframework.web.servlet.DispatcherServlet + 1 + + + api + / + + + + + + + diff --git a/spring-rest/src/test/java/org/baeldung/web/controller/redirect/RedirectControllerTest.java b/spring-rest/src/test/java/org/baeldung/web/controller/redirect/RedirectControllerTest.java new file mode 100644 index 0000000000..cafaff7b07 --- /dev/null +++ b/spring-rest/src/test/java/org/baeldung/web/controller/redirect/RedirectControllerTest.java @@ -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")); + } + +} diff --git a/spring-rest/src/test/java/org/baeldung/web/controller/status/ExampleControllerTest.java b/spring-rest/src/test/java/org/baeldung/web/controller/status/ExampleControllerTest.java new file mode 100644 index 0000000000..1344d2d40e --- /dev/null +++ b/spring-rest/src/test/java/org/baeldung/web/controller/status/ExampleControllerTest.java @@ -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()); + } +} diff --git a/spring-rest/src/test/java/org/baeldung/web/test/SpringHttpMessageConvertersIntegrationTestsCase.java b/spring-rest/src/test/java/org/baeldung/web/test/SpringHttpMessageConvertersIntegrationTestsCase.java new file mode 100644 index 0000000000..1536f14bc8 --- /dev/null +++ b/spring-rest/src/test/java/org/baeldung/web/test/SpringHttpMessageConvertersIntegrationTestsCase.java @@ -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 entity = new HttpEntity(headers); + + final ResponseEntity 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 entity = new HttpEntity(headers); + + final ResponseEntity 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 entity = new HttpEntity(resource, headers); + + final ResponseEntity 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 entity = new HttpEntity(headers); + + final ResponseEntity 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 entity = new HttpEntity(headers); + + final ResponseEntity response = restTemplate.exchange(URI, HttpMethod.GET, entity, Foo.class, "1"); + final Foo resource = response.getBody(); + + assertThat(resource, notNullValue()); + } + + // UTIL + + private List> getMessageConverters() { + final List> converters = new ArrayList>(); + + 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; + } + +} diff --git a/spring-rest/src/test/resources/.gitignore b/spring-rest/src/test/resources/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/spring-rest/src/test/resources/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file