diff --git a/core-java/src/main/java/com/baeldung/hexToAscii/HexToAscii.java b/core-java/src/main/java/com/baeldung/hexToAscii/HexToAscii.java new file mode 100644 index 0000000000..2a3c4b109e --- /dev/null +++ b/core-java/src/main/java/com/baeldung/hexToAscii/HexToAscii.java @@ -0,0 +1,46 @@ +package com.baeldung.hexToAscii; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class HexToAscii { + + @Test + public static void whenHexToAscii() { + String asciiString = "http://www.baeldung.com/jackson-serialize-dates"; + String hexEquivalent = "687474703a2f2f7777772e6261656c64756e672e636f6d2f6a61636b736f6e2d73657269616c697a652d6461746573"; + + assertEquals(asciiString, hexToAscii(hexEquivalent)); + } + + @Test + public static void whenAsciiToHex() { + String asciiString = "http://www.baeldung.com/jackson-serialize-dates"; + String hexEquivalent = "687474703a2f2f7777772e6261656c64756e672e636f6d2f6a61636b736f6e2d73657269616c697a652d6461746573"; + + assertEquals(hexEquivalent, asciiToHex(asciiString)); + } + + // + + private static String asciiToHex(String asciiStr) { + char[] chars = asciiStr.toCharArray(); + StringBuilder hex = new StringBuilder(); + for (char ch : chars) { + hex.append(Integer.toHexString((int) ch)); + } + + return hex.toString(); + } + + private static String hexToAscii(String hexStr) { + StringBuilder output = new StringBuilder(""); + for (int i = 0; i < hexStr.length(); i += 2) { + String str = hexStr.substring(i, i + 2); + output.append((char) Integer.parseInt(str, 16)); + } + return output.toString(); + } + +} diff --git a/core-java/src/main/java/com/baeldung/java/nio/selector/EchoClient.java b/core-java/src/main/java/com/baeldung/java/nio/selector/EchoClient.java index 1c034051aa..61f339db58 100644 --- a/core-java/src/main/java/com/baeldung/java/nio/selector/EchoClient.java +++ b/core-java/src/main/java/com/baeldung/java/nio/selector/EchoClient.java @@ -17,6 +17,11 @@ public class EchoClient { return instance; } + public static void stop() throws IOException { + client.close(); + buffer = null; + } + private EchoClient() { try { client = SocketChannel.open(new InetSocketAddress("localhost", 5454)); @@ -42,5 +47,4 @@ public class EchoClient { return response; } - } diff --git a/core-java/src/main/java/com/baeldung/java/nio/selector/EchoServer.java b/core-java/src/main/java/com/baeldung/java/nio/selector/EchoServer.java index 1d4e01bbc3..2ed9a27c4c 100644 --- a/core-java/src/main/java/com/baeldung/java/nio/selector/EchoServer.java +++ b/core-java/src/main/java/com/baeldung/java/nio/selector/EchoServer.java @@ -1,21 +1,19 @@ package com.baeldung.java.nio.selector; +import java.io.File; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; -import java.nio.channels.Selector; -import java.nio.channels.SelectionKey; -import java.nio.ByteBuffer; -import java.io.IOException; -import java.util.Set; import java.util.Iterator; -import java.net.InetSocketAddress; -import java.io.File; +import java.util.Set; public class EchoServer { - public static void main(String[] args) - - throws IOException { + public static void main(String[] args) throws IOException { Selector selector = Selector.open(); ServerSocketChannel serverSocket = ServerSocketChannel.open(); serverSocket.bind(new InetSocketAddress("localhost", 5454)); @@ -49,7 +47,6 @@ public class EchoServer { } } - public static Process start() throws IOException, InterruptedException { String javaHome = System.getProperty("java.home"); String javaBin = javaHome + File.separator + "bin" + File.separator + "java"; diff --git a/core-java/src/test/java/com/baeldung/java/nio/selector/NioEchoIntegrationTest.java b/core-java/src/test/java/com/baeldung/java/nio/selector/NioEchoIntegrationTest.java index 748dc5b9f4..fc64799578 100644 --- a/core-java/src/test/java/com/baeldung/java/nio/selector/NioEchoIntegrationTest.java +++ b/core-java/src/test/java/com/baeldung/java/nio/selector/NioEchoIntegrationTest.java @@ -4,19 +4,32 @@ import static org.junit.Assert.assertEquals; import java.io.IOException; +import org.junit.After; +import org.junit.Before; import org.junit.Test; public class NioEchoIntegrationTest { + Process server; + EchoClient client; + + @Before + public void setup() throws IOException, InterruptedException { + server = EchoServer.start(); + client = EchoClient.start(); + } + @Test - public void givenClient_whenServerEchosMessage_thenCorrect() throws IOException, InterruptedException { - Process process = EchoServer.start(); - EchoClient client = EchoClient.start(); + public void givenServerClient_whenServerEchosMessage_thenCorrect() { String resp1 = client.sendMessage("hello"); String resp2 = client.sendMessage("world"); assertEquals("hello", resp1); assertEquals("world", resp2); + } - process.destroy(); + @After + public void teardown() throws IOException { + server.destroy(); + EchoClient.stop(); } } diff --git a/enterprise-patterns/pom.xml b/enterprise-patterns/pom.xml new file mode 100644 index 0000000000..036a61c44a --- /dev/null +++ b/enterprise-patterns/pom.xml @@ -0,0 +1,35 @@ + + + 4.0.0 + + com.baeldung.enterprise.patterns + enterprise-patterns-parent + pom + + spring-dispatcher-servlet + + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + 1.8 + 1.8 + + + + + + diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/LoginCommand.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/LoginCommand.java index cbc8ad9498..46a0329112 100644 --- a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/LoginCommand.java +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/LoginCommand.java @@ -3,6 +3,7 @@ package com.baeldung.patterns.intercepting.filter.commands; import javax.servlet.ServletException; import javax.servlet.http.HttpSession; import java.io.IOException; +import java.util.Optional; public class LoginCommand extends FrontCommand { @Override @@ -12,10 +13,8 @@ public class LoginCommand extends FrontCommand { session.setAttribute("username", request.getParameter("username")); response.sendRedirect(request.getParameter("redirect")); } else { - String queryString = request.getQueryString(); - if (queryString == null) { - queryString = "command=Home"; - } + String queryString = Optional.ofNullable(request.getQueryString()) + .orElse("command=Home"); request.setAttribute("redirect", request.getRequestURL() .append("?").append(queryString).toString()); forward("login"); diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/LogoutCommand.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/LogoutCommand.java index 3c9475d6af..f309dc5cf3 100644 --- a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/LogoutCommand.java +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/LogoutCommand.java @@ -3,14 +3,17 @@ package com.baeldung.patterns.intercepting.filter.commands; import javax.servlet.ServletException; import javax.servlet.http.HttpSession; import java.io.IOException; +import java.util.Optional; public class LogoutCommand extends FrontCommand { @Override public void process() throws ServletException, IOException { super.process(); - HttpSession session = request.getSession(false); - session.removeAttribute("username"); - session.removeAttribute("order"); + Optional.ofNullable(request.getSession(false)) + .ifPresent(session -> { + session.removeAttribute("username"); + session.removeAttribute("order"); + }); response.sendRedirect("/?command=Home"); } } diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/OrderCommand.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/OrderCommand.java index e53fcf78dd..a57785669b 100644 --- a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/OrderCommand.java +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/OrderCommand.java @@ -8,6 +8,7 @@ import com.baeldung.patterns.intercepting.filter.data.OrderImpl; import javax.servlet.ServletException; import javax.servlet.http.HttpSession; import java.io.IOException; +import java.util.Optional; public class OrderCommand extends FrontCommand { @Override @@ -15,11 +16,10 @@ public class OrderCommand extends FrontCommand { super.process(); if (request.getMethod().equals("POST")) { HttpSession session = request.getSession(false); - Order order = (Order) session.getAttribute("order"); - if (order == null) { - String username = (String) session.getAttribute("username"); - order = new OrderImpl(username); - } + Order order = Optional + .ofNullable(session.getAttribute("order")) + .map(Order.class::cast) + .orElseGet(() -> new OrderImpl((String) session.getAttribute("username"))); Bookshelf bookshelf = (Bookshelf) request.getServletContext() .getAttribute("bookshelf"); String isbn = request.getParameter("isbn"); diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/EncodingFilter.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/EncodingFilter.java index ef3f95382e..0806aecba3 100644 --- a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/EncodingFilter.java +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/EncodingFilter.java @@ -4,6 +4,7 @@ import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.annotation.WebInitParam; import java.io.IOException; +import java.util.Optional; @WebFilter( servletNames = {"intercepting-filter"}, @@ -24,10 +25,9 @@ public class EncodingFilter extends BaseFilter { ServletResponse response, FilterChain chain ) throws IOException, ServletException { - String encoding = request.getParameter("encoding"); - if (encoding == null) { - encoding = this.encoding; - } + String encoding = Optional + .ofNullable(request.getParameter("encoding")) + .orElse(this.encoding); response.setCharacterEncoding(encoding); chain.doFilter(request, response); } diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/LoggingFilter.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/LoggingFilter.java index 0ebb397938..322592f84e 100644 --- a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/LoggingFilter.java +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/LoggingFilter.java @@ -10,6 +10,7 @@ import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import java.io.IOException; +import java.util.Optional; @WebFilter(servletNames = "intercepting-filter") public class LoggingFilter extends BaseFilter { @@ -23,10 +24,10 @@ public class LoggingFilter extends BaseFilter { ) throws IOException, ServletException { chain.doFilter(request, response); HttpServletRequest httpServletRequest = (HttpServletRequest) request; - String username = (String) httpServletRequest.getAttribute("username"); - if (username == null) { - username = "guest"; - } + String username = Optional + .ofNullable(httpServletRequest.getAttribute("username")) + .map(Object::toString) + .orElse("guest"); log.info("Request from '{}@{}': {}?{}", username, request.getRemoteAddr(), httpServletRequest.getRequestURI(), request.getParameterMap()); } diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/VisitorCounterFilter.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/VisitorCounterFilter.java index 5521b9faee..42551310d3 100644 --- a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/VisitorCounterFilter.java +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/VisitorCounterFilter.java @@ -5,6 +5,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.io.IOException; import java.util.HashSet; +import java.util.Optional; import java.util.Set; public class VisitorCounterFilter implements Filter { @@ -21,8 +22,9 @@ public class VisitorCounterFilter implements Filter { FilterChain chain ) throws IOException, ServletException { HttpSession session = ((HttpServletRequest) request).getSession(false); - String username = (String) session.getAttribute("username"); - users.add(username); + Optional.ofNullable(session.getAttribute("username")) + .map(Object::toString) + .ifPresent(users::add); request.setAttribute("counter", users.size()); chain.doFilter(request, response); } diff --git a/pom.xml b/pom.xml index ef24531698..d8830e2a59 100644 --- a/pom.xml +++ b/pom.xml @@ -95,6 +95,7 @@ spring-data-neo4j spring-data-redis spring-data-rest + spring-dispatcher-servlet spring-exceptions spring-freemarker spring-hibernate3 diff --git a/spring-dispatcher-servlet/pom.xml b/spring-dispatcher-servlet/pom.xml new file mode 100644 index 0000000000..646db663db --- /dev/null +++ b/spring-dispatcher-servlet/pom.xml @@ -0,0 +1,82 @@ + + + 4.0.0 + + spring-dispatcher-servlet + war + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + .. + + + + + javax.servlet + javax.servlet-api + 3.1.0 + provided + + + org.springframework + spring-webmvc + 4.3.3.RELEASE + + + org.thymeleaf + thymeleaf-spring4 + 3.0.2.RELEASE + + + org.slf4j + slf4j-api + 1.7.21 + + + org.apache.logging.log4j + log4j-core + 2.7 + + + org.apache.logging.log4j + log4j-slf4j-impl + 2.7 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-war-plugin + 3.0.0 + + false + + + + org.eclipse.jetty + jetty-maven-plugin + 9.3.12.v20160915 + + + / + + + + + + diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/RootConfiguration.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/RootConfiguration.java new file mode 100644 index 0000000000..48281c5e5d --- /dev/null +++ b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/RootConfiguration.java @@ -0,0 +1,19 @@ +package com.baeldung.spring.dispatcher.servlet; + +import com.baeldung.spring.dispatcher.servlet.models.Task; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.*; + +@Configuration +public class RootConfiguration { + @Bean + public Map> taskList() { + Map> taskMap = new HashMap<>(); + List taskList = new ArrayList<>(); + taskList.add(new Task("Clean the dishes!", new Date())); + taskMap.put("Cid", taskList); + return taskMap; + } +} diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/WebApplicationInitializer.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/WebApplicationInitializer.java new file mode 100644 index 0000000000..016e4a8b4c --- /dev/null +++ b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/WebApplicationInitializer.java @@ -0,0 +1,30 @@ +package com.baeldung.spring.dispatcher.servlet; + +import org.springframework.web.context.ContextLoaderListener; +import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; +import org.springframework.web.servlet.DispatcherServlet; + +import javax.servlet.MultipartConfigElement; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRegistration; + +public class WebApplicationInitializer implements org.springframework.web.WebApplicationInitializer { + @Override + public void onStartup(ServletContext servletContext) throws ServletException { + AnnotationConfigWebApplicationContext rootContext = + new AnnotationConfigWebApplicationContext(); + rootContext.register(RootConfiguration.class); + servletContext.addListener(new ContextLoaderListener(rootContext)); + AnnotationConfigWebApplicationContext webContext = + new AnnotationConfigWebApplicationContext(); + webContext.register(WebConfiguration.class); + DispatcherServlet dispatcherServlet = new DispatcherServlet(webContext); + ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcher", + dispatcherServlet); + servlet.addMapping("/*"); + MultipartConfigElement multipartConfigElement = + new MultipartConfigElement("/tmp"); + servlet.setMultipartConfig(multipartConfigElement); + } +} diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/WebConfiguration.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/WebConfiguration.java new file mode 100644 index 0000000000..419c1a2908 --- /dev/null +++ b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/WebConfiguration.java @@ -0,0 +1,129 @@ +package com.baeldung.spring.dispatcher.servlet; + +import org.springframework.context.MessageSource; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.ResourceBundleMessageSource; +import org.springframework.ui.context.support.ResourceBundleThemeSource; +import org.springframework.web.multipart.MultipartResolver; +import org.springframework.web.multipart.support.StandardServletMultipartResolver; +import org.springframework.web.servlet.HandlerExceptionResolver; +import org.springframework.web.servlet.LocaleResolver; +import org.springframework.web.servlet.ThemeResolver; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.i18n.CookieLocaleResolver; +import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; +import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver; +import org.springframework.web.servlet.theme.CookieThemeResolver; +import org.springframework.web.servlet.theme.ThemeChangeInterceptor; +import org.thymeleaf.spring4.SpringTemplateEngine; +import org.thymeleaf.spring4.view.ThymeleafViewResolver; +import org.thymeleaf.templatemode.TemplateMode; +import org.thymeleaf.templateresolver.ServletContextTemplateResolver; + +import javax.servlet.ServletContext; +import java.util.Locale; + +@Configuration +@ComponentScan("com.baeldung.spring.dispatcher.servlet.web") +@EnableWebMvc +public class WebConfiguration extends WebMvcConfigurerAdapter { + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry + .addResourceHandler("/public/**") + .addResourceLocations("/public/"); + } + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(localeChangeInterceptor()); + registry.addInterceptor(themeChangeInterceptor()); + } + + @Bean + public ServletContextTemplateResolver templateResolver(ServletContext servletContext) { + ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(servletContext); + templateResolver.setPrefix("/WEB-INF/views/"); + templateResolver.setSuffix(".html"); + templateResolver.setTemplateMode(TemplateMode.HTML); + return templateResolver; + } + + @Bean + public SpringTemplateEngine templateEngine(ServletContextTemplateResolver templateResolver) { + SpringTemplateEngine templateEngine = new SpringTemplateEngine(); + templateEngine.setTemplateResolver(templateResolver); + return templateEngine; + } + + @Bean + public ThymeleafViewResolver viewResolver(SpringTemplateEngine templateEngine) { + ThymeleafViewResolver viewResolver = new ThymeleafViewResolver(); + viewResolver.setTemplateEngine(templateEngine); + return viewResolver; + } + + @Bean + public MessageSource messageSource() { + ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); + messageSource.setBasename("messages"); + messageSource.setFallbackToSystemLocale(false); + return messageSource; + } + + @Bean + public LocaleResolver localeResolver() { + CookieLocaleResolver localeResolver = new CookieLocaleResolver(); + localeResolver.setDefaultLocale(Locale.ENGLISH); + localeResolver.setCookieName("locale"); + localeResolver.setCookieMaxAge(-1); + return localeResolver; + } + + @Bean + public LocaleChangeInterceptor localeChangeInterceptor() { + LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor(); + localeChangeInterceptor.setParamName("lang"); + localeChangeInterceptor.setIgnoreInvalidLocale(true); + return localeChangeInterceptor; + } + + @Bean + public ResourceBundleThemeSource themeSource() { + ResourceBundleThemeSource themeSource = new ResourceBundleThemeSource(); + themeSource.setBasenamePrefix("theme-"); + themeSource.setFallbackToSystemLocale(false); + return themeSource; + } + + @Bean + public ThemeResolver themeResolver() { + CookieThemeResolver themeResolver = new CookieThemeResolver(); + themeResolver.setDefaultThemeName("robotask"); + themeResolver.setCookieName("theme"); + themeResolver.setCookieMaxAge(-1); + return themeResolver; + } + + @Bean + public ThemeChangeInterceptor themeChangeInterceptor() { + ThemeChangeInterceptor themeChangeInterceptor = new ThemeChangeInterceptor(); + themeChangeInterceptor.setParamName("theme"); + return themeChangeInterceptor; + } + + @Bean + public MultipartResolver multipartResolver() { + return new StandardServletMultipartResolver(); + } + + @Bean + public HandlerExceptionResolver handlerExceptionResolver() { + return new ExceptionHandlerExceptionResolver(); + } +} diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/models/Attachment.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/models/Attachment.java new file mode 100644 index 0000000000..1d6248650f --- /dev/null +++ b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/models/Attachment.java @@ -0,0 +1,58 @@ +package com.baeldung.spring.dispatcher.servlet.models; + +import java.util.UUID; + +public class Attachment { + private String id; + + private String name; + + private String description; + + public Attachment() { + this.id = UUID.randomUUID().toString(); + } + + public Attachment(String name, String description) { + this(); + this.name = name; + this.description = description; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Attachment that = (Attachment) o; + return id.equals(that.id); + } + + @Override + public int hashCode() { + return id.hashCode(); + } +} diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/models/Task.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/models/Task.java new file mode 100644 index 0000000000..1e6a533e3a --- /dev/null +++ b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/models/Task.java @@ -0,0 +1,52 @@ +package com.baeldung.spring.dispatcher.servlet.models; + +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +public class Task { + private String description; + + @DateTimeFormat(pattern = "yyyy-MM-dd'T'hh:mm") + private Date due; + + private Set attachments = new HashSet<>(); + + public Task() { + } + + public Task(Date due) { + this.due = due; + } + + public Task(String description, Date due) { + this.description = description; + this.due = due; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Date getDue() { + return due; + } + + public void setDue(Date due) { + this.due = due; + } + + public Set getAttachments() { + return attachments; + } + + public void setAttachments(Set attachments) { + this.attachments = attachments; + } +} diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/AttachmentController.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/AttachmentController.java new file mode 100644 index 0000000000..2521004ff1 --- /dev/null +++ b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/AttachmentController.java @@ -0,0 +1,17 @@ +package com.baeldung.spring.dispatcher.servlet.web; + +import org.springframework.core.io.FileSystemResource; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; + +@RequestMapping("/attachments") +public interface AttachmentController { + @GetMapping("/{attachmentId}") + ResponseEntity getAttachment( + @PathVariable("attachmentId") String attachmentId, + @RequestParam(name = "download", required = false, defaultValue = "false") boolean forcedDownload + ); +} diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/AttachmentControllerImpl.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/AttachmentControllerImpl.java new file mode 100644 index 0000000000..75a15cf657 --- /dev/null +++ b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/AttachmentControllerImpl.java @@ -0,0 +1,45 @@ +package com.baeldung.spring.dispatcher.servlet.web; + +import com.baeldung.spring.dispatcher.servlet.models.Task; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.FileSystemResource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; + +import java.net.URLConnection; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +@Controller +public class AttachmentControllerImpl implements AttachmentController { + @Autowired + private Map> taskMap; + + @Override + public ResponseEntity getAttachment( + @PathVariable("attachmentId") String attachmentId, + @RequestParam(name = "download", required = false, defaultValue = "false") boolean forcedDownload + ) { + FileSystemResource resource = new FileSystemResource("/tmp/" + attachmentId); + HttpHeaders headers = new HttpHeaders(); + taskMap.values().stream() + .flatMap(Collection::stream) + .flatMap(t -> t.getAttachments().stream()) + .filter(a -> a.getId().equals(attachmentId)) + .findFirst() + .ifPresent(a -> { + headers.add("Content-Disposition", + "attachment; filename=" + a.getName()); + headers.add("Content-Type", forcedDownload ? + MediaType.APPLICATION_OCTET_STREAM_VALUE : + URLConnection.guessContentTypeFromName(a.getName())); + }); + return new ResponseEntity<>(resource, headers, HttpStatus.OK); + } +} diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/GlobalDefaultExceptionHandler.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/GlobalDefaultExceptionHandler.java new file mode 100644 index 0000000000..f25eb601a7 --- /dev/null +++ b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/GlobalDefaultExceptionHandler.java @@ -0,0 +1,19 @@ +package com.baeldung.spring.dispatcher.servlet.web; + +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; + +@ControllerAdvice +public class GlobalDefaultExceptionHandler { + @ExceptionHandler(Exception.class) + public ModelAndView defaultErrorHandler(HttpServletRequest request, Exception e) throws Exception { + ModelAndView modelAndView = new ModelAndView(); + modelAndView.addObject("exception", e); + modelAndView.addObject("url", request.getRequestURL()); + modelAndView.setViewName("error"); + return modelAndView; + } +} diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/HomeController.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/HomeController.java new file mode 100644 index 0000000000..5ac39fadb4 --- /dev/null +++ b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/HomeController.java @@ -0,0 +1,13 @@ +package com.baeldung.spring.dispatcher.servlet.web; + +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +@RequestMapping("/") +public interface HomeController { + @GetMapping("/*") + String home( + Model model + ); +} diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/HomeControllerImpl.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/HomeControllerImpl.java new file mode 100644 index 0000000000..66d869ca67 --- /dev/null +++ b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/HomeControllerImpl.java @@ -0,0 +1,25 @@ +package com.baeldung.spring.dispatcher.servlet.web; + +import com.baeldung.spring.dispatcher.servlet.models.Task; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Controller +public class HomeControllerImpl implements HomeController { + @Autowired + private Map> taskMap; + + @Override + public String home(Model model) { + List users = taskMap.keySet().stream() + .sorted() + .collect(Collectors.toList()); + model.addAttribute("users", users); + return "home"; + } +} diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/TaskController.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/TaskController.java new file mode 100644 index 0000000000..eff93ffb2f --- /dev/null +++ b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/TaskController.java @@ -0,0 +1,49 @@ +package com.baeldung.spring.dispatcher.servlet.web; + +import com.baeldung.spring.dispatcher.servlet.models.Task; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +@RequestMapping("/tasks") +public interface TaskController { + @GetMapping("/{username}/list") + String listTasks( + @PathVariable("username") String username, + Model model + ); + + @GetMapping("/{username}/add") + String addTask( + @PathVariable("username") String username, + Model model + ); + + @PostMapping("/{username}/add") + String addTask( + @PathVariable("username") String username, + @ModelAttribute Task task + ); + + @GetMapping("/{username}/get/{id}") + String getTask( + @PathVariable("username") String username, + @PathVariable("id") int id, + Model model + ); + + @GetMapping("/{username}/get/{id}/attach") + String attachToTask( + @PathVariable("username") String username, + @PathVariable("id") int id, + Model model + ); + + @PostMapping("/{username}/get/{id}/attach") + String attachToTask( + @PathVariable("username") String username, + @PathVariable("id") int id, + @RequestParam("attachment") MultipartFile attachment, + @RequestParam("description") String description + ); +} diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/TaskControllerImpl.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/TaskControllerImpl.java new file mode 100644 index 0000000000..464e58aa54 --- /dev/null +++ b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/TaskControllerImpl.java @@ -0,0 +1,111 @@ +package com.baeldung.spring.dispatcher.servlet.web; + +import com.baeldung.spring.dispatcher.servlet.models.Attachment; +import com.baeldung.spring.dispatcher.servlet.models.Task; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.*; +import java.util.stream.Collectors; + +@Controller +public class TaskControllerImpl implements TaskController { + @Autowired + private Map> taskMap; + + @Override + public String listTasks( + @PathVariable("username") String username, + Model model + ) { + List tasks = taskMap.get(username).stream() + .sorted(Comparator.comparing(Task::getDue)) + .collect(Collectors.toList()); + model.addAttribute("username", username); + model.addAttribute("tasks", tasks); + return "task-list"; + } + + @Override + public String addTask( + @PathVariable("username") String username, + Model model + ) { + model.addAttribute("username", username); + model.addAttribute("task", new Task(new Date())); + return "task-add"; + } + + @Override + public String addTask( + @PathVariable("username") String username, + @ModelAttribute Task task + ) { + List taskList = taskMap.get(username); + if (taskList == null) { + taskList = new ArrayList<>(); + } + taskList.add(task); + taskMap.put(username, taskList); + return "redirect:list"; + } + + @Override + public String getTask( + @PathVariable("username") String username, + @PathVariable("id") int id, + Model model + ) { + Task task = taskMap.get(username).get(id); + model.addAttribute("username", username); + model.addAttribute("id", id); + model.addAttribute("task", task); + return "task-get"; + } + + @Override + public String attachToTask( + @PathVariable("username") String username, + @PathVariable("id") int id, + Model model + ) { + model.addAttribute("username", username); + model.addAttribute("id", id); + return "task-attach"; + } + + @Override + public String attachToTask( + @PathVariable("username") String username, + @PathVariable("id") int id, + @RequestParam("attachment") MultipartFile multipartFile, + @RequestParam("description") String description + ) { + Task task = taskMap.get(username).get(id); + Attachment attachment = new Attachment(multipartFile.getOriginalFilename(), + description); + task.getAttachments().add(attachment); + try (InputStream inputStream = + new BufferedInputStream(multipartFile.getInputStream()); + OutputStream outputStream = + new BufferedOutputStream(Files.newOutputStream( + Paths.get("/tmp", attachment.getId())))) { + byte[] buf = new byte[1024 * 16]; + int len; + while ((len = inputStream.read(buf)) != -1) { + outputStream.write(buf, 0, len); + } + } catch (IOException e) { + throw new RuntimeException("Failed to upload file!", e); + } + return "redirect:./"; + } +} diff --git a/spring-dispatcher-servlet/src/main/resources/log4j2.xml b/spring-dispatcher-servlet/src/main/resources/log4j2.xml new file mode 100644 index 0000000000..fb18e8279a --- /dev/null +++ b/spring-dispatcher-servlet/src/main/resources/log4j2.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/spring-dispatcher-servlet/src/main/resources/messages.properties b/spring-dispatcher-servlet/src/main/resources/messages.properties new file mode 100644 index 0000000000..c36eb5aa42 --- /dev/null +++ b/spring-dispatcher-servlet/src/main/resources/messages.properties @@ -0,0 +1,22 @@ +home.title=Welcome to TaskTools! +task.add.description=description +task.add.due=due +task.add.header=Adding a task to {0}''s list: +task.add.submit=Submit +task.add.title={0}: task add +task.attach.attachment=attached file +task.attach.description=description +task.attach.header=task #{0}: attach file +task.attach.submit=Submit +task.attach.title=#{0}: Attach file +task.get.attach=Attach file +task.get.attachments=attachments: +task.get.download=Download +task.get.header=task #{0}: +task.get.list=Back +task.get.title={0}: task details +task.list.add-new=Add new +task.list.details=Details +task.list.header={0}''s tasks: +task.list.home=Home +task.list.title={0}: task list diff --git a/spring-dispatcher-servlet/src/main/resources/messages_de.properties b/spring-dispatcher-servlet/src/main/resources/messages_de.properties new file mode 100644 index 0000000000..184b72101c --- /dev/null +++ b/spring-dispatcher-servlet/src/main/resources/messages_de.properties @@ -0,0 +1,22 @@ +home.title=Willkommen bei TaskTools! +task.add.description=Beschreibung +task.add.due=f\u00e4llig +task.add.header=F\u00fcge eine Aufgabe zu {0}''s Liste hinzu: +task.add.submit=Senden +task.add.title={0}: Task hinzuf\u00fcgen +task.attach.attachment=Angeh\u00e4ngte Datei +task.attach.description=Beschreibung +task.attach.header=Task #{0}: Datei anh\u00e4ngen +task.attach.submit=Senden +task.attach.title=#{0}: Datei anh\u00e4ngen +task.get.attach=Datei anh\u00e4ngen +task.get.attachments=Anh\u00e4nge: +task.get.download=Download +task.get.header=Task #{0}: +task.get.list=Zur\u00fcck +task.get.title={0}: Task Details +task.list.add-new=Neuer Task +task.list.details=Details +task.list.header={0}''s Tasks: +task.list.home=Startseite +task.list.title={0}: Task Liste diff --git a/spring-dispatcher-servlet/src/main/resources/theme-post_it.properties b/spring-dispatcher-servlet/src/main/resources/theme-post_it.properties new file mode 100644 index 0000000000..d2998e2bdf --- /dev/null +++ b/spring-dispatcher-servlet/src/main/resources/theme-post_it.properties @@ -0,0 +1 @@ +stylesheet=/public/css/themes/post_it.css diff --git a/spring-dispatcher-servlet/src/main/resources/theme-robotask.properties b/spring-dispatcher-servlet/src/main/resources/theme-robotask.properties new file mode 100644 index 0000000000..68fe270b64 --- /dev/null +++ b/spring-dispatcher-servlet/src/main/resources/theme-robotask.properties @@ -0,0 +1 @@ +stylesheet=/public/css/themes/robotask.css diff --git a/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/error.html b/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/error.html new file mode 100644 index 0000000000..8f0f6afca7 --- /dev/null +++ b/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/error.html @@ -0,0 +1,13 @@ + + + + Error + + + + +

Error:

+

+

+ + diff --git a/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/home.html b/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/home.html new file mode 100644 index 0000000000..6adec7bb12 --- /dev/null +++ b/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/home.html @@ -0,0 +1,16 @@ + + + + + + + + +

TaskTools

+
    +
  • + +
  • +
+ + diff --git a/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/task-add.html b/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/task-add.html new file mode 100644 index 0000000000..520486f52e --- /dev/null +++ b/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/task-add.html @@ -0,0 +1,16 @@ + + + + + + + + +

+
+ + + +
+ + diff --git a/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/task-attach.html b/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/task-attach.html new file mode 100644 index 0000000000..23246f330b --- /dev/null +++ b/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/task-attach.html @@ -0,0 +1,17 @@ + + + + + + + + +

+
+ + + +
+ + diff --git a/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/task-get.html b/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/task-get.html new file mode 100644 index 0000000000..e7b35b6780 --- /dev/null +++ b/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/task-get.html @@ -0,0 +1,28 @@ + + + + + + + + +

+

+

+
+

+
+
+
+ + +
+
+
+

+ + +

+ + diff --git a/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/task-list.html b/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/task-list.html new file mode 100644 index 0000000000..0671f24ba3 --- /dev/null +++ b/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/task-list.html @@ -0,0 +1,22 @@ + + + + + + + + +

+
    +
  • +

    +

    + +
  • +
+

+ + +

+ + diff --git a/spring-dispatcher-servlet/src/main/webapp/public/css/base.css b/spring-dispatcher-servlet/src/main/webapp/public/css/base.css new file mode 100644 index 0000000000..4d3c2597cf --- /dev/null +++ b/spring-dispatcher-servlet/src/main/webapp/public/css/base.css @@ -0,0 +1,8 @@ +a.button { + -webkit-appearance: button; + -moz-appearance: button; + appearance: button; + text-decoration: none; + color: #2196f3; + background-color: #e0e0e0; +} diff --git a/spring-dispatcher-servlet/src/main/webapp/public/css/themes/post_it.css b/spring-dispatcher-servlet/src/main/webapp/public/css/themes/post_it.css new file mode 100644 index 0000000000..578781ec83 --- /dev/null +++ b/spring-dispatcher-servlet/src/main/webapp/public/css/themes/post_it.css @@ -0,0 +1,8 @@ +@import url('https://fonts.googleapis.com/css?family=Indie+Flower'); + +* { + font-family: 'Indie Flower', sans-serif; + font-size: 18px; + color: #ffeb3b; + background-color: #212121; +} diff --git a/spring-dispatcher-servlet/src/main/webapp/public/css/themes/robotask.css b/spring-dispatcher-servlet/src/main/webapp/public/css/themes/robotask.css new file mode 100644 index 0000000000..8c0121b536 --- /dev/null +++ b/spring-dispatcher-servlet/src/main/webapp/public/css/themes/robotask.css @@ -0,0 +1,8 @@ +@import url('https://fonts.googleapis.com/css?family=Roboto'); + +* { + font-family: Roboto, sans-serif; + font-size: 1em; + color: #212121; + background-color: #fafafa; +} diff --git a/spring-jpa/README.md b/spring-jpa/README.md index bc768bee22..30b39e1a4e 100644 --- a/spring-jpa/README.md +++ b/spring-jpa/README.md @@ -13,5 +13,12 @@ - [Hibernate Second-Level Cache](http://www.baeldung.com/hibernate-second-level-cache) - [Spring, Hibernate and a JNDI Datasource](http://www.baeldung.com/spring-persistence-jpa-jndi-datasource) -To ignore "No persistence xml file found in project", you do: -Project -> Properties -> Java Persistance -> JPA -> Error/Warnings -> Select Ignore on "No persistence xml file found in project" +### Eclipse Config +After importing the project into Eclipse, you may see the following error: +"No persistence xml file found in project" + +This can be ignored: +- Project -> Properties -> Java Persistance -> JPA -> Error/Warnings -> Select Ignore on "No persistence xml file found in project" +Or: +- Eclipse -> Preferences - Validation - disable the "Build" execution of the JPA Validator + diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/ErrorController.java b/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/ErrorController.java new file mode 100644 index 0000000000..96556bd5b1 --- /dev/null +++ b/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/ErrorController.java @@ -0,0 +1,52 @@ +package com.baeldung.spring.controller; + +import javax.servlet.http.HttpServletRequest; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.servlet.ModelAndView; + +@Controller +public class ErrorController { + + @RequestMapping(value = "500Error", method = RequestMethod.GET) + public void throwRuntimeException() { + throw new NullPointerException("Throwing a null pointer exception"); + } + + @RequestMapping(value = "errors", method = RequestMethod.GET) + public ModelAndView renderErrorPage(HttpServletRequest httpRequest) { + ModelAndView errorPage = new ModelAndView("errorPage"); + String errorMsg = ""; + int httpErrorCode = getErrorCode(httpRequest); + + switch (httpErrorCode) { + case 400: { + errorMsg = "Http Error Code : 400 . Bad Request"; + break; + } + case 401: { + errorMsg = "Http Error Code : 401. Unauthorized"; + break; + } + case 404: { + errorMsg = "Http Error Code : 404. Resource not found"; + break; + } + // Handle other 4xx error codes. + case 500: { + errorMsg = "Http Error Code : 500. Internal Server Error"; + break; + } + // Handle other 5xx error codes. + } + errorPage.addObject("errorMsg", errorMsg); + return errorPage; + } + + private int getErrorCode(HttpServletRequest httpRequest) { + return (Integer) httpRequest + .getAttribute("javax.servlet.error.status_code"); + } +} diff --git a/spring-mvc-xml/src/main/webapp/WEB-INF/view/errorPage.jsp b/spring-mvc-xml/src/main/webapp/WEB-INF/view/errorPage.jsp new file mode 100644 index 0000000000..ba8a836285 --- /dev/null +++ b/spring-mvc-xml/src/main/webapp/WEB-INF/view/errorPage.jsp @@ -0,0 +1,10 @@ +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> +<%@ page session="false"%> + + + Home + + +

${errorMsg}

+ + diff --git a/spring-mvc-xml/src/main/webapp/WEB-INF/web.xml b/spring-mvc-xml/src/main/webapp/WEB-INF/web.xml index 29608a17ef..2240ac0a22 100644 --- a/spring-mvc-xml/src/main/webapp/WEB-INF/web.xml +++ b/spring-mvc-xml/src/main/webapp/WEB-INF/web.xml @@ -43,4 +43,7 @@ index.jsp + + /errors + \ No newline at end of file diff --git a/spring-rest/pom.xml b/spring-rest/pom.xml index 69ab4ed361..6580f5ecc7 100644 --- a/spring-rest/pom.xml +++ b/spring-rest/pom.xml @@ -332,5 +332,17 @@ 3.4.1 - + + + + org.codehaus.mojo + findbugs-maven-plugin + 3.0.4 + + Max + FindDeadLocalStores,FindNullDeref + + + + diff --git a/spring-thymeleaf/README.md b/spring-thymeleaf/README.md index a8ca755044..98fb4b043b 100644 --- a/spring-thymeleaf/README.md +++ b/spring-thymeleaf/README.md @@ -2,15 +2,16 @@ ## Spring Thymeleaf Example Project - ### Relevant Articles: - [Introduction to Using Thymeleaf in Spring](http://www.baeldung.com/thymeleaf-in-spring-mvc) - [CSRF Protection with Spring MVC and Thymeleaf](http://www.baeldung.com/csrf-thymeleaf-with-spring-security) + ### Build the Project mvn clean install + ### Run the Project mvn cargo:run - **note**: starts on port '8082' diff --git a/testing/README.md b/testing/README.md index f49aeeb881..121472ae13 100644 --- a/testing/README.md +++ b/testing/README.md @@ -5,4 +5,4 @@ ### Relevant Articles: - [Introduction to Mutation Testing Using the PITest Library](http://www.baeldung.com/java-mutation-testing-with-pitest) - [Intro to JaCoCo](http://www.baeldung.com/jacoco) -- [Mutation Testing with PITest](http://www.baeldung.com/java-mutation-testing-with-pitest) +