Merge branch 'master' into JAVA-3533
This commit is contained in:
@@ -22,9 +22,11 @@
|
||||
<module>spring-mvc-forms-jsp</module>
|
||||
<module>spring-mvc-views</module>
|
||||
<module>spring-mvc-webflow</module>
|
||||
<module>spring-mvc-xml</module>
|
||||
<module>spring-rest-angular</module>
|
||||
<module>spring-rest-http</module>
|
||||
<module>spring-rest-http-2</module>
|
||||
<module>spring-rest-query-language</module>
|
||||
<module>spring-resttemplate-2</module>
|
||||
<module>spring-thymeleaf</module>
|
||||
<module>spring-thymeleaf-2</module>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
*.class
|
||||
|
||||
#folders#
|
||||
/target
|
||||
/neoDb*
|
||||
/data
|
||||
/src/main/webapp/WEB-INF/classes
|
||||
*/META-INF/*
|
||||
|
||||
# Packaged files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
@@ -0,0 +1,24 @@
|
||||
## Spring MVC XML
|
||||
|
||||
This module contains articles about Spring MVC with XML configuration
|
||||
|
||||
### The Course
|
||||
|
||||
The "REST With Spring" Classes: http://bit.ly/restwithspring
|
||||
|
||||
### Relevant Articles:
|
||||
|
||||
- [Java Session Timeout](https://www.baeldung.com/servlet-session-timeout)
|
||||
- [Returning Image/Media Data with Spring MVC](https://www.baeldung.com/spring-mvc-image-media-data)
|
||||
- [Geolocation by IP in Java](https://www.baeldung.com/geolocation-by-ip-with-maxmind)
|
||||
- [Guide to JavaServer Pages (JSP)](https://www.baeldung.com/jsp)
|
||||
- [Exploring SpringMVC’s Form Tag Library](https://www.baeldung.com/spring-mvc-form-tags)
|
||||
- [web.xml vs Initializer with Spring](https://www.baeldung.com/spring-xml-vs-java-config)
|
||||
- [A Java Web Application Without a web.xml](https://www.baeldung.com/java-web-app-without-web-xml)
|
||||
- [Validating RequestParams and PathVariables in Spring](https://www.baeldung.com/spring-validate-requestparam-pathvariable)
|
||||
- [Debugging the Spring MVC 404 “No mapping found for HTTP request” Error](https://www.baeldung.com/spring-mvc-404-error)
|
||||
- [Introduction to Servlets and Servlet Containers](https://www.baeldung.com/java-servlets-containers-intro)
|
||||
|
||||
## Spring MVC with XML Configuration Example Project
|
||||
|
||||
- access a sample jsp page at: `http://localhost:8080/spring-mvc-xml/sample.html`
|
||||
@@ -0,0 +1,176 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>spring-mvc-xml</artifactId>
|
||||
<version>0.1-SNAPSHOT</version>
|
||||
<name>spring-mvc-xml</name>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- Spring -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<version>${org.springframework.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
<version>${org.springframework.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- web -->
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>${javax.servlet-api.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>jstl</artifactId>
|
||||
<version>${jstl.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hibernate.validator</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<version>${hibernate-validator.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Json conversion -->
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- IO -->
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons-io.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.maxmind.geoip2</groupId>
|
||||
<artifactId>geoip2</artifactId>
|
||||
<version>${geoip2.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish</groupId>
|
||||
<artifactId>javax.el</artifactId>
|
||||
<version>${javax.el.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- CRaSH Dependency -->
|
||||
<dependency>
|
||||
<groupId>org.crashub</groupId>
|
||||
<artifactId>crash.embed.spring</artifactId>
|
||||
<version>${crash.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.crashub</groupId>
|
||||
<artifactId>crash.cli</artifactId>
|
||||
<version>${crash.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.crashub</groupId>
|
||||
<artifactId>crash.connectors.telnet</artifactId>
|
||||
<version>${crash.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>log4j</artifactId>
|
||||
<groupId>log4j</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- Groovy -->
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy</artifactId>
|
||||
<version>${groovy.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>spring-mvc-xml</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>${maven-war-plugin.version}</version>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
|
||||
<!-- Spring -->
|
||||
<org.springframework.version>5.0.2.RELEASE</org.springframework.version>
|
||||
<spring-boot.version>1.5.10.RELEASE</spring-boot.version>
|
||||
|
||||
<!-- persistence -->
|
||||
<mysql-connector-java.version>5.1.40</mysql-connector-java.version>
|
||||
|
||||
<!-- http -->
|
||||
<httpcore.version>4.4.5</httpcore.version>
|
||||
<httpclient.version>4.5.2</httpclient.version>
|
||||
|
||||
<!-- various -->
|
||||
<hibernate-validator.version>6.0.10.Final</hibernate-validator.version>
|
||||
<javax.el.version>3.0.1-b08</javax.el.version>
|
||||
|
||||
<!-- util -->
|
||||
<guava.version>19.0</guava.version>
|
||||
<geoip2.version>2.8.0</geoip2.version>
|
||||
|
||||
<!-- Maven plugins -->
|
||||
<cargo-maven2-plugin.version>1.6.1</cargo-maven2-plugin.version>
|
||||
|
||||
<crash.version>1.3.2</crash.version>
|
||||
<groovy.version>3.0.0-rc-3</groovy.version>
|
||||
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.baeldung.jsp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public class ExampleOne extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
response.setContentType("text/html");
|
||||
PrintWriter out = response.getWriter();
|
||||
out.println("<!DOCTYPE html><html>" + "<head>" + "<meta charset=\"UTF-8\" />" + "<title>HTML Rendered by Servlet</title>" + "</head>" + "<body>" + "<h1>HTML Rendered by Servlet</h1></br>" + "<p>This page was rendered by the ExampleOne Servlet!</p>"
|
||||
+ "</body>" + "</html>");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.baeldung.jsp;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@WebServlet(name = "ExampleThree", description = "JSP Servlet With Annotations", urlPatterns = { "/ExampleThree" })
|
||||
public class ExampleThree extends HttpServlet {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String instanceMessage;
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
String message = request.getParameter("message");
|
||||
instanceMessage = request.getParameter("message");
|
||||
request.setAttribute("text", message);
|
||||
request.setAttribute("unsafeText", instanceMessage);
|
||||
request.getRequestDispatcher("/jsp/ExampleThree.jsp").forward(request, response);
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.baeldung.spring;
|
||||
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.ImportResource;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@ImportResource("classpath:webMvcConfig.xml")
|
||||
@Configuration
|
||||
@ComponentScan
|
||||
public class ClientWebConfig implements WebMvcConfigurer {
|
||||
|
||||
public ClientWebConfig() {
|
||||
super();
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
package com.baeldung.spring;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.support.MessageSourceResourceBundle;
|
||||
import org.springframework.context.support.ResourceBundleMessageSource;
|
||||
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
|
||||
import org.springframework.web.servlet.ViewResolver;
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
||||
import org.springframework.web.servlet.view.JstlView;
|
||||
|
||||
//@EnableWebMvc
|
||||
//@Configuration
|
||||
@ComponentScan("com.baeldung.spring")
|
||||
public class ClientWebConfigJava implements WebMvcConfigurer {
|
||||
|
||||
public ClientWebConfigJava() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MessageSource messageSource() {
|
||||
|
||||
final ResourceBundleMessageSource ms = new ResourceBundleMessageSource();
|
||||
ms.setBasenames("messages");
|
||||
return ms;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ResourceBundle getBeanResourceBundle() {
|
||||
|
||||
final Locale locale = Locale.getDefault();
|
||||
return new MessageSourceResourceBundle(messageSource(), locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addViewControllers(final ViewControllerRegistry registry) {
|
||||
registry.addViewController("/sample.html");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ViewResolver viewResolver() {
|
||||
final InternalResourceViewResolver bean = new InternalResourceViewResolver();
|
||||
|
||||
bean.setViewClass(JstlView.class);
|
||||
bean.setPrefix("/WEB-INF/view/");
|
||||
bean.setSuffix(".jsp");
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MethodValidationPostProcessor methodValidationPostProcessor() {
|
||||
return new MethodValidationPostProcessor();
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.baeldung.spring.controller;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
|
||||
|
||||
import javax.validation.ConstraintViolationException;
|
||||
|
||||
@ControllerAdvice
|
||||
public class ConstraintViolationExceptionHandler extends ResponseEntityExceptionHandler {
|
||||
|
||||
@ExceptionHandler(value = {ConstraintViolationException.class})
|
||||
protected ResponseEntity<Object> handleConstraintViolation(ConstraintViolationException e, WebRequest request) {
|
||||
return handleExceptionInternal(e, e.getMessage(), new HttpHeaders(), HttpStatus.BAD_REQUEST, request);
|
||||
}
|
||||
}
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
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");
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.baeldung.spring.controller;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
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.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import com.baeldung.spring.form.GeoIP;
|
||||
import com.baeldung.spring.service.RawDBDemoGeoIPLocationService;
|
||||
|
||||
//@Controller
|
||||
//add db file and uncomment to see the working example
|
||||
public class GeoIPTestController {
|
||||
private RawDBDemoGeoIPLocationService locationService;
|
||||
|
||||
public GeoIPTestController() throws IOException {
|
||||
locationService = new RawDBDemoGeoIPLocationService();
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/GeoIPTest", method = RequestMethod.POST)
|
||||
@ResponseBody
|
||||
public GeoIP getLocation(@RequestParam(value = "ipAddress", required = true) String ipAddress) throws Exception {
|
||||
|
||||
return locationService.getLocation(ipAddress);
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.baeldung.spring.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
@Controller
|
||||
public class GreetingController {
|
||||
|
||||
@RequestMapping(value = "/greeting", method = RequestMethod.GET)
|
||||
public String get(ModelMap model) {
|
||||
model.addAttribute("message", "Hello, World!");
|
||||
return "greeting";
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.baeldung.spring.controller;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.mvc.AbstractController;
|
||||
|
||||
public class HelloController extends AbstractController {
|
||||
|
||||
@Override
|
||||
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
ModelAndView model = new ModelAndView("helloworld");
|
||||
model.addObject("msg", "Welcome to Baeldung's Spring Handler Mappings Guide.<br>This request was mapped" + " using SimpleUrlHandlerMapping.");
|
||||
|
||||
return model;
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.baeldung.spring.controller;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.mvc.AbstractController;
|
||||
|
||||
public class HelloGuestController extends AbstractController {
|
||||
@Override
|
||||
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
ModelAndView model = new ModelAndView("helloworld");
|
||||
model.addObject("msg", "Welcome to Baeldung's Spring Handler Mappings Guide.<br>This request was mapped" + " using ControllerClassNameHandlerMapping.");
|
||||
|
||||
return model;
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.baeldung.spring.controller;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.mvc.AbstractController;
|
||||
|
||||
public class HelloWorldController extends AbstractController {
|
||||
@Override
|
||||
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
ModelAndView model = new ModelAndView("helloworld");
|
||||
model.addObject("msg", "Welcome to Baeldung's Spring Handler Mappings Guide.<br>This request was mapped" + " using BeanNameUrlHandlerMapping.");
|
||||
|
||||
return model;
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package com.baeldung.spring.controller;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.*;
|
||||
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;
|
||||
import org.springframework.web.context.support.ServletContextResource;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
@Controller
|
||||
public class ImageController {
|
||||
|
||||
@Autowired
|
||||
private ServletContext servletContext;
|
||||
|
||||
@RequestMapping(value = "/image-view", method = RequestMethod.GET)
|
||||
public String imageView() throws IOException {
|
||||
return "image-download";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/image-manual-response", method = RequestMethod.GET)
|
||||
public void getImageAsByteArray(HttpServletResponse response) throws IOException {
|
||||
final InputStream in = servletContext.getResourceAsStream("/WEB-INF/images/image-example.jpg");
|
||||
response.setContentType(MediaType.IMAGE_JPEG_VALUE);
|
||||
IOUtils.copy(in, response.getOutputStream());
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/image-byte-array", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public byte[] getImageAsByteArray() throws IOException {
|
||||
final InputStream in = servletContext.getResourceAsStream("/WEB-INF/images/image-example.jpg");
|
||||
return IOUtils.toByteArray(in);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/image-response-entity", method = RequestMethod.GET)
|
||||
public ResponseEntity<byte[]> getImageAsResponseEntity() throws IOException {
|
||||
ResponseEntity<byte[]> responseEntity;
|
||||
final HttpHeaders headers = new HttpHeaders();
|
||||
final InputStream in = servletContext.getResourceAsStream("/WEB-INF/images/image-example.jpg");
|
||||
byte[] media = IOUtils.toByteArray(in);
|
||||
headers.setCacheControl(CacheControl.noCache().getHeaderValue());
|
||||
responseEntity = new ResponseEntity<>(media, headers, HttpStatus.OK);
|
||||
return responseEntity;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/image-resource", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public ResponseEntity<Resource> getImageAsResource() {
|
||||
final HttpHeaders headers = new HttpHeaders();
|
||||
Resource resource = new ServletContextResource(servletContext, "/WEB-INF/images/image-example.jpg");
|
||||
return new ResponseEntity<>(resource, headers, HttpStatus.OK);
|
||||
}
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
package com.baeldung.spring.controller;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
import com.baeldung.spring.form.Person;
|
||||
import com.baeldung.spring.validator.PersonValidator;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.validation.BindingResult;
|
||||
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;
|
||||
|
||||
@Controller
|
||||
public class PersonController {
|
||||
|
||||
@Autowired
|
||||
PersonValidator validator;
|
||||
|
||||
@RequestMapping(value = "/person", method = RequestMethod.GET)
|
||||
public ModelAndView showForm(final Model model) {
|
||||
|
||||
initData(model);
|
||||
return new ModelAndView("personForm", "person", new Person());
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/addPerson", method = RequestMethod.POST)
|
||||
public String submit(@Valid @ModelAttribute("person") final Person person, final BindingResult result, final ModelMap modelMap, final Model model) {
|
||||
|
||||
validator.validate(person, result);
|
||||
|
||||
if (result.hasErrors()) {
|
||||
|
||||
initData(model);
|
||||
return "personForm";
|
||||
}
|
||||
|
||||
modelMap.addAttribute("person", person);
|
||||
|
||||
return "personView";
|
||||
}
|
||||
|
||||
private void initData(final Model model) {
|
||||
|
||||
final List<String> favouriteLanguageItem = new ArrayList<String>();
|
||||
favouriteLanguageItem.add("Java");
|
||||
favouriteLanguageItem.add("C++");
|
||||
favouriteLanguageItem.add("Perl");
|
||||
model.addAttribute("favouriteLanguageItem", favouriteLanguageItem);
|
||||
|
||||
final List<String> jobItem = new ArrayList<String>();
|
||||
jobItem.add("Full time");
|
||||
jobItem.add("Part time");
|
||||
model.addAttribute("jobItem", jobItem);
|
||||
|
||||
final Map<String, String> countryItems = new LinkedHashMap<String, String>();
|
||||
countryItems.put("US", "United Stated");
|
||||
countryItems.put("IT", "Italy");
|
||||
countryItems.put("UK", "United Kingdom");
|
||||
countryItems.put("FR", "Grance");
|
||||
model.addAttribute("countryItems", countryItems);
|
||||
|
||||
final List<String> fruit = new ArrayList<String>();
|
||||
fruit.add("Banana");
|
||||
fruit.add("Mango");
|
||||
fruit.add("Apple");
|
||||
model.addAttribute("fruit", fruit);
|
||||
|
||||
final List<String> books = new ArrayList<String>();
|
||||
books.add("The Great Gatsby");
|
||||
books.add("Nineteen Eighty-Four");
|
||||
books.add("The Lord of the Rings");
|
||||
model.addAttribute("books", books);
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.baeldung.spring.controller;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import javax.validation.constraints.*;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/public/api/1")
|
||||
@Validated
|
||||
public class RequestAndPathVariableValidationController {
|
||||
|
||||
@GetMapping("/name-for-day")
|
||||
public String getNameOfDayByNumberRequestParam(@RequestParam @Min(1) @Max(7) Integer dayOfWeek) {
|
||||
return dayOfWeek + "";
|
||||
}
|
||||
|
||||
@GetMapping("/name-for-day/{dayOfWeek}")
|
||||
public String getNameOfDayByPathVariable(@PathVariable("dayOfWeek") @Min(1) @Max(7) Integer dayOfWeek) {
|
||||
return dayOfWeek + "";
|
||||
}
|
||||
|
||||
@GetMapping("/valid-name")
|
||||
public void validStringRequestParam(@RequestParam @NotBlank @Size(max = 10) @Pattern(regexp = "^[A-Z][a-zA-Z0-9]+$") String name) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.baeldung.spring.controller;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.mvc.AbstractController;
|
||||
|
||||
public class WelcomeController extends AbstractController {
|
||||
@Override
|
||||
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
|
||||
ModelAndView model = new ModelAndView("welcome");
|
||||
model.addObject("msg", " Baeldung's Spring Handler Mappings Guide.<br>This request was mapped" + " using SimpleUrlHandlerMapping.");
|
||||
|
||||
return model;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.baeldung.spring.form;
|
||||
|
||||
public class GeoIP {
|
||||
private String ipAddress;
|
||||
private String city;
|
||||
private String latitude;
|
||||
private String longitude;
|
||||
|
||||
public GeoIP() {
|
||||
|
||||
}
|
||||
|
||||
public GeoIP(String ipAddress) {
|
||||
this.ipAddress = ipAddress;
|
||||
}
|
||||
|
||||
public GeoIP(String ipAddress, String city, String latitude, String longitude) {
|
||||
this.ipAddress = ipAddress;
|
||||
this.city = city;
|
||||
this.latitude = latitude;
|
||||
this.longitude = longitude;
|
||||
}
|
||||
|
||||
public String getIpAddress() {
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
public void setIpAddress(String ipAddress) {
|
||||
this.ipAddress = ipAddress;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public String getLatitude() {
|
||||
return latitude;
|
||||
}
|
||||
|
||||
public void setLatitude(String latitude) {
|
||||
this.latitude = latitude;
|
||||
}
|
||||
|
||||
public String getLongitude() {
|
||||
return longitude;
|
||||
}
|
||||
|
||||
public void setLongitude(String longitude) {
|
||||
this.longitude = longitude;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
package com.baeldung.spring.form;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
public class Person {
|
||||
|
||||
private long id;
|
||||
|
||||
private String name;
|
||||
private String email;
|
||||
private String dateOfBirth;
|
||||
|
||||
@NotEmpty
|
||||
private String password;
|
||||
private String sex;
|
||||
private String country;
|
||||
private String book;
|
||||
private String job;
|
||||
private boolean receiveNewsletter;
|
||||
private String[] hobbies;
|
||||
private List<String> favouriteLanguage;
|
||||
private List<String> fruit;
|
||||
private String notes;
|
||||
private MultipartFile file;
|
||||
|
||||
public Person() {
|
||||
super();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(final String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getDateOfBirth() {
|
||||
return dateOfBirth;
|
||||
}
|
||||
|
||||
public void setDateOfBirth(final String dateOfBirth) {
|
||||
this.dateOfBirth = dateOfBirth;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(final String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getSex() {
|
||||
return sex;
|
||||
}
|
||||
|
||||
public void setSex(final String sex) {
|
||||
this.sex = sex;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(final String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public String getJob() {
|
||||
return job;
|
||||
}
|
||||
|
||||
public void setJob(final String job) {
|
||||
this.job = job;
|
||||
}
|
||||
|
||||
public boolean isReceiveNewsletter() {
|
||||
return receiveNewsletter;
|
||||
}
|
||||
|
||||
public void setReceiveNewsletter(final boolean receiveNewsletter) {
|
||||
this.receiveNewsletter = receiveNewsletter;
|
||||
}
|
||||
|
||||
public String[] getHobbies() {
|
||||
return hobbies;
|
||||
}
|
||||
|
||||
public void setHobbies(final String[] hobbies) {
|
||||
this.hobbies = hobbies;
|
||||
}
|
||||
|
||||
public List<String> getFavouriteLanguage() {
|
||||
return favouriteLanguage;
|
||||
}
|
||||
|
||||
public void setFavouriteLanguage(final List<String> favouriteLanguage) {
|
||||
this.favouriteLanguage = favouriteLanguage;
|
||||
}
|
||||
|
||||
public String getNotes() {
|
||||
return notes;
|
||||
}
|
||||
|
||||
public void setNotes(final String notes) {
|
||||
this.notes = notes;
|
||||
}
|
||||
|
||||
public List<String> getFruit() {
|
||||
return fruit;
|
||||
}
|
||||
|
||||
public void setFruit(final List<String> fruit) {
|
||||
this.fruit = fruit;
|
||||
}
|
||||
|
||||
public String getBook() {
|
||||
return book;
|
||||
}
|
||||
|
||||
public void setBook(final String book) {
|
||||
this.book = book;
|
||||
}
|
||||
|
||||
public MultipartFile getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public void setFile(final MultipartFile file) {
|
||||
this.file = file;
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.baeldung.spring.service;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
|
||||
import com.baeldung.spring.form.GeoIP;
|
||||
import com.maxmind.geoip2.DatabaseReader;
|
||||
import com.maxmind.geoip2.exception.GeoIp2Exception;
|
||||
import com.maxmind.geoip2.model.CityResponse;
|
||||
|
||||
public class RawDBDemoGeoIPLocationService {
|
||||
private DatabaseReader dbReader;
|
||||
|
||||
public RawDBDemoGeoIPLocationService() throws IOException {
|
||||
File database = new File("your-path-to-db-file");
|
||||
dbReader = new DatabaseReader.Builder(database).build();
|
||||
}
|
||||
|
||||
public GeoIP getLocation(String ip) throws IOException, GeoIp2Exception {
|
||||
InetAddress ipAddress = InetAddress.getByName(ip);
|
||||
CityResponse response = dbReader.city(ipAddress);
|
||||
|
||||
String cityName = response.getCity().getName();
|
||||
String latitude = response.getLocation().getLatitude().toString();
|
||||
String longitude = response.getLocation().getLongitude().toString();
|
||||
return new GeoIP(ip, cityName, latitude, longitude);
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.baeldung.spring.validator;
|
||||
|
||||
import com.baeldung.spring.form.Person;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.validation.ValidationUtils;
|
||||
import org.springframework.validation.Validator;
|
||||
|
||||
@Component
|
||||
public class PersonValidator implements Validator {
|
||||
|
||||
@Override
|
||||
public boolean supports(final Class calzz) {
|
||||
return Person.class.isAssignableFrom(calzz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(final Object obj, final Errors errors) {
|
||||
|
||||
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "required.name");
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:mvc="http://www.springframework.org/schema/mvc"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context.xsd
|
||||
http://www.springframework.org/schema/mvc
|
||||
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
|
||||
|
||||
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />
|
||||
<context:component-scan base-package="com.baeldung.spring.controller" />
|
||||
<bean id="viewResolver"
|
||||
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
|
||||
<property name="prefix" value="/WEB-INF/view/" />
|
||||
<property name="suffix" value=".jsp" />
|
||||
</bean>
|
||||
|
||||
<mvc:view-controller path="/sample.html" view-name="sample" />
|
||||
|
||||
<!-- Content strategy using path extension -->
|
||||
<bean id="contentNegotiationManager"
|
||||
class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
|
||||
<property name="favorPathExtension" value="false" />
|
||||
<property name="favorParameter" value="true"/>
|
||||
<property name="parameterName" value="mediaType"/>
|
||||
<property name="ignoreAcceptHeader" value="true" />
|
||||
<property name="defaultContentType" value="application/json" />
|
||||
<property name="useJaf" value="false" />
|
||||
|
||||
<property name="mediaTypes">
|
||||
<map>
|
||||
<entry key="json" value="application/json" />
|
||||
<entry key="xml" value="application/xml" />
|
||||
</map>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="org.springframework" level="WARN" />
|
||||
<logger name="org.springframework.transaction" level="WARN" />
|
||||
|
||||
<!-- in order to debug some marshalling issues, this needs to be TRACE -->
|
||||
<logger name="org.springframework.web.servlet.mvc" level="WARN" />
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
||||
@@ -0,0 +1,2 @@
|
||||
required.name = Name is required!
|
||||
NotEmpty.person.password = Password is required!
|
||||
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:mvc="http://www.springframework.org/schema/mvc"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context.xsd
|
||||
http://www.springframework.org/schema/mvc
|
||||
http://www.springframework.org/schema/mvc/spring-mvc.xsd"
|
||||
>
|
||||
|
||||
<mvc:annotation-driven>
|
||||
<mvc:message-converters>
|
||||
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter">
|
||||
<property name="supportedMediaTypes">
|
||||
<list>
|
||||
<value>image/jpeg</value>
|
||||
<value>image/png</value>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
</mvc:message-converters>
|
||||
</mvc:annotation-driven>
|
||||
|
||||
<context:component-scan base-package="com.baeldung.spring.controller"/>
|
||||
|
||||
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
|
||||
<property name="prefix" value="/WEB-INF/view/"/>
|
||||
<property name="suffix" value=".jsp"/>
|
||||
</bean>
|
||||
|
||||
<mvc:view-controller path="/sample.html" view-name="sample"/>
|
||||
|
||||
<bean class="org.springframework.context.support.ResourceBundleMessageSource" id="messageSource">
|
||||
<property name="basename" value="messages" />
|
||||
</bean>
|
||||
</beans>
|
||||
@@ -0,0 +1,84 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="ISO-8859-1">
|
||||
<title>Geo IP Test</title>
|
||||
|
||||
<!--jquery dep -->
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready (function () {
|
||||
// getting the public ip address from api and setting on text box
|
||||
// ip api : https://www.ipify.org/
|
||||
$.get( "https://api.ipify.org?format=json", function( data ) {
|
||||
console.log(data);
|
||||
$("#ip").val(data.ip) ;
|
||||
});
|
||||
|
||||
function showLocationOnMap (location) {
|
||||
var map;
|
||||
|
||||
map = new google.maps.Map(document.getElementById('map'), {
|
||||
center: {lat: Number(location.latitude), lng: Number(location.longitude)},
|
||||
zoom: 15
|
||||
});
|
||||
|
||||
var marker = new google.maps.Marker({
|
||||
position: {lat: Number(location.latitude), lng: Number(location.longitude)},
|
||||
map: map,
|
||||
title: "Public IP:"+location.ipAddress+" @ "+location.city
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
$( "#ipForm" ).submit(function( event ) {
|
||||
event.preventDefault();
|
||||
$.ajax({
|
||||
url: "GeoIPTest",
|
||||
type: "POST",
|
||||
contentType: "application/x-www-form-urlencoded; charset=UTF-8", // send as JSON
|
||||
data: $.param( {ipAddress : $("#ip").val()} ),
|
||||
|
||||
complete: function(data) {
|
||||
console.log ("Request complete");
|
||||
|
||||
},
|
||||
|
||||
success: function(data) {
|
||||
$("#status").html(JSON.stringify(data));
|
||||
|
||||
if (data.ipAddress !=null) {
|
||||
console.log ("Success:"+data.ipAddress);
|
||||
showLocationOnMap(data);
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
error: function(err) {
|
||||
console.log(err);
|
||||
$("#status").html("Error:"+JSON.stringify(data));
|
||||
},
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
<form id="ipForm" action="GeoIPTest" method="POST">
|
||||
<input type="text" name = "ipAddress" id = "ip"/>
|
||||
<input type="submit" name="submit" value="submit" />
|
||||
|
||||
</form>
|
||||
|
||||
<div id="status"></div>
|
||||
|
||||
<div id="map" style="height: 500px; width:100%; position:absolute"></div>
|
||||
|
||||
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR-MAPS-API-KEY"
|
||||
async defer></script>
|
||||
</body>
|
||||
</html>
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import org.crsh.cli.Command;
|
||||
import org.crsh.cli.Usage;
|
||||
import org.crsh.cli.Option;
|
||||
|
||||
class message {
|
||||
|
||||
@Usage("show my own message")
|
||||
@Command
|
||||
Object main(@Usage("custom message") @Option(names=["m","message"]) String message) {
|
||||
if (message == null)
|
||||
message = "No message given...";
|
||||
return message;
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import org.crsh.command.BaseCommand;
|
||||
import org.crsh.cli.Usage;
|
||||
import org.crsh.cli.Command;
|
||||
import org.crsh.cli.Option;
|
||||
|
||||
public class message2 extends BaseCommand {
|
||||
@Usage("show my own message using java")
|
||||
@Command
|
||||
public Object main(@Usage("custom message") @Option(names = { "m", "message" }) String message) {
|
||||
if (message == null)
|
||||
message = "No message given...";
|
||||
return message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
crash.telnet.port=50001
|
||||
@@ -0,0 +1,65 @@
|
||||
############################
|
||||
# Telnet daemon properties #
|
||||
############################
|
||||
|
||||
#####################
|
||||
# Terminals Section #
|
||||
#####################
|
||||
|
||||
# List of terminals available and defined below
|
||||
terminals=vt100,ansi,windoof,xterm
|
||||
|
||||
# vt100 implementation and aliases
|
||||
term.vt100.class=net.wimpi.telnetd.io.terminal.vt100
|
||||
term.vt100.aliases=default,vt100-am,vt102,dec-vt100
|
||||
|
||||
# ansi implementation and aliases
|
||||
term.ansi.class=net.wimpi.telnetd.io.terminal.ansi
|
||||
term.ansi.aliases=color-xterm,xterm-color,vt320,vt220,linux,screen
|
||||
|
||||
# windoof implementation and aliases
|
||||
term.windoof.class=net.wimpi.telnetd.io.terminal.Windoof
|
||||
term.windoof.aliases=
|
||||
|
||||
# xterm implementation and aliases
|
||||
term.xterm.class=net.wimpi.telnetd.io.terminal.xterm
|
||||
term.xterm.aliases=
|
||||
|
||||
##################
|
||||
# Shells Section #
|
||||
##################
|
||||
|
||||
# List of shells available and defined below
|
||||
shells=simple
|
||||
|
||||
# shell implementations
|
||||
shell.simple.class=org.crsh.telnet.term.TelnetHandler
|
||||
|
||||
#####################
|
||||
# Listeners Section #
|
||||
#####################
|
||||
listeners=std
|
||||
|
||||
|
||||
# std listener specific properties
|
||||
|
||||
#Basic listener and connection management settings (port is commented because CRaSH configures it)
|
||||
# std.port=5000
|
||||
std.floodprotection=5
|
||||
std.maxcon=25
|
||||
|
||||
|
||||
# Timeout Settings for connections (ms)
|
||||
std.time_to_warning=3600000
|
||||
std.time_to_timedout=60000
|
||||
|
||||
# Housekeeping thread active every 1 secs
|
||||
std.housekeepinginterval=1000
|
||||
|
||||
std.inputmode=character
|
||||
|
||||
# Login shell
|
||||
std.loginshell=simple
|
||||
|
||||
# Connection filter class
|
||||
std.connectionfilter=none
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 101 KiB |
@@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
|
||||
http://www.springframework.org/schema/mvc
|
||||
http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
|
||||
|
||||
|
||||
<context:component-scan base-package="com.baeldung.spring.controller"/>
|
||||
|
||||
<!-- Start: Mapping by bean name (BeanNameUrlHandlerMapping) -->
|
||||
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
|
||||
<property name="order" value="1"/>
|
||||
</bean>
|
||||
|
||||
<bean name="/hello*.htm" class="com.baeldung.spring.controller.HelloWorldController"/>
|
||||
<!-- End: Mapping by bean name (BeanNameUrlHandlerMapping) -->
|
||||
|
||||
<!-- Start: Mapping by SimpleUrlHandlerMapping -->
|
||||
|
||||
<!-- Method 1 – Using Value -->
|
||||
<!-- <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
|
||||
<property name="mappings"> <value> /welcome.htm=welcomeController /welcome*=welcomeController
|
||||
</value> </property> <property name="order" value="2" /> </bean> -->
|
||||
|
||||
<!-- Method 2 – Using prop key -->
|
||||
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
|
||||
<property name="mappings">
|
||||
<props>
|
||||
<prop key="/welcome.htm">welcomeController</prop>
|
||||
<prop key="/welcome*">welcomeController</prop>
|
||||
<prop key="/hello*">helloController</prop>
|
||||
</props>
|
||||
</property>
|
||||
<property name="order" value="2"/>
|
||||
</bean>
|
||||
|
||||
<bean id="welcomeController" class="com.baeldung.spring.controller.WelcomeController"></bean>
|
||||
<bean id="helloController" class="com.baeldung.spring.controller.HelloController"/>
|
||||
<!-- End: Mapping by SimpleUrlHandlerMapping -->
|
||||
|
||||
|
||||
<bean class="com.baeldung.spring.controller.HelloGuestController"/>
|
||||
<!-- End: Mapping by ControllerClassNameHandlerMapping -->
|
||||
|
||||
<!-- Start: Mapping by ControllerClassNameHandlerMapping with prefix -->
|
||||
<!-- <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
|
||||
<property name="caseSensitive" value="true" /> <property name="order" value="0"
|
||||
/> <property name="pathPrefix" value="/login" /> </bean> <bean class="com.baeldung.spring.controller.HelloGuestController"
|
||||
/> -->
|
||||
<!-- End: Mapping by ControllerClassNameHandlerMapping with prefix -->
|
||||
|
||||
|
||||
<bean class="org.crsh.spring.SpringWebBootstrap">
|
||||
<property name="cmdMountPointConfig"
|
||||
value="war:/WEB-INF/crash/commands/" />
|
||||
<property name="confMountPointConfig"
|
||||
value="war:/WEB-INF/crash/" />
|
||||
<property name="config">
|
||||
<props>
|
||||
<prop key="crash.telnet.port">5000</prop>
|
||||
</props>
|
||||
</property>
|
||||
</bean>
|
||||
</beans>
|
||||
@@ -0,0 +1,20 @@
|
||||
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
|
||||
pageEncoding="ISO-8859-1"%>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>SpringMVCExample</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h3>Pleas enter the correct details</h3>
|
||||
<table>
|
||||
<tr>
|
||||
<td><a href="employee">Retry</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,10 @@
|
||||
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
|
||||
<%@ page session="false"%>
|
||||
<html>
|
||||
<head>
|
||||
<title>Home</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>${errorMsg}</h1>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||
<html>
|
||||
<head>
|
||||
<title>Greeting</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>${message}</h2>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,15 @@
|
||||
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
|
||||
pageEncoding="ISO-8859-1"%>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Hello World</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Hello ${msg}</h2>
|
||||
<br>
|
||||
<p>
|
||||
<a href="spring-handler-index.jsp">Go to spring handler mappings homepage</a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,15 @@
|
||||
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
|
||||
pageEncoding="ISO-8859-1"%>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Hello World</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Hello World ${msg}</h2>
|
||||
<br>
|
||||
<p>
|
||||
<a href="spring-handler-index.jsp">Go to spring handler mappings homepage</a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||
<html>
|
||||
<head>
|
||||
<title>Image download examples</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Image download examples</h1>
|
||||
<ul>
|
||||
<li><a href="<c:url value="/image-manual-response" />">Image manually add to response</a></li>
|
||||
<li><a href="<c:url value="/image-byte-array.jpg" />">Image Download <i>byte[]</i> Example</a></li>
|
||||
<li><a href="<c:url value="/image-response-entity.jpg" />">Image Download <i>ResponseEntity</i> Example</a></li>
|
||||
<li><a href="<c:url value="/image-resource.jpg" />">Image Download <i>Resource</i> Example</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,120 @@
|
||||
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
|
||||
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Form Example - Register a Person</title>
|
||||
</head>
|
||||
|
||||
<style>
|
||||
|
||||
.error {
|
||||
color: #ff0000;
|
||||
}
|
||||
|
||||
.errorbox {
|
||||
|
||||
background-color: #ffEEEE;
|
||||
border: 2px solid #ff0000;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<body>
|
||||
|
||||
<h3>Welcome, Enter the Person Details</h3>
|
||||
|
||||
<form:form method="POST" action="/spring-mvc-xml/addPerson" modelAttribute="person">
|
||||
|
||||
<form:errors path="*" cssClass="errorbox" element="div" />
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><form:label path="name">Name</form:label></td>
|
||||
<td><form:input path="name" /></td>
|
||||
<td><form:errors path="name" cssClass="error" element="div"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><form:label path="email">E-mail</form:label></td>
|
||||
<td><form:input type="email" path="email" /></td>
|
||||
<td><form:errors path="email" cssClass="error" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><form:label path="dateOfBirth">Date of birth</form:label></td>
|
||||
<td><form:input type="date" path="dateOfBirth" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><form:label path="password">Password</form:label></td>
|
||||
<td><form:password path="password" /></td>
|
||||
<td><form:errors path="password" cssClass="error" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><form:label path="sex">Sex</form:label></td>
|
||||
<td>
|
||||
Male: <form:radiobutton path="sex" value="M"/> <br/>
|
||||
Female: <form:radiobutton path="sex" value="F"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><form:label path="job">Job</form:label></td>
|
||||
<td>
|
||||
<form:radiobuttons items="${jobItem}" path="job" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><form:label path="country">Country</form:label></td>
|
||||
<td>
|
||||
<form:select path="country" items="${countryItems}" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><form:label path="book">Book</form:label></td>
|
||||
<td>
|
||||
<form:select path="book">
|
||||
<form:option value="-" label="--Please Select"/>
|
||||
<form:options items="${books}" />
|
||||
</form:select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><form:label path="fruit">Fruit</form:label></td>
|
||||
<td>
|
||||
<form:select path="fruit" items="${fruit}" multiple="true"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><form:label path="receiveNewsletter">Receive newsletter</form:label></td>
|
||||
<td><form:checkbox path="receiveNewsletter" rows="3" cols="20"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><form:label path="hobbies">Hobbies</form:label></td>
|
||||
<td>
|
||||
Bird watching: <form:checkbox path="hobbies" value="Bird watching"/>
|
||||
Astronomy: <form:checkbox path="hobbies" value="Astronomy"/>
|
||||
Snowboarding: <form:checkbox path="hobbies" value="Snowboarding"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><form:label path="favouriteLanguage">Favourite languages</form:label></td>
|
||||
<td>
|
||||
<form:checkboxes items="${favouriteLanguageItem}" path="favouriteLanguage" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><form:label path="notes">Notes</form:label></td>
|
||||
<td><form:textarea path="notes" rows="3" cols="20"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><form:hidden path="id" value="12345"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="submit" value="Submit" /></td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
</form:form>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,65 @@
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Spring MVC Form Handling</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h2>Submitted Person Information</h2>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Id :</td>
|
||||
<td>${person.id}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Name :</td>
|
||||
<td>${person.name}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Date of birth :</td>
|
||||
<td>${person.dateOfBirth}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Password :</td>
|
||||
<td>${person.password}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Sex :</td>
|
||||
<td>${person.sex}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Job :</td>
|
||||
<td>${person.job}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Country :</td>
|
||||
<td>${person.country}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Fruit :</td>
|
||||
<td><c:forEach items="${person.fruit}" var="current">[<c:out value="${current}" />]</c:forEach></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Book :</td>
|
||||
<td>${person.book}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Receive Newsletter :</td>
|
||||
<td>${person.receiveNewsletter}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Hobbies :</td>
|
||||
<td><c:forEach items="${person.hobbies}" var="current">[<c:out value="${current}" />]</c:forEach></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Favourite Languages :</td>
|
||||
<td><c:forEach items="${person.favouriteLanguage}" var="current">[<c:out value="${current}" />]</c:forEach></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Notes :</td>
|
||||
<td>${person.notes}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<head></head>
|
||||
|
||||
<body>
|
||||
<h1>This is the body of the sample view</h1>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,15 @@
|
||||
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
|
||||
pageEncoding="ISO-8859-1"%>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Welcome Page</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Welcome to ${msg}</h2>
|
||||
<br>
|
||||
<p>
|
||||
<a href="spring-handler-index.jsp">Go to spring handler mappings homepage</a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
|
||||
version="3.1"
|
||||
>
|
||||
<display-name>Spring MVC XML Application</display-name>
|
||||
|
||||
<!-- Spring root -->
|
||||
<context-param>
|
||||
<param-name>contextClass</param-name>
|
||||
<param-value>
|
||||
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
|
||||
</param-value>
|
||||
</context-param>
|
||||
<context-param>
|
||||
<param-name>contextConfigLocation</param-name>
|
||||
<param-value>com.baeldung.spring</param-value>
|
||||
</context-param>
|
||||
|
||||
<listener>
|
||||
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
|
||||
</listener>
|
||||
<listener>
|
||||
<listener-class>org.crsh.plugin.WebPluginLifeCycle</listener-class>
|
||||
</listener>
|
||||
|
||||
<!-- Spring child -->
|
||||
<servlet>
|
||||
<servlet-name>mvc</servlet-name>
|
||||
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>mvc</servlet-name>
|
||||
<url-pattern>/</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- JSP Servlet -->
|
||||
|
||||
<servlet>
|
||||
<servlet-name>ExampleOne</servlet-name>
|
||||
<servlet-class>com.baeldung.jsp.ExampleOne</servlet-class>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>ExampleOne</servlet-name>
|
||||
<url-pattern>/jsp/ExampleOne</url-pattern>
|
||||
</servlet-mapping>
|
||||
<servlet>
|
||||
<servlet-name>ExampleThree</servlet-name>
|
||||
<servlet-class>com.baeldung.jsp.ExampleThree</servlet-class>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>ExampleThree</servlet-name>
|
||||
<url-pattern>/jsp/ExampleThree</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- additional config -->
|
||||
|
||||
<session-config>
|
||||
<session-timeout>10</session-timeout>
|
||||
</session-config>
|
||||
<welcome-file-list>
|
||||
<welcome-file>index.jsp</welcome-file>
|
||||
</welcome-file-list>
|
||||
|
||||
<error-page>
|
||||
<location>/errors</location>
|
||||
</error-page>
|
||||
</web-app>
|
||||
@@ -0,0 +1,20 @@
|
||||
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
|
||||
pageEncoding="ISO-8859-1"%>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Spring MVC Examples</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Spring MVC Examples</h1>
|
||||
<ul>
|
||||
<li><a href="employee">Welcome Page</a></li>
|
||||
<li><a href="spring-handler-index.jsp">Spring Handler Mapping Examples</a></li>
|
||||
<li><a href="image-view">Image Download Examples</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,10 @@
|
||||
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<title>Java Binding Example</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Bound Value</h1>
|
||||
<p>You said: ${text}</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,13 @@
|
||||
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<title>Java in Static Page Example</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Java in Static Page Example</h1>
|
||||
<% String[] arr = {"What's up?", "Hello", "It's a nice day today!"};
|
||||
String greetings = arr[(int)(Math.random() * arr.length)];
|
||||
%>
|
||||
<p><%= greetings %></p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,12 @@
|
||||
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||
<html>
|
||||
<head>
|
||||
<title>JSP Examples</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Simple JSP Examples</h1>
|
||||
<p>Invoke HTML rendered by Servlet: <a href="ExampleOne" target="_blank">here</a></p>
|
||||
<p>Java in static page: <a href="ExampleTwo.jsp" target="_blank">here</a></p>
|
||||
<p>Java injected by Servlet: <a href="ExampleThree?message=hello!" target="_blank">here</a></p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Welcome</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Spring Handler Mapping Examples</h2>
|
||||
<h3>Click each link below to see how the request is mapped using the specified mapping:
|
||||
</h3>
|
||||
<ol>
|
||||
<li><a href="helloWorld.html">BeanNameUrlHandlerMapping - Mapping by bean name</a></li>
|
||||
<li><a href="welcome.html">SimpleUrlHandlerMapping</a></li>
|
||||
<li><a href="helloGuest.html">ControllerClassNameHandlerMapping - Mapping by controller name</a></li>
|
||||
</ol>
|
||||
<a href="index.jsp">Home</a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.baeldung;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
import com.baeldung.spring.ClientWebConfig;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = ClientWebConfig.class)
|
||||
@WebAppConfiguration
|
||||
public class SpringContextTest {
|
||||
|
||||
@Test
|
||||
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package com.baeldung.geoip;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.maxmind.geoip2.DatabaseReader;
|
||||
import com.maxmind.geoip2.exception.GeoIp2Exception;
|
||||
import com.maxmind.geoip2.model.CityResponse;
|
||||
|
||||
public class GeoIpIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void givenIP_whenFetchingCity_thenReturnsCityData() throws IOException, GeoIp2Exception {
|
||||
|
||||
ClassLoader classLoader = getClass().getClassLoader();
|
||||
File database = new File(classLoader.getResource("GeoLite2-City.mmdb").getFile());
|
||||
DatabaseReader dbReader = new DatabaseReader.Builder(database).build();
|
||||
|
||||
InetAddress ipAddress = InetAddress.getByName("google.com");
|
||||
CityResponse response = dbReader.city(ipAddress);
|
||||
|
||||
String countryName = response.getCountry().getName();
|
||||
String cityName = response.getCity().getName();
|
||||
String postal = response.getPostal().getCode();
|
||||
String state = response.getLeastSpecificSubdivision().getName();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
package com.baeldung.spring.controller;
|
||||
|
||||
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;
|
||||
|
||||
import com.baeldung.spring.ClientWebConfig;
|
||||
import com.baeldung.spring.ClientWebConfigJava;
|
||||
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = ClientWebConfigJava.class)
|
||||
@WebAppConfiguration
|
||||
public class RequestAndPathVariableValidationControllerIntegrationTest {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Autowired
|
||||
private WebApplicationContext webApplicationContext;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getNameOfDayByNumberRequestParam_whenGetWithProperRequestParam_thenReturn200() throws Exception {
|
||||
mockMvc.perform(get("/public/api/1/name-for-day").param("dayOfWeek", Integer.toString(5)))
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getNameOfDayByNumberRequestParam_whenGetWithRequestParamOutOfRange_thenReturn400() throws Exception {
|
||||
mockMvc.perform(get("/public/api/1/name-for-day").param("dayOfWeek", Integer.toString(15)))
|
||||
.andExpect(status().isBadRequest());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getNameOfDayByPathVariable_whenGetWithProperRequestParam_thenReturn200() throws Exception {
|
||||
mockMvc.perform(get("/public/api/1/name-for-day/{dayOfWeek}", Integer.toString(5))).andExpect(status().isOk());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getNameOfDayByPathVariable_whenGetWithRequestParamOutOfRange_thenReturn400() throws Exception {
|
||||
mockMvc.perform(get("/public/api/1/name-for-day/{dayOfWeek}", Integer.toString(15)))
|
||||
.andExpect(status().isBadRequest());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validStringRequestParam_whenGetWithProperRequestParam_thenReturn200() throws Exception {
|
||||
mockMvc.perform(get("/public/api/1/valid-name").param("name", "John")).andExpect(status().isOk());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validStringRequestParam_whenGetWithTooLongRequestParam_thenReturn400() throws Exception {
|
||||
mockMvc.perform(get("/public/api/1/valid-name").param("name", "asdfghjklqw"))
|
||||
.andExpect(status().isBadRequest());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validStringRequestParam_whenGetWithLowerCaseRequestParam_thenReturn400() throws Exception {
|
||||
mockMvc.perform(get("/public/api/1/valid-name").param("name", "john")).andExpect(status().isBadRequest());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
*.class
|
||||
|
||||
#folders#
|
||||
/target
|
||||
/neoDb*
|
||||
/data
|
||||
/src/main/webapp/WEB-INF/classes
|
||||
*/META-INF/*
|
||||
|
||||
# Packaged files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
@@ -0,0 +1,32 @@
|
||||
## Spring REST Query Language
|
||||
|
||||
This module contains articles about the REST query language with Spring
|
||||
|
||||
### Courses
|
||||
|
||||
The "REST With Spring" Classes: http://bit.ly/restwithspring
|
||||
|
||||
The "Learn Spring Security" Classes: http://github.learnspringsecurity.com
|
||||
|
||||
### Relevant Articles:
|
||||
|
||||
- [REST Query Language with Spring and JPA Criteria](https://www.baeldung.com/rest-search-language-spring-jpa-criteria)
|
||||
- [REST Query Language with Spring Data JPA Specifications](https://www.baeldung.com/rest-api-search-language-spring-data-specifications)
|
||||
- [REST Query Language with Spring Data JPA and QueryDSL](https://www.baeldung.com/rest-api-search-language-spring-data-querydsl)
|
||||
- [REST Query Language – Advanced Search Operations](https://www.baeldung.com/rest-api-query-search-language-more-operations)
|
||||
- [REST Query Language with RSQL](https://www.baeldung.com/rest-api-search-language-rsql-fiql)
|
||||
- [REST Query Language – Implementing OR Operation](https://www.baeldung.com/rest-api-query-search-or-operation)
|
||||
|
||||
### Build the Project
|
||||
```
|
||||
mvn clean install
|
||||
```
|
||||
|
||||
### Set up MySQL
|
||||
```
|
||||
mysql -u root -p
|
||||
> CREATE USER 'tutorialuser'@'localhost' IDENTIFIED BY 'tutorialmy5ql';
|
||||
> GRANT ALL PRIVILEGES ON *.* TO 'tutorialuser'@'localhost';
|
||||
> FLUSH PRIVILEGES;
|
||||
```
|
||||
|
||||
@@ -0,0 +1,359 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>spring-rest-query-language</artifactId>
|
||||
<version>0.1-SNAPSHOT</version>
|
||||
<name>spring-rest-query-language</name>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- Spring Boot Dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.tomcat.embed</groupId>
|
||||
<artifactId>tomcat-embed-jasper</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-expression</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-commons</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- deployment -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Querydsl -->
|
||||
|
||||
<dependency>
|
||||
<groupId>com.querydsl</groupId>
|
||||
<artifactId>querydsl-apt</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.querydsl</groupId>
|
||||
<artifactId>querydsl-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Rsql -->
|
||||
|
||||
<dependency>
|
||||
<groupId>cz.jirutka.rsql</groupId>
|
||||
<artifactId>rsql-parser</artifactId>
|
||||
<version>${rsql.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- web -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpcore</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- persistence -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-orm</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>xml-apis</groupId>
|
||||
<artifactId>xml-apis</artifactId>
|
||||
<version>${xml-apis.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
<version>${javassist.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- web -->
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>jstl</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- marshalling -->
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.thoughtworks.xstream</groupId>
|
||||
<artifactId>xstream</artifactId>
|
||||
<version>${xstream.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- util -->
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- test scoped -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>spring-rest-query-language</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.codehaus.cargo</groupId>
|
||||
<artifactId>cargo-maven2-plugin</artifactId>
|
||||
<version>${cargo-maven2-plugin.version}</version>
|
||||
<configuration>
|
||||
<wait>true</wait>
|
||||
<container>
|
||||
<containerId>jetty8x</containerId>
|
||||
<type>embedded</type>
|
||||
<systemProperties>
|
||||
<!-- <provPersistenceTarget>cargo</provPersistenceTarget> -->
|
||||
</systemProperties>
|
||||
</container>
|
||||
<configuration>
|
||||
<properties>
|
||||
<cargo.servlet.port>8082</cargo.servlet.port>
|
||||
</properties>
|
||||
</configuration>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!-- Querydsl and Specifications -->
|
||||
|
||||
<plugin>
|
||||
<groupId>com.mysema.maven</groupId>
|
||||
<artifactId>apt-maven-plugin</artifactId>
|
||||
<version>${apt-maven-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>process</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>target/generated-sources/java</outputDirectory>
|
||||
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>live</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>integration-test</phase>
|
||||
<goals>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/*IntegrationTest.java</exclude>
|
||||
<exclude>**/*IntTest.java</exclude>
|
||||
</excludes>
|
||||
<includes>
|
||||
<include>**/*LiveTest.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<test.mime>json</test.mime>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.cargo</groupId>
|
||||
<artifactId>cargo-maven2-plugin</artifactId>
|
||||
<configuration>
|
||||
<wait>false</wait>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>start-server</id>
|
||||
<phase>pre-integration-test</phase>
|
||||
<goals>
|
||||
<goal>start</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>stop-server</id>
|
||||
<phase>post-integration-test</phase>
|
||||
<goals>
|
||||
<goal>stop</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<properties>
|
||||
<!-- persistence -->
|
||||
<rsql.version>2.1.0</rsql.version>
|
||||
|
||||
<!-- various -->
|
||||
<xstream.version>1.4.9</xstream.version>
|
||||
<javassist.version>3.21.0-GA</javassist.version>
|
||||
<xml-apis.version>1.4.01</xml-apis.version>
|
||||
|
||||
<!-- util -->
|
||||
<guava.version>19.0</guava.version>
|
||||
|
||||
<!-- Maven plugins -->
|
||||
<cargo-maven2-plugin.version>1.7.0</cargo-maven2-plugin.version>
|
||||
<apt-maven-plugin.version>1.1.3</apt-maven-plugin.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
package com.baeldung.persistence.dao;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Deque;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
|
||||
import com.baeldung.web.util.SearchOperation;
|
||||
import com.baeldung.web.util.SpecSearchCriteria;
|
||||
|
||||
public class GenericSpecificationsBuilder<U> {
|
||||
|
||||
private final List<SpecSearchCriteria> params;
|
||||
|
||||
public GenericSpecificationsBuilder() {
|
||||
this.params = new ArrayList<>();
|
||||
}
|
||||
|
||||
public final GenericSpecificationsBuilder<U> with(final String key, final String operation, final Object value, final String prefix, final String suffix) {
|
||||
return with(null, key, operation, value, prefix, suffix);
|
||||
}
|
||||
|
||||
public final GenericSpecificationsBuilder<U> with(final String precedenceIndicator, final String key, final String operation, final Object value, final String prefix, final String suffix) {
|
||||
SearchOperation op = SearchOperation.getSimpleOperation(operation.charAt(0));
|
||||
if (op != null) {
|
||||
if (op == SearchOperation.EQUALITY) // the operation may be complex operation
|
||||
{
|
||||
final boolean startWithAsterisk = prefix != null && prefix.contains(SearchOperation.ZERO_OR_MORE_REGEX);
|
||||
final boolean endWithAsterisk = suffix != null && suffix.contains(SearchOperation.ZERO_OR_MORE_REGEX);
|
||||
|
||||
if (startWithAsterisk && endWithAsterisk) {
|
||||
op = SearchOperation.CONTAINS;
|
||||
} else if (startWithAsterisk) {
|
||||
op = SearchOperation.ENDS_WITH;
|
||||
} else if (endWithAsterisk) {
|
||||
op = SearchOperation.STARTS_WITH;
|
||||
}
|
||||
}
|
||||
params.add(new SpecSearchCriteria(precedenceIndicator, key, op, value));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Specification<U> build(Function<SpecSearchCriteria, Specification<U>> converter) {
|
||||
|
||||
if (params.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<Specification<U>> specs = params.stream()
|
||||
.map(converter)
|
||||
.collect(Collectors.toCollection(ArrayList::new));
|
||||
|
||||
Specification<U> result = specs.get(0);
|
||||
|
||||
for (int idx = 1; idx < specs.size(); idx++) {
|
||||
result = params.get(idx)
|
||||
.isOrPredicate()
|
||||
? Specification.where(result)
|
||||
.or(specs.get(idx))
|
||||
: Specification.where(result)
|
||||
.and(specs.get(idx));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Specification<U> build(Deque<?> postFixedExprStack, Function<SpecSearchCriteria, Specification<U>> converter) {
|
||||
|
||||
Deque<Specification<U>> specStack = new LinkedList<>();
|
||||
|
||||
Collections.reverse((List<?>) postFixedExprStack);
|
||||
|
||||
while (!postFixedExprStack.isEmpty()) {
|
||||
Object mayBeOperand = postFixedExprStack.pop();
|
||||
|
||||
if (!(mayBeOperand instanceof String)) {
|
||||
specStack.push(converter.apply((SpecSearchCriteria) mayBeOperand));
|
||||
} else {
|
||||
Specification<U> operand1 = specStack.pop();
|
||||
Specification<U> operand2 = specStack.pop();
|
||||
if (mayBeOperand.equals(SearchOperation.AND_OPERATOR))
|
||||
specStack.push(Specification.where(operand1)
|
||||
.and(operand2));
|
||||
else if (mayBeOperand.equals(SearchOperation.OR_OPERATOR))
|
||||
specStack.push(Specification.where(operand1)
|
||||
.or(operand2));
|
||||
}
|
||||
|
||||
}
|
||||
return specStack.pop();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.baeldung.persistence.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.baeldung.persistence.model.User;
|
||||
import com.baeldung.web.util.SearchCriteria;
|
||||
|
||||
public interface IUserDAO {
|
||||
List<User> searchUser(List<SearchCriteria> params);
|
||||
|
||||
void save(User entity);
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package com.baeldung.persistence.dao;
|
||||
|
||||
import com.baeldung.persistence.model.MyUser;
|
||||
import com.baeldung.web.util.SearchCriteria;
|
||||
import com.querydsl.core.types.dsl.BooleanExpression;
|
||||
import com.querydsl.core.types.dsl.NumberPath;
|
||||
import com.querydsl.core.types.dsl.PathBuilder;
|
||||
import com.querydsl.core.types.dsl.StringPath;
|
||||
|
||||
public class MyUserPredicate {
|
||||
|
||||
private SearchCriteria criteria;
|
||||
|
||||
public MyUserPredicate(final SearchCriteria criteria) {
|
||||
this.criteria = criteria;
|
||||
}
|
||||
|
||||
public BooleanExpression getPredicate() {
|
||||
final PathBuilder<MyUser> entityPath = new PathBuilder<>(MyUser.class, "myUser");
|
||||
|
||||
if (isNumeric(criteria.getValue().toString())) {
|
||||
final NumberPath<Integer> path = entityPath.getNumber(criteria.getKey(), Integer.class);
|
||||
final int value = Integer.parseInt(criteria.getValue().toString());
|
||||
switch (criteria.getOperation()) {
|
||||
case ":":
|
||||
return path.eq(value);
|
||||
case ">":
|
||||
return path.goe(value);
|
||||
case "<":
|
||||
return path.loe(value);
|
||||
}
|
||||
} else {
|
||||
final StringPath path = entityPath.getString(criteria.getKey());
|
||||
if (criteria.getOperation().equalsIgnoreCase(":")) {
|
||||
return path.containsIgnoreCase(criteria.getValue().toString());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public SearchCriteria getCriteria() {
|
||||
return criteria;
|
||||
}
|
||||
|
||||
public void setCriteria(final SearchCriteria criteria) {
|
||||
this.criteria = criteria;
|
||||
}
|
||||
|
||||
public static boolean isNumeric(final String str) {
|
||||
try {
|
||||
Integer.parseInt(str);
|
||||
} catch (final NumberFormatException e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package com.baeldung.persistence.dao;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.baeldung.web.util.SearchCriteria;
|
||||
import com.querydsl.core.types.dsl.BooleanExpression;
|
||||
import com.querydsl.core.types.dsl.Expressions;
|
||||
|
||||
public final class MyUserPredicatesBuilder {
|
||||
private final List<SearchCriteria> params;
|
||||
|
||||
public MyUserPredicatesBuilder() {
|
||||
params = new ArrayList<>();
|
||||
}
|
||||
|
||||
public MyUserPredicatesBuilder with(final String key, final String operation, final Object value) {
|
||||
params.add(new SearchCriteria(key, operation, value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BooleanExpression build() {
|
||||
if (params.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<BooleanExpression> predicates = params.stream().map(param -> {
|
||||
MyUserPredicate predicate = new MyUserPredicate(param);
|
||||
return predicate.getPredicate();
|
||||
}).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
|
||||
BooleanExpression result = Expressions.asBoolean(true).isTrue();
|
||||
for (BooleanExpression predicate : predicates) {
|
||||
result = result.and(predicate);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static class BooleanExpressionWrapper {
|
||||
|
||||
private BooleanExpression result;
|
||||
|
||||
public BooleanExpressionWrapper(final BooleanExpression result) {
|
||||
super();
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public BooleanExpression getResult() {
|
||||
return result;
|
||||
}
|
||||
public void setResult(BooleanExpression result) {
|
||||
this.result = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.baeldung.persistence.dao;
|
||||
|
||||
import com.baeldung.persistence.model.QMyUser;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
|
||||
import org.springframework.data.querydsl.binding.QuerydslBinderCustomizer;
|
||||
import org.springframework.data.querydsl.binding.QuerydslBindings;
|
||||
import org.springframework.data.querydsl.binding.SingleValueBinding;
|
||||
|
||||
import com.baeldung.persistence.model.MyUser;
|
||||
import com.querydsl.core.types.dsl.StringExpression;
|
||||
import com.querydsl.core.types.dsl.StringPath;
|
||||
|
||||
public interface MyUserRepository extends JpaRepository<MyUser, Long>, QuerydslPredicateExecutor<MyUser>, QuerydslBinderCustomizer<QMyUser> {
|
||||
@Override
|
||||
default public void customize(final QuerydslBindings bindings, final QMyUser root) {
|
||||
bindings.bind(String.class)
|
||||
.first((SingleValueBinding<StringPath, String>) StringExpression::containsIgnoreCase);
|
||||
bindings.excluding(root.email);
|
||||
}
|
||||
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package com.baeldung.persistence.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.baeldung.persistence.model.User;
|
||||
import com.baeldung.web.util.SearchCriteria;
|
||||
|
||||
@Repository
|
||||
public class UserDAO implements IUserDAO {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Override
|
||||
public List<User> searchUser(final List<SearchCriteria> params) {
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<User> query = builder.createQuery(User.class);
|
||||
final Root r = query.from(User.class);
|
||||
|
||||
Predicate predicate = builder.conjunction();
|
||||
UserSearchQueryCriteriaConsumer searchConsumer = new UserSearchQueryCriteriaConsumer(predicate, builder, r);
|
||||
params.stream().forEach(searchConsumer);
|
||||
predicate = searchConsumer.getPredicate();
|
||||
query.where(predicate);
|
||||
|
||||
return entityManager.createQuery(query).getResultList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(final User entity) {
|
||||
entityManager.persist(entity);
|
||||
}
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.baeldung.persistence.dao;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
|
||||
import com.baeldung.persistence.model.User;
|
||||
|
||||
public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {
|
||||
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package com.baeldung.persistence.dao;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
import com.baeldung.web.util.SearchCriteria;
|
||||
|
||||
public class UserSearchQueryCriteriaConsumer implements Consumer<SearchCriteria>{
|
||||
|
||||
private Predicate predicate;
|
||||
private CriteriaBuilder builder;
|
||||
private Root r;
|
||||
|
||||
public UserSearchQueryCriteriaConsumer(Predicate predicate, CriteriaBuilder builder, Root r) {
|
||||
super();
|
||||
this.predicate = predicate;
|
||||
this.builder = builder;
|
||||
this.r= r;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(SearchCriteria param) {
|
||||
|
||||
if (param.getOperation().equalsIgnoreCase(">")) {
|
||||
predicate = builder.and(predicate, builder.greaterThanOrEqualTo(r.get(param.getKey()), param.getValue().toString()));
|
||||
} else if (param.getOperation().equalsIgnoreCase("<")) {
|
||||
predicate = builder.and(predicate, builder.lessThanOrEqualTo(r.get(param.getKey()), param.getValue().toString()));
|
||||
} else if (param.getOperation().equalsIgnoreCase(":")) {
|
||||
if (r.get(param.getKey()).getJavaType() == String.class) {
|
||||
predicate = builder.and(predicate, builder.like(r.get(param.getKey()), "%" + param.getValue() + "%"));
|
||||
} else {
|
||||
predicate = builder.and(predicate, builder.equal(r.get(param.getKey()), param.getValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Predicate getPredicate() {
|
||||
return predicate;
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
package com.baeldung.persistence.dao;
|
||||
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
|
||||
import com.baeldung.persistence.model.User;
|
||||
import com.baeldung.web.util.SpecSearchCriteria;
|
||||
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
public class UserSpecification implements Specification<User> {
|
||||
|
||||
private SpecSearchCriteria criteria;
|
||||
|
||||
public UserSpecification(final SpecSearchCriteria criteria) {
|
||||
super();
|
||||
this.criteria = criteria;
|
||||
}
|
||||
|
||||
public SpecSearchCriteria getCriteria() {
|
||||
return criteria;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Predicate toPredicate(final Root<User> root, final CriteriaQuery<?> query, final CriteriaBuilder builder) {
|
||||
switch (criteria.getOperation()) {
|
||||
case EQUALITY:
|
||||
return builder.equal(root.get(criteria.getKey()), criteria.getValue());
|
||||
case NEGATION:
|
||||
return builder.notEqual(root.get(criteria.getKey()), criteria.getValue());
|
||||
case GREATER_THAN:
|
||||
return builder.greaterThan(root.get(criteria.getKey()), criteria.getValue().toString());
|
||||
case LESS_THAN:
|
||||
return builder.lessThan(root.get(criteria.getKey()), criteria.getValue().toString());
|
||||
case LIKE:
|
||||
return builder.like(root.get(criteria.getKey()), criteria.getValue().toString());
|
||||
case STARTS_WITH:
|
||||
return builder.like(root.get(criteria.getKey()), criteria.getValue() + "%");
|
||||
case ENDS_WITH:
|
||||
return builder.like(root.get(criteria.getKey()), "%" + criteria.getValue());
|
||||
case CONTAINS:
|
||||
return builder.like(root.get(criteria.getKey()), "%" + criteria.getValue() + "%");
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
package com.baeldung.persistence.dao;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
|
||||
import com.baeldung.persistence.model.User;
|
||||
import com.baeldung.web.util.SearchOperation;
|
||||
import com.baeldung.web.util.SpecSearchCriteria;
|
||||
|
||||
public final class UserSpecificationsBuilder {
|
||||
|
||||
private final List<SpecSearchCriteria> params;
|
||||
|
||||
public UserSpecificationsBuilder() {
|
||||
params = new ArrayList<>();
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
public final UserSpecificationsBuilder with(final String key, final String operation, final Object value, final String prefix, final String suffix) {
|
||||
return with(null, key, operation, value, prefix, suffix);
|
||||
}
|
||||
|
||||
public final UserSpecificationsBuilder with(final String orPredicate, final String key, final String operation, final Object value, final String prefix, final String suffix) {
|
||||
SearchOperation op = SearchOperation.getSimpleOperation(operation.charAt(0));
|
||||
if (op != null) {
|
||||
if (op == SearchOperation.EQUALITY) { // the operation may be complex operation
|
||||
final boolean startWithAsterisk = prefix != null && prefix.contains(SearchOperation.ZERO_OR_MORE_REGEX);
|
||||
final boolean endWithAsterisk = suffix != null && suffix.contains(SearchOperation.ZERO_OR_MORE_REGEX);
|
||||
|
||||
if (startWithAsterisk && endWithAsterisk) {
|
||||
op = SearchOperation.CONTAINS;
|
||||
} else if (startWithAsterisk) {
|
||||
op = SearchOperation.ENDS_WITH;
|
||||
} else if (endWithAsterisk) {
|
||||
op = SearchOperation.STARTS_WITH;
|
||||
}
|
||||
}
|
||||
params.add(new SpecSearchCriteria(orPredicate, key, op, value));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Specification<User> build() {
|
||||
if (params.size() == 0)
|
||||
return null;
|
||||
|
||||
Specification<User> result = new UserSpecification(params.get(0));
|
||||
|
||||
for (int i = 1; i < params.size(); i++) {
|
||||
result = params.get(i).isOrPredicate()
|
||||
? Specification.where(result).or(new UserSpecification(params.get(i)))
|
||||
: Specification.where(result).and(new UserSpecification(params.get(i)));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public final UserSpecificationsBuilder with(UserSpecification spec) {
|
||||
params.add(spec.getCriteria());
|
||||
return this;
|
||||
}
|
||||
|
||||
public final UserSpecificationsBuilder with(SpecSearchCriteria criteria) {
|
||||
params.add(criteria);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package com.baeldung.persistence.dao.rsql;
|
||||
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
|
||||
import cz.jirutka.rsql.parser.ast.AndNode;
|
||||
import cz.jirutka.rsql.parser.ast.ComparisonNode;
|
||||
import cz.jirutka.rsql.parser.ast.OrNode;
|
||||
import cz.jirutka.rsql.parser.ast.RSQLVisitor;
|
||||
|
||||
public class CustomRsqlVisitor<T> implements RSQLVisitor<Specification<T>, Void> {
|
||||
|
||||
private GenericRsqlSpecBuilder<T> builder;
|
||||
|
||||
public CustomRsqlVisitor() {
|
||||
builder = new GenericRsqlSpecBuilder<T>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Specification<T> visit(final AndNode node, final Void param) {
|
||||
return builder.createSpecification(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Specification<T> visit(final OrNode node, final Void param) {
|
||||
return builder.createSpecification(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Specification<T> visit(final ComparisonNode node, final Void params) {
|
||||
return builder.createSpecification(node);
|
||||
}
|
||||
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
package com.baeldung.persistence.dao.rsql;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
|
||||
import cz.jirutka.rsql.parser.ast.ComparisonNode;
|
||||
import cz.jirutka.rsql.parser.ast.LogicalNode;
|
||||
import cz.jirutka.rsql.parser.ast.LogicalOperator;
|
||||
import cz.jirutka.rsql.parser.ast.Node;
|
||||
|
||||
public class GenericRsqlSpecBuilder<T> {
|
||||
|
||||
public Specification<T> createSpecification(final Node node) {
|
||||
if (node instanceof LogicalNode) {
|
||||
return createSpecification((LogicalNode) node);
|
||||
}
|
||||
if (node instanceof ComparisonNode) {
|
||||
return createSpecification((ComparisonNode) node);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Specification<T> createSpecification(final LogicalNode logicalNode) {
|
||||
|
||||
List<Specification<T>> specs = logicalNode.getChildren()
|
||||
.stream()
|
||||
.map(node -> createSpecification(node))
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Specification<T> result = specs.get(0);
|
||||
if (logicalNode.getOperator() == LogicalOperator.AND) {
|
||||
for (int i = 1; i < specs.size(); i++) {
|
||||
result = Specification.where(result).and(specs.get(i));
|
||||
}
|
||||
}
|
||||
else if (logicalNode.getOperator() == LogicalOperator.OR) {
|
||||
for (int i = 1; i < specs.size(); i++) {
|
||||
result = Specification.where(result).or(specs.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Specification<T> createSpecification(final ComparisonNode comparisonNode) {
|
||||
return Specification.where(new GenericRsqlSpecification<T>(comparisonNode.getSelector(), comparisonNode.getOperator(), comparisonNode.getArguments()));
|
||||
}
|
||||
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
package com.baeldung.persistence.dao.rsql;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
|
||||
import cz.jirutka.rsql.parser.ast.ComparisonOperator;
|
||||
|
||||
public class GenericRsqlSpecification<T> implements Specification<T> {
|
||||
|
||||
private String property;
|
||||
private ComparisonOperator operator;
|
||||
private List<String> arguments;
|
||||
|
||||
public GenericRsqlSpecification(final String property, final ComparisonOperator operator, final List<String> arguments) {
|
||||
super();
|
||||
this.property = property;
|
||||
this.operator = operator;
|
||||
this.arguments = arguments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Predicate toPredicate(final Root<T> root, final CriteriaQuery<?> query, final CriteriaBuilder builder) {
|
||||
final List<Object> args = castArguments(root);
|
||||
final Object argument = args.get(0);
|
||||
switch (RsqlSearchOperation.getSimpleOperator(operator)) {
|
||||
|
||||
case EQUAL: {
|
||||
if (argument instanceof String) {
|
||||
return builder.like(root.get(property), argument.toString().replace('*', '%'));
|
||||
} else if (argument == null) {
|
||||
return builder.isNull(root.get(property));
|
||||
} else {
|
||||
return builder.equal(root.get(property), argument);
|
||||
}
|
||||
}
|
||||
case NOT_EQUAL: {
|
||||
if (argument instanceof String) {
|
||||
return builder.notLike(root.<String> get(property), argument.toString().replace('*', '%'));
|
||||
} else if (argument == null) {
|
||||
return builder.isNotNull(root.get(property));
|
||||
} else {
|
||||
return builder.notEqual(root.get(property), argument);
|
||||
}
|
||||
}
|
||||
case GREATER_THAN: {
|
||||
return builder.greaterThan(root.<String> get(property), argument.toString());
|
||||
}
|
||||
case GREATER_THAN_OR_EQUAL: {
|
||||
return builder.greaterThanOrEqualTo(root.<String> get(property), argument.toString());
|
||||
}
|
||||
case LESS_THAN: {
|
||||
return builder.lessThan(root.<String> get(property), argument.toString());
|
||||
}
|
||||
case LESS_THAN_OR_EQUAL: {
|
||||
return builder.lessThanOrEqualTo(root.<String> get(property), argument.toString());
|
||||
}
|
||||
case IN:
|
||||
return root.get(property).in(args);
|
||||
case NOT_IN:
|
||||
return builder.not(root.get(property).in(args));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// === private
|
||||
|
||||
private List<Object> castArguments(final Root<T> root) {
|
||||
|
||||
final Class<? extends Object> type = root.get(property).getJavaType();
|
||||
|
||||
final List<Object> args = arguments.stream().map(arg -> {
|
||||
if (type.equals(Integer.class)) {
|
||||
return Integer.parseInt(arg);
|
||||
} else if (type.equals(Long.class)) {
|
||||
return Long.parseLong(arg);
|
||||
} else {
|
||||
return arg;
|
||||
}
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.baeldung.persistence.dao.rsql;
|
||||
|
||||
import cz.jirutka.rsql.parser.ast.ComparisonOperator;
|
||||
import cz.jirutka.rsql.parser.ast.RSQLOperators;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public enum RsqlSearchOperation {
|
||||
EQUAL(RSQLOperators.EQUAL), NOT_EQUAL(RSQLOperators.NOT_EQUAL), GREATER_THAN(RSQLOperators.GREATER_THAN), GREATER_THAN_OR_EQUAL(RSQLOperators.GREATER_THAN_OR_EQUAL), LESS_THAN(RSQLOperators.LESS_THAN), LESS_THAN_OR_EQUAL(
|
||||
RSQLOperators.LESS_THAN_OR_EQUAL), IN(RSQLOperators.IN), NOT_IN(RSQLOperators.NOT_IN);
|
||||
|
||||
private ComparisonOperator operator;
|
||||
|
||||
RsqlSearchOperation(final ComparisonOperator operator) {
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
public static RsqlSearchOperation getSimpleOperator(final ComparisonOperator operator) {
|
||||
return Arrays.stream(values())
|
||||
.filter(operation -> operation.getOperator() == operator)
|
||||
.findAny().orElse(null);
|
||||
}
|
||||
|
||||
public ComparisonOperator getOperator() {
|
||||
return operator;
|
||||
}
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
package com.baeldung.persistence.model;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
||||
// used for Querydsl test
|
||||
|
||||
@Entity
|
||||
public class MyUser {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String firstName;
|
||||
|
||||
private String lastName;
|
||||
|
||||
private String email;
|
||||
|
||||
private int age;
|
||||
|
||||
public MyUser() {
|
||||
super();
|
||||
}
|
||||
|
||||
public MyUser(final String firstName, final String lastName, final String email, final int age) {
|
||||
super();
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
this.email = email;
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(final Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(final String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(final String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(final String username) {
|
||||
email = username;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(final int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((email == null) ? 0 : email.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
final MyUser user = (MyUser) obj;
|
||||
if (!email.equals(user.email))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append("MyUser [firstName=").append(firstName).append("]").append("[lastName=").append(lastName).append("]").append("[username").append(email).append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
package com.baeldung.persistence.model;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class User {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String firstName;
|
||||
|
||||
private String lastName;
|
||||
|
||||
private String email;
|
||||
|
||||
private int age;
|
||||
|
||||
public User() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(final Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(final String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(final String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(final String username) {
|
||||
email = username;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(final int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((email == null) ? 0 : email.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
final User user = (User) obj;
|
||||
return email.equals(user.email);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append("User [firstName=").append(firstName).append("]").append("[lastName=").append(lastName).append("]").append("[username").append(email).append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.baeldung.persistence.model;
|
||||
|
||||
import javax.persistence.metamodel.SingularAttribute;
|
||||
import javax.persistence.metamodel.StaticMetamodel;
|
||||
|
||||
@StaticMetamodel(User.class)
|
||||
public class User_ {
|
||||
public static volatile SingularAttribute<User, Long> id;
|
||||
public static volatile SingularAttribute<User, String> firstName;
|
||||
public static volatile SingularAttribute<User, String> lastName;
|
||||
public static volatile SingularAttribute<User, Integer> age;
|
||||
public static volatile SingularAttribute<User, String> email;
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.baeldung.spring;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.web.context.request.RequestContextListener;
|
||||
|
||||
/**
|
||||
* Main Application Class - uses Spring Boot. Just run this as a normal Java
|
||||
* class to run up a Jetty Server (on http://localhost:8082/spring-rest-query-language)
|
||||
*
|
||||
*/
|
||||
@EnableScheduling
|
||||
@EnableAutoConfiguration
|
||||
@ComponentScan("com.baeldung")
|
||||
@SpringBootApplication
|
||||
public class Application extends SpringBootServletInitializer {
|
||||
|
||||
@Override
|
||||
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
|
||||
return application.sources(Application.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartup(ServletContext sc) throws ServletException {
|
||||
// Manages the lifecycle of the root application context
|
||||
sc.addListener(new RequestContextListener());
|
||||
}
|
||||
|
||||
public static void main(final String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
package com.baeldung.spring;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
@Configuration
|
||||
@EnableTransactionManagement
|
||||
@PropertySource({ "classpath:persistence-${envTarget:h2}.properties" })
|
||||
@ComponentScan({ "com.baeldung.persistence" })
|
||||
// @ImportResource("classpath*:springDataPersistenceConfig.xml")
|
||||
@EnableJpaRepositories(basePackages = "com.baeldung.persistence.dao")
|
||||
public class PersistenceConfig {
|
||||
|
||||
@Autowired
|
||||
private Environment env;
|
||||
|
||||
public PersistenceConfig() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
|
||||
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
|
||||
em.setDataSource(dataSource());
|
||||
em.setPackagesToScan(new String[] { "com.baeldung.persistence.model" });
|
||||
|
||||
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
|
||||
// vendorAdapter.set
|
||||
em.setJpaVendorAdapter(vendorAdapter);
|
||||
em.setJpaProperties(additionalProperties());
|
||||
|
||||
return em;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource() {
|
||||
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
|
||||
dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName")));
|
||||
dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url")));
|
||||
dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user")));
|
||||
dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass")));
|
||||
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PlatformTransactionManager transactionManager() {
|
||||
final JpaTransactionManager transactionManager = new JpaTransactionManager();
|
||||
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
|
||||
|
||||
return transactionManager;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
|
||||
return new PersistenceExceptionTranslationPostProcessor();
|
||||
}
|
||||
|
||||
final Properties additionalProperties() {
|
||||
final Properties hibernateProperties = new Properties();
|
||||
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
|
||||
hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
|
||||
// hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true");
|
||||
return hibernateProperties;
|
||||
}
|
||||
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.baeldung.spring;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.ViewResolver;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
||||
|
||||
@Configuration
|
||||
@ComponentScan("com.baeldung.web")
|
||||
@EnableWebMvc
|
||||
public class WebConfig implements WebMvcConfigurer {
|
||||
|
||||
@Bean
|
||||
public ViewResolver viewResolver() {
|
||||
final InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
|
||||
viewResolver.setPrefix("/WEB-INF/view/");
|
||||
viewResolver.setSuffix(".jsp");
|
||||
return viewResolver;
|
||||
}
|
||||
|
||||
// API
|
||||
@Override
|
||||
public void addViewControllers(final ViewControllerRegistry registry) {
|
||||
registry.addViewController("/homepage.html");
|
||||
}
|
||||
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.baeldung.web.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
@Controller
|
||||
@RequestMapping(value = "/")
|
||||
public class HomeController {
|
||||
|
||||
public String index() {
|
||||
return "homepage";
|
||||
}
|
||||
|
||||
}
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
package com.baeldung.web.controller;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.data.querydsl.binding.QuerydslPredicate;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
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.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
||||
import com.baeldung.persistence.dao.GenericSpecificationsBuilder;
|
||||
import com.baeldung.persistence.dao.IUserDAO;
|
||||
import com.baeldung.persistence.dao.MyUserPredicatesBuilder;
|
||||
import com.baeldung.persistence.dao.MyUserRepository;
|
||||
import com.baeldung.persistence.dao.UserRepository;
|
||||
import com.baeldung.persistence.dao.UserSpecification;
|
||||
import com.baeldung.persistence.dao.UserSpecificationsBuilder;
|
||||
import com.baeldung.persistence.dao.rsql.CustomRsqlVisitor;
|
||||
import com.baeldung.persistence.model.MyUser;
|
||||
import com.baeldung.persistence.model.User;
|
||||
import com.baeldung.web.util.CriteriaParser;
|
||||
import com.baeldung.web.util.SearchCriteria;
|
||||
import com.baeldung.web.util.SearchOperation;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.querydsl.core.types.Predicate;
|
||||
import com.querydsl.core.types.dsl.BooleanExpression;
|
||||
|
||||
import cz.jirutka.rsql.parser.RSQLParser;
|
||||
import cz.jirutka.rsql.parser.ast.Node;
|
||||
|
||||
//@EnableSpringDataWebSupport
|
||||
@Controller
|
||||
@RequestMapping(value = "/auth/")
|
||||
public class UserController {
|
||||
|
||||
@Autowired
|
||||
private IUserDAO service;
|
||||
|
||||
@Autowired
|
||||
private UserRepository dao;
|
||||
|
||||
@Autowired
|
||||
private MyUserRepository myUserRepository;
|
||||
|
||||
public UserController() {
|
||||
super();
|
||||
}
|
||||
|
||||
// API - READ
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/users")
|
||||
@ResponseBody
|
||||
public List<User> search(@RequestParam(value = "search", required = false) String search) {
|
||||
List<SearchCriteria> params = new ArrayList<SearchCriteria>();
|
||||
if (search != null) {
|
||||
Pattern pattern = Pattern.compile("(\\w+?)(:|<|>)(\\w+?),");
|
||||
Matcher matcher = pattern.matcher(search + ",");
|
||||
while (matcher.find()) {
|
||||
params.add(new SearchCriteria(matcher.group(1), matcher.group(2), matcher.group(3)));
|
||||
}
|
||||
}
|
||||
return service.searchUser(params);
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/users/spec")
|
||||
@ResponseBody
|
||||
public List<User> findAllBySpecification(@RequestParam(value = "search") String search) {
|
||||
UserSpecificationsBuilder builder = new UserSpecificationsBuilder();
|
||||
String operationSetExper = Joiner.on("|")
|
||||
.join(SearchOperation.SIMPLE_OPERATION_SET);
|
||||
Pattern pattern = Pattern.compile("(\\w+?)(" + operationSetExper + ")(\\p{Punct}?)(\\w+?)(\\p{Punct}?),");
|
||||
Matcher matcher = pattern.matcher(search + ",");
|
||||
while (matcher.find()) {
|
||||
builder.with(matcher.group(1), matcher.group(2), matcher.group(4), matcher.group(3), matcher.group(5));
|
||||
}
|
||||
|
||||
Specification<User> spec = builder.build();
|
||||
return dao.findAll(spec);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/users/espec")
|
||||
@ResponseBody
|
||||
public List<User> findAllByOrPredicate(@RequestParam(value = "search") String search) {
|
||||
Specification<User> spec = resolveSpecification(search);
|
||||
return dao.findAll(spec);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/users/spec/adv")
|
||||
@ResponseBody
|
||||
public List<User> findAllByAdvPredicate(@RequestParam(value = "search") String search) {
|
||||
Specification<User> spec = resolveSpecificationFromInfixExpr(search);
|
||||
return dao.findAll(spec);
|
||||
}
|
||||
|
||||
protected Specification<User> resolveSpecificationFromInfixExpr(String searchParameters) {
|
||||
CriteriaParser parser = new CriteriaParser();
|
||||
GenericSpecificationsBuilder<User> specBuilder = new GenericSpecificationsBuilder<>();
|
||||
return specBuilder.build(parser.parse(searchParameters), UserSpecification::new);
|
||||
}
|
||||
|
||||
protected Specification<User> resolveSpecification(String searchParameters) {
|
||||
|
||||
UserSpecificationsBuilder builder = new UserSpecificationsBuilder();
|
||||
String operationSetExper = Joiner.on("|")
|
||||
.join(SearchOperation.SIMPLE_OPERATION_SET);
|
||||
Pattern pattern = Pattern.compile("(\\p{Punct}?)(\\w+?)(" + operationSetExper + ")(\\p{Punct}?)(\\w+?)(\\p{Punct}?),");
|
||||
Matcher matcher = pattern.matcher(searchParameters + ",");
|
||||
while (matcher.find()) {
|
||||
builder.with(matcher.group(1), matcher.group(2), matcher.group(3), matcher.group(5), matcher.group(4), matcher.group(6));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/myusers")
|
||||
@ResponseBody
|
||||
public Iterable<MyUser> findAllByQuerydsl(@RequestParam(value = "search") String search) {
|
||||
MyUserPredicatesBuilder builder = new MyUserPredicatesBuilder();
|
||||
if (search != null) {
|
||||
Pattern pattern = Pattern.compile("(\\w+?)(:|<|>)(\\w+?),");
|
||||
Matcher matcher = pattern.matcher(search + ",");
|
||||
while (matcher.find()) {
|
||||
builder.with(matcher.group(1), matcher.group(2), matcher.group(3));
|
||||
}
|
||||
}
|
||||
BooleanExpression exp = builder.build();
|
||||
return myUserRepository.findAll(exp);
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/users/rsql")
|
||||
@ResponseBody
|
||||
public List<User> findAllByRsql(@RequestParam(value = "search") String search) {
|
||||
Node rootNode = new RSQLParser().parse(search);
|
||||
Specification<User> spec = rootNode.accept(new CustomRsqlVisitor<User>());
|
||||
return dao.findAll(spec);
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/api/myusers")
|
||||
@ResponseBody
|
||||
public Iterable<MyUser> findAllByWebQuerydsl(@QuerydslPredicate(root = MyUser.class) Predicate predicate) {
|
||||
return myUserRepository.findAll(predicate);
|
||||
}
|
||||
|
||||
// API - WRITE
|
||||
|
||||
@RequestMapping(method = RequestMethod.POST, value = "/users")
|
||||
@ResponseStatus(HttpStatus.CREATED)
|
||||
public void create(@RequestBody User resource) {
|
||||
Preconditions.checkNotNull(resource);
|
||||
dao.save(resource);
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.POST, value = "/myusers")
|
||||
@ResponseStatus(HttpStatus.CREATED)
|
||||
public void addMyUser(@RequestBody MyUser resource) {
|
||||
Preconditions.checkNotNull(resource);
|
||||
myUserRepository.save(resource);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
package com.baeldung.web.error;
|
||||
|
||||
import javax.persistence.EntityNotFoundException;
|
||||
|
||||
import org.hibernate.exception.ConstraintViolationException;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
|
||||
|
||||
import com.baeldung.web.exception.MyResourceNotFoundException;
|
||||
|
||||
@ControllerAdvice
|
||||
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
|
||||
|
||||
public RestResponseEntityExceptionHandler() {
|
||||
super();
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
// 400
|
||||
|
||||
@ExceptionHandler({ ConstraintViolationException.class })
|
||||
public ResponseEntity<Object> handleBadRequest(final ConstraintViolationException ex, final WebRequest request) {
|
||||
final String bodyOfResponse = "This should be application specific";
|
||||
return handleExceptionInternal(ex, bodyOfResponse, new HttpHeaders(), HttpStatus.BAD_REQUEST, request);
|
||||
}
|
||||
|
||||
@ExceptionHandler({ DataIntegrityViolationException.class })
|
||||
public ResponseEntity<Object> handleBadRequest(final DataIntegrityViolationException ex, final WebRequest request) {
|
||||
final String bodyOfResponse = "This should be application specific";
|
||||
return handleExceptionInternal(ex, bodyOfResponse, new HttpHeaders(), HttpStatus.BAD_REQUEST, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseEntity<Object> handleHttpMessageNotReadable(final HttpMessageNotReadableException ex, final HttpHeaders headers, final HttpStatus status, final WebRequest request) {
|
||||
final String bodyOfResponse = "This should be application specific";
|
||||
// ex.getCause() instanceof JsonMappingException, JsonParseException // for additional information later on
|
||||
return handleExceptionInternal(ex, bodyOfResponse, headers, HttpStatus.BAD_REQUEST, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseEntity<Object> handleMethodArgumentNotValid(final MethodArgumentNotValidException ex, final HttpHeaders headers, final HttpStatus status, final WebRequest request) {
|
||||
final String bodyOfResponse = "This should be application specific";
|
||||
return handleExceptionInternal(ex, bodyOfResponse, headers, HttpStatus.BAD_REQUEST, request);
|
||||
}
|
||||
|
||||
|
||||
// 404
|
||||
|
||||
@ExceptionHandler(value = { EntityNotFoundException.class, MyResourceNotFoundException.class })
|
||||
protected ResponseEntity<Object> handleNotFound(final RuntimeException ex, final WebRequest request) {
|
||||
final String bodyOfResponse = "This should be application specific";
|
||||
return handleExceptionInternal(ex, bodyOfResponse, new HttpHeaders(), HttpStatus.NOT_FOUND, request);
|
||||
}
|
||||
|
||||
// 409
|
||||
|
||||
@ExceptionHandler({ InvalidDataAccessApiUsageException.class, DataAccessException.class })
|
||||
protected ResponseEntity<Object> handleConflict(final RuntimeException ex, final WebRequest request) {
|
||||
final String bodyOfResponse = "This should be application specific";
|
||||
return handleExceptionInternal(ex, bodyOfResponse, new HttpHeaders(), HttpStatus.CONFLICT, request);
|
||||
}
|
||||
|
||||
// 412
|
||||
|
||||
// 500
|
||||
|
||||
@ExceptionHandler({ NullPointerException.class, IllegalArgumentException.class, IllegalStateException.class })
|
||||
/*500*/public ResponseEntity<Object> handleInternal(final RuntimeException ex, final WebRequest request) {
|
||||
logger.error("500 Status Code", ex);
|
||||
final String bodyOfResponse = "This should be application specific";
|
||||
return handleExceptionInternal(ex, bodyOfResponse, new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR, request);
|
||||
}
|
||||
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.baeldung.web.exception;
|
||||
|
||||
public final class MyResourceNotFoundException extends RuntimeException {
|
||||
|
||||
public MyResourceNotFoundException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public MyResourceNotFoundException(final String message, final Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public MyResourceNotFoundException(final String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public MyResourceNotFoundException(final Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
package com.baeldung.web.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Deque;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
|
||||
public class CriteriaParser {
|
||||
|
||||
private static Map<String, Operator> ops;
|
||||
|
||||
private static Pattern SpecCriteraRegex = Pattern.compile("^(\\w+?)(" + Joiner.on("|")
|
||||
.join(SearchOperation.SIMPLE_OPERATION_SET) + ")(\\p{Punct}?)(\\w+?)(\\p{Punct}?)$");
|
||||
|
||||
private enum Operator {
|
||||
OR(1), AND(2);
|
||||
final int precedence;
|
||||
|
||||
Operator(int p) {
|
||||
precedence = p;
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
Map<String, Operator> tempMap = new HashMap<>();
|
||||
tempMap.put("AND", Operator.AND);
|
||||
tempMap.put("OR", Operator.OR);
|
||||
tempMap.put("or", Operator.OR);
|
||||
tempMap.put("and", Operator.AND);
|
||||
|
||||
ops = Collections.unmodifiableMap(tempMap);
|
||||
}
|
||||
|
||||
private static boolean isHigerPrecedenceOperator(String currOp, String prevOp) {
|
||||
return (ops.containsKey(prevOp) && ops.get(prevOp).precedence >= ops.get(currOp).precedence);
|
||||
}
|
||||
|
||||
public Deque<?> parse(String searchParam) {
|
||||
|
||||
Deque<Object> output = new LinkedList<>();
|
||||
Deque<String> stack = new LinkedList<>();
|
||||
|
||||
Arrays.stream(searchParam.split("\\s+")).forEach(token -> {
|
||||
if (ops.containsKey(token)) {
|
||||
while (!stack.isEmpty() && isHigerPrecedenceOperator(token, stack.peek()))
|
||||
output.push(stack.pop()
|
||||
.equalsIgnoreCase(SearchOperation.OR_OPERATOR) ? SearchOperation.OR_OPERATOR : SearchOperation.AND_OPERATOR);
|
||||
stack.push(token.equalsIgnoreCase(SearchOperation.OR_OPERATOR) ? SearchOperation.OR_OPERATOR : SearchOperation.AND_OPERATOR);
|
||||
} else if (token.equals(SearchOperation.LEFT_PARANTHESIS)) {
|
||||
stack.push(SearchOperation.LEFT_PARANTHESIS);
|
||||
} else if (token.equals(SearchOperation.RIGHT_PARANTHESIS)) {
|
||||
while (!stack.peek()
|
||||
.equals(SearchOperation.LEFT_PARANTHESIS))
|
||||
output.push(stack.pop());
|
||||
stack.pop();
|
||||
} else {
|
||||
|
||||
Matcher matcher = SpecCriteraRegex.matcher(token);
|
||||
while (matcher.find()) {
|
||||
output.push(new SpecSearchCriteria(matcher.group(1), matcher.group(2), matcher.group(3), matcher.group(4), matcher.group(5)));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
while (!stack.isEmpty())
|
||||
output.push(stack.pop());
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package com.baeldung.web.util;
|
||||
|
||||
public class SearchCriteria {
|
||||
|
||||
private String key;
|
||||
private String operation;
|
||||
private Object value;
|
||||
|
||||
public SearchCriteria() {
|
||||
|
||||
}
|
||||
|
||||
public SearchCriteria(final String key, final String operation, final Object value) {
|
||||
super();
|
||||
this.key = key;
|
||||
this.operation = operation;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(final String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String getOperation() {
|
||||
return operation;
|
||||
}
|
||||
|
||||
public void setOperation(final String operation) {
|
||||
this.operation = operation;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(final Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package com.baeldung.web.util;
|
||||
|
||||
public enum SearchOperation {
|
||||
EQUALITY, NEGATION, GREATER_THAN, LESS_THAN, LIKE, STARTS_WITH, ENDS_WITH, CONTAINS;
|
||||
|
||||
public static final String[] SIMPLE_OPERATION_SET = { ":", "!", ">", "<", "~" };
|
||||
|
||||
public static final String OR_PREDICATE_FLAG = "'";
|
||||
|
||||
public static final String ZERO_OR_MORE_REGEX = "*";
|
||||
|
||||
public static final String OR_OPERATOR = "OR";
|
||||
|
||||
public static final String AND_OPERATOR = "AND";
|
||||
|
||||
public static final String LEFT_PARANTHESIS = "(";
|
||||
|
||||
public static final String RIGHT_PARANTHESIS = ")";
|
||||
|
||||
public static SearchOperation getSimpleOperation(final char input) {
|
||||
switch (input) {
|
||||
case ':':
|
||||
return EQUALITY;
|
||||
case '!':
|
||||
return NEGATION;
|
||||
case '>':
|
||||
return GREATER_THAN;
|
||||
case '<':
|
||||
return LESS_THAN;
|
||||
case '~':
|
||||
return LIKE;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
package com.baeldung.web.util;
|
||||
|
||||
public class SpecSearchCriteria {
|
||||
|
||||
private String key;
|
||||
private SearchOperation operation;
|
||||
private Object value;
|
||||
private boolean orPredicate;
|
||||
|
||||
public SpecSearchCriteria() {
|
||||
|
||||
}
|
||||
|
||||
public SpecSearchCriteria(final String key, final SearchOperation operation, final Object value) {
|
||||
super();
|
||||
this.key = key;
|
||||
this.operation = operation;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public SpecSearchCriteria(final String orPredicate, final String key, final SearchOperation operation, final Object value) {
|
||||
super();
|
||||
this.orPredicate = orPredicate != null && orPredicate.equals(SearchOperation.OR_PREDICATE_FLAG);
|
||||
this.key = key;
|
||||
this.operation = operation;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public SpecSearchCriteria(String key, String operation, String prefix, String value, String suffix) {
|
||||
SearchOperation op = SearchOperation.getSimpleOperation(operation.charAt(0));
|
||||
if (op != null) {
|
||||
if (op == SearchOperation.EQUALITY) { // the operation may be complex operation
|
||||
final boolean startWithAsterisk = prefix != null && prefix.contains(SearchOperation.ZERO_OR_MORE_REGEX);
|
||||
final boolean endWithAsterisk = suffix != null && suffix.contains(SearchOperation.ZERO_OR_MORE_REGEX);
|
||||
|
||||
if (startWithAsterisk && endWithAsterisk) {
|
||||
op = SearchOperation.CONTAINS;
|
||||
} else if (startWithAsterisk) {
|
||||
op = SearchOperation.ENDS_WITH;
|
||||
} else if (endWithAsterisk) {
|
||||
op = SearchOperation.STARTS_WITH;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.key = key;
|
||||
this.operation = op;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(final String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public SearchOperation getOperation() {
|
||||
return operation;
|
||||
}
|
||||
|
||||
public void setOperation(final SearchOperation operation) {
|
||||
this.operation = operation;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(final Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public boolean isOrPredicate() {
|
||||
return orPredicate;
|
||||
}
|
||||
|
||||
public void setOrPredicate(boolean orPredicate) {
|
||||
this.orPredicate = orPredicate;
|
||||
}
|
||||
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
server.port=8082
|
||||
server.servlet.context-path=/spring-rest-query-language
|
||||
@@ -0,0 +1,5 @@
|
||||
insert into User (id, firstName, lastName, email, age) values (1, 'john', 'doe', 'john@doe.com', 22);
|
||||
insert into User (id, firstName, lastName, email, age) values (2, 'tom', 'doe', 'tom@doe.com', 26);
|
||||
|
||||
insert into MyUser (id, firstName, lastName, email, age) values (1, 'john', 'doe', 'john@doe.com', 22);
|
||||
insert into MyUser (id, firstName, lastName, email, age) values (2, 'tom', 'doe', 'tom@doe.com', 26);
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="org.springframework" level="WARN" />
|
||||
<logger name="org.springframework.transaction" level="WARN" />
|
||||
|
||||
<!-- in order to debug some marshalling issues, this needs to be TRACE -->
|
||||
<logger name="org.springframework.web.servlet.mvc" level="WARN" />
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
## jdbc.X
|
||||
#jdbc.driverClassName=com.mysql.jdbc.Driver
|
||||
#jdbc.url=jdbc:mysql://localhost:3306/spring_hibernate4_01?createDatabaseIfNotExist=true
|
||||
#jdbc.user=tutorialuser
|
||||
#jdbc.pass=tutorialmy5ql
|
||||
#
|
||||
## hibernate.X
|
||||
#hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
|
||||
#hibernate.show_sql=false
|
||||
#hibernate.hbm2ddl.auto=create-drop
|
||||
|
||||
|
||||
# jdbc.X
|
||||
jdbc.driverClassName=org.h2.Driver
|
||||
jdbc.url=jdbc:h2:mem:security_permission;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
|
||||
jdbc.user=sa
|
||||
jdbc.pass=
|
||||
|
||||
# hibernate.X
|
||||
hibernate.dialect=org.hibernate.dialect.H2Dialect
|
||||
hibernate.show_sql=false
|
||||
hibernate.hbm2ddl.auto=create-drop
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
# jdbc.X
|
||||
jdbc.driverClassName=com.mysql.jdbc.Driver
|
||||
jdbc.url=jdbc:mysql://localhost:3306/spring_hibernate4_01?createDatabaseIfNotExist=true
|
||||
jdbc.user=tutorialuser
|
||||
jdbc.pass=tutorialmy5ql
|
||||
|
||||
# hibernate.X
|
||||
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
|
||||
hibernate.show_sql=false
|
||||
hibernate.hbm2ddl.auto=create-drop
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/data/jpa
|
||||
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"
|
||||
>
|
||||
|
||||
<jpa:repositories base-package="com.baeldung.persistence.dao"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd" >
|
||||
|
||||
</beans>
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<head></head>
|
||||
|
||||
<body>
|
||||
<h1>This is the body of the sample view</h1>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
|
||||
xsi:schemaLocation="
|
||||
http://java.sun.com/xml/ns/javaee
|
||||
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"
|
||||
>
|
||||
|
||||
<display-name>Spring REST Query language Application</display-name>
|
||||
|
||||
<!-- Spring root -->
|
||||
<context-param>
|
||||
<param-name>contextClass</param-name>
|
||||
<param-value>
|
||||
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
|
||||
</param-value>
|
||||
</context-param>
|
||||
<context-param>
|
||||
<param-name>contextConfigLocation</param-name>
|
||||
<param-value>com.baeldung.spring</param-value>
|
||||
</context-param>
|
||||
|
||||
<listener>
|
||||
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
|
||||
</listener>
|
||||
|
||||
<!-- Spring child -->
|
||||
<servlet>
|
||||
<servlet-name>api</servlet-name>
|
||||
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>api</servlet-name>
|
||||
<url-pattern>/</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
|
||||
<welcome-file-list>
|
||||
<welcome-file>index.html</welcome-file>
|
||||
</welcome-file-list>
|
||||
|
||||
</web-app>
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.baeldung;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import com.baeldung.spring.Application;
|
||||
|
||||
/**
|
||||
* Note: In the IDE, remember to generate query type classes before running the Integration Test (e.g. in Eclipse right-click on the project > Run As > Maven generate sources)
|
||||
*
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = Application.class)
|
||||
public class SpringContextTest {
|
||||
|
||||
@Test
|
||||
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
|
||||
}
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
package com.baeldung.persistence.query;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.collection.IsIn.isIn;
|
||||
import static org.hamcrest.core.IsNot.not;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.annotation.Rollback;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.baeldung.persistence.dao.IUserDAO;
|
||||
import com.baeldung.persistence.model.User;
|
||||
import com.baeldung.spring.PersistenceConfig;
|
||||
import com.baeldung.web.util.SearchCriteria;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = { PersistenceConfig.class })
|
||||
@Transactional
|
||||
@Rollback
|
||||
public class JPACriteriaQueryIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private IUserDAO userApi;
|
||||
|
||||
private User userJohn;
|
||||
|
||||
private User userTom;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
userJohn = new User();
|
||||
userJohn.setFirstName("john");
|
||||
userJohn.setLastName("doe");
|
||||
userJohn.setEmail("john@doe.com");
|
||||
userJohn.setAge(22);
|
||||
userApi.save(userJohn);
|
||||
|
||||
userTom = new User();
|
||||
userTom.setFirstName("tom");
|
||||
userTom.setLastName("doe");
|
||||
userTom.setEmail("tom@doe.com");
|
||||
userTom.setAge(26);
|
||||
userApi.save(userTom);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFirstAndLastName_whenGettingListOfUsers_thenCorrect() {
|
||||
final List<SearchCriteria> params = new ArrayList<SearchCriteria>();
|
||||
params.add(new SearchCriteria("firstName", ":", "john"));
|
||||
params.add(new SearchCriteria("lastName", ":", "doe"));
|
||||
|
||||
final List<User> results = userApi.searchUser(params);
|
||||
|
||||
assertThat(userJohn, isIn(results));
|
||||
assertThat(userTom, not(isIn(results)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenLast_whenGettingListOfUsers_thenCorrect() {
|
||||
final List<SearchCriteria> params = new ArrayList<SearchCriteria>();
|
||||
params.add(new SearchCriteria("lastName", ":", "doe"));
|
||||
|
||||
final List<User> results = userApi.searchUser(params);
|
||||
assertThat(userJohn, isIn(results));
|
||||
assertThat(userTom, isIn(results));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenLastAndAge_whenGettingListOfUsers_thenCorrect() {
|
||||
final List<SearchCriteria> params = new ArrayList<SearchCriteria>();
|
||||
params.add(new SearchCriteria("lastName", ":", "doe"));
|
||||
params.add(new SearchCriteria("age", ">", "25"));
|
||||
|
||||
final List<User> results = userApi.searchUser(params);
|
||||
|
||||
assertThat(userTom, isIn(results));
|
||||
assertThat(userJohn, not(isIn(results)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenWrongFirstAndLast_whenGettingListOfUsers_thenCorrect() {
|
||||
final List<SearchCriteria> params = new ArrayList<SearchCriteria>();
|
||||
params.add(new SearchCriteria("firstName", ":", "adam"));
|
||||
params.add(new SearchCriteria("lastName", ":", "fox"));
|
||||
|
||||
final List<User> results = userApi.searchUser(params);
|
||||
assertThat(userJohn, not(isIn(results)));
|
||||
assertThat(userTom, not(isIn(results)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPartialFirst_whenGettingListOfUsers_thenCorrect() {
|
||||
final List<SearchCriteria> params = new ArrayList<SearchCriteria>();
|
||||
params.add(new SearchCriteria("firstName", ":", "jo"));
|
||||
|
||||
final List<User> results = userApi.searchUser(params);
|
||||
|
||||
assertThat(userJohn, isIn(results));
|
||||
assertThat(userTom, not(isIn(results)));
|
||||
}
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
package com.baeldung.persistence.query;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.collection.IsEmptyIterable.emptyIterable;
|
||||
import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
|
||||
import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
|
||||
import static org.hamcrest.core.IsNot.not;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.annotation.Rollback;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.baeldung.persistence.dao.MyUserPredicatesBuilder;
|
||||
import com.baeldung.persistence.dao.MyUserRepository;
|
||||
import com.baeldung.persistence.model.MyUser;
|
||||
import com.baeldung.spring.PersistenceConfig;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = { PersistenceConfig.class })
|
||||
@Transactional
|
||||
@Rollback
|
||||
public class JPAQuerydslIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private MyUserRepository repo;
|
||||
|
||||
private MyUser userJohn;
|
||||
|
||||
private MyUser userTom;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
userJohn = new MyUser();
|
||||
userJohn.setFirstName("john");
|
||||
userJohn.setLastName("doe");
|
||||
userJohn.setEmail("john@doe.com");
|
||||
userJohn.setAge(22);
|
||||
repo.save(userJohn);
|
||||
|
||||
userTom = new MyUser();
|
||||
userTom.setFirstName("tom");
|
||||
userTom.setLastName("doe");
|
||||
userTom.setEmail("tom@doe.com");
|
||||
userTom.setAge(26);
|
||||
repo.save(userTom);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenLast_whenGettingListOfUsers_thenCorrect() {
|
||||
final MyUserPredicatesBuilder builder = new MyUserPredicatesBuilder().with("lastName", ":", "doe");
|
||||
|
||||
final Iterable<MyUser> results = repo.findAll(builder.build());
|
||||
assertThat(results, containsInAnyOrder(userJohn, userTom));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFirstAndLastName_whenGettingListOfUsers_thenCorrect() {
|
||||
final MyUserPredicatesBuilder builder = new MyUserPredicatesBuilder().with("firstName", ":", "john").with("lastName", ":", "doe");
|
||||
|
||||
final Iterable<MyUser> results = repo.findAll(builder.build());
|
||||
|
||||
assertThat(results, contains(userJohn));
|
||||
assertThat(results, not(contains(userTom)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenLastAndAge_whenGettingListOfUsers_thenCorrect() {
|
||||
final MyUserPredicatesBuilder builder = new MyUserPredicatesBuilder().with("lastName", ":", "doe").with("age", ">", "25");
|
||||
|
||||
final Iterable<MyUser> results = repo.findAll(builder.build());
|
||||
|
||||
assertThat(results, contains(userTom));
|
||||
assertThat(results, not(contains(userJohn)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenWrongFirstAndLast_whenGettingListOfUsers_thenCorrect() {
|
||||
final MyUserPredicatesBuilder builder = new MyUserPredicatesBuilder().with("firstName", ":", "adam").with("lastName", ":", "fox");
|
||||
|
||||
final Iterable<MyUser> results = repo.findAll(builder.build());
|
||||
assertThat(results, emptyIterable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPartialFirst_whenGettingListOfUsers_thenCorrect() {
|
||||
final MyUserPredicatesBuilder builder = new MyUserPredicatesBuilder().with("firstName", ":", "jo");
|
||||
|
||||
final Iterable<MyUser> results = repo.findAll(builder.build());
|
||||
|
||||
assertThat(results, contains(userJohn));
|
||||
assertThat(results, not(contains(userTom)));
|
||||
}
|
||||
}
|
||||
+180
@@ -0,0 +1,180 @@
|
||||
package com.baeldung.persistence.query;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.test.annotation.Rollback;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.baeldung.persistence.dao.GenericSpecificationsBuilder;
|
||||
import com.baeldung.persistence.dao.UserRepository;
|
||||
import com.baeldung.persistence.dao.UserSpecification;
|
||||
import com.baeldung.persistence.dao.UserSpecificationsBuilder;
|
||||
import com.baeldung.persistence.model.User;
|
||||
import com.baeldung.spring.PersistenceConfig;
|
||||
import com.baeldung.web.util.CriteriaParser;
|
||||
import com.baeldung.web.util.SearchOperation;
|
||||
import com.baeldung.web.util.SpecSearchCriteria;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
|
||||
import static org.hamcrest.collection.IsIn.isIn;
|
||||
import static org.hamcrest.core.IsNot.not;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = { PersistenceConfig.class })
|
||||
@Transactional
|
||||
@Rollback
|
||||
public class JPASpecificationIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private UserRepository repository;
|
||||
|
||||
private User userJohn;
|
||||
|
||||
private User userTom;
|
||||
|
||||
private User userPercy;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
userJohn = new User();
|
||||
userJohn.setFirstName("john");
|
||||
userJohn.setLastName("doe");
|
||||
userJohn.setEmail("john@doe.com");
|
||||
userJohn.setAge(22);
|
||||
repository.save(userJohn);
|
||||
|
||||
userTom = new User();
|
||||
userTom.setFirstName("tom");
|
||||
userTom.setLastName("doe");
|
||||
userTom.setEmail("tom@doe.com");
|
||||
userTom.setAge(26);
|
||||
repository.save(userTom);
|
||||
|
||||
userPercy = new User();
|
||||
userPercy.setFirstName("percy");
|
||||
userPercy.setLastName("blackney");
|
||||
userPercy.setEmail("percy@blackney.com");
|
||||
userPercy.setAge(30);
|
||||
repository.save(userPercy);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFirstAndLastName_whenGettingListOfUsers_thenCorrect() {
|
||||
final UserSpecification spec = new UserSpecification(new SpecSearchCriteria("firstName", SearchOperation.EQUALITY, "john"));
|
||||
final UserSpecification spec1 = new UserSpecification(new SpecSearchCriteria("lastName", SearchOperation.EQUALITY, "doe"));
|
||||
final List<User> results = repository.findAll(Specification
|
||||
.where(spec)
|
||||
.and(spec1));
|
||||
|
||||
assertThat(userJohn, isIn(results));
|
||||
assertThat(userTom, not(isIn(results)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFirstOrLastName_whenGettingListOfUsers_thenCorrect() {
|
||||
UserSpecificationsBuilder builder = new UserSpecificationsBuilder();
|
||||
|
||||
SpecSearchCriteria spec = new SpecSearchCriteria("firstName", SearchOperation.EQUALITY, "john");
|
||||
SpecSearchCriteria spec1 = new SpecSearchCriteria("'","lastName", SearchOperation.EQUALITY, "doe");
|
||||
|
||||
List<User> results = repository.findAll(builder
|
||||
.with(spec)
|
||||
.with(spec1)
|
||||
.build());
|
||||
|
||||
assertThat(results, hasSize(2));
|
||||
assertThat(userJohn, isIn(results));
|
||||
assertThat(userTom, isIn(results));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFirstOrLastNameAndAgeGenericBuilder_whenGettingListOfUsers_thenCorrect() {
|
||||
GenericSpecificationsBuilder<User> builder = new GenericSpecificationsBuilder<>();
|
||||
Function<SpecSearchCriteria, Specification<User>> converter = UserSpecification::new;
|
||||
|
||||
CriteriaParser parser=new CriteriaParser();
|
||||
List<User> results = repository.findAll(builder.build(parser.parse("( lastName:doe OR firstName:john ) AND age:22"), converter));
|
||||
|
||||
assertThat(results, hasSize(1));
|
||||
assertThat(userJohn, isIn(results));
|
||||
assertThat(userTom, not(isIn(results)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFirstOrLastNameGenericBuilder_whenGettingListOfUsers_thenCorrect() {
|
||||
GenericSpecificationsBuilder<User> builder = new GenericSpecificationsBuilder<>();
|
||||
Function<SpecSearchCriteria, Specification<User>> converter = UserSpecification::new;
|
||||
|
||||
builder.with("firstName", ":", "john", null, null);
|
||||
builder.with("'", "lastName", ":", "doe", null, null);
|
||||
|
||||
List<User> results = repository.findAll(builder.build(converter));
|
||||
|
||||
assertThat(results, hasSize(2));
|
||||
assertThat(userJohn, isIn(results));
|
||||
assertThat(userTom, isIn(results));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFirstNameInverse_whenGettingListOfUsers_thenCorrect() {
|
||||
final UserSpecification spec = new UserSpecification(new SpecSearchCriteria("firstName", SearchOperation.NEGATION, "john"));
|
||||
final List<User> results = repository.findAll(Specification.where(spec));
|
||||
|
||||
assertThat(userTom, isIn(results));
|
||||
assertThat(userJohn, not(isIn(results)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenMinAge_whenGettingListOfUsers_thenCorrect() {
|
||||
final UserSpecification spec = new UserSpecification(new SpecSearchCriteria("age", SearchOperation.GREATER_THAN, "25"));
|
||||
final List<User> results = repository.findAll(Specification.where(spec));
|
||||
assertThat(userTom, isIn(results));
|
||||
assertThat(userJohn, not(isIn(results)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFirstNamePrefix_whenGettingListOfUsers_thenCorrect() {
|
||||
final UserSpecification spec = new UserSpecification(new SpecSearchCriteria("firstName", SearchOperation.STARTS_WITH, "jo"));
|
||||
final List<User> results = repository.findAll(spec);
|
||||
assertThat(userJohn, isIn(results));
|
||||
assertThat(userTom, not(isIn(results)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFirstNameSuffix_whenGettingListOfUsers_thenCorrect() {
|
||||
final UserSpecification spec = new UserSpecification(new SpecSearchCriteria("firstName", SearchOperation.ENDS_WITH, "n"));
|
||||
final List<User> results = repository.findAll(spec);
|
||||
assertThat(userJohn, isIn(results));
|
||||
assertThat(userTom, not(isIn(results)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFirstNameSubstring_whenGettingListOfUsers_thenCorrect() {
|
||||
final UserSpecification spec = new UserSpecification(new SpecSearchCriteria("firstName", SearchOperation.CONTAINS, "oh"));
|
||||
final List<User> results = repository.findAll(spec);
|
||||
|
||||
assertThat(userJohn, isIn(results));
|
||||
assertThat(userTom, not(isIn(results)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAgeRange_whenGettingListOfUsers_thenCorrect() {
|
||||
final UserSpecification spec = new UserSpecification(new SpecSearchCriteria("age", SearchOperation.GREATER_THAN, "20"));
|
||||
final UserSpecification spec1 = new UserSpecification(new SpecSearchCriteria("age", SearchOperation.LESS_THAN, "25"));
|
||||
final List<User> results = repository.findAll(Specification
|
||||
.where(spec)
|
||||
.and(spec1));
|
||||
|
||||
assertThat(userJohn, isIn(results));
|
||||
assertThat(userTom, not(isIn(results)));
|
||||
}
|
||||
}
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
package com.baeldung.persistence.query;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.response.Response;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
|
||||
import com.baeldung.persistence.model.User;
|
||||
|
||||
//@RunWith(SpringJUnit4ClassRunner.class)
|
||||
//@ContextConfiguration(classes = { ConfigTest.class,
|
||||
// PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class)
|
||||
@ActiveProfiles("test")
|
||||
public class JPASpecificationLiveTest {
|
||||
|
||||
// @Autowired
|
||||
// private UserRepository repository;
|
||||
|
||||
private User userJohn;
|
||||
|
||||
private User userTom;
|
||||
|
||||
private final String URL_PREFIX = "http://localhost:8082/spring-rest-query-language/auth/users/spec?search=";
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
userJohn = new User();
|
||||
userJohn.setFirstName("john");
|
||||
userJohn.setLastName("doe");
|
||||
userJohn.setEmail("john@doe.com");
|
||||
userJohn.setAge(22);
|
||||
// repository.save(userJohn);
|
||||
|
||||
userTom = new User();
|
||||
userTom.setFirstName("tom");
|
||||
userTom.setLastName("doe");
|
||||
userTom.setEmail("tom@doe.com");
|
||||
userTom.setAge(26);
|
||||
// repository.save(userTom);
|
||||
}
|
||||
|
||||
private final String EURL_PREFIX = "http://localhost:8082/spring-rest-query-language/auth/users/espec?search=";
|
||||
|
||||
@Test
|
||||
public void givenFirstOrLastName_whenGettingListOfUsers_thenCorrect() {
|
||||
final Response response = RestAssured.get(EURL_PREFIX + "firstName:john,'lastName:doe");
|
||||
final String result = response.body()
|
||||
.asString();
|
||||
assertTrue(result.contains(userJohn.getEmail()));
|
||||
assertTrue(result.contains(userTom.getEmail()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFirstAndLastName_whenGettingListOfUsers_thenCorrect() {
|
||||
final Response response = RestAssured.get(URL_PREFIX + "firstName:john,lastName:doe");
|
||||
final String result = response.body()
|
||||
.asString();
|
||||
|
||||
assertTrue(result.contains(userJohn.getEmail()));
|
||||
assertFalse(result.contains(userTom.getEmail()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFirstNameInverse_whenGettingListOfUsers_thenCorrect() {
|
||||
final Response response = RestAssured.get(URL_PREFIX + "firstName!john");
|
||||
final String result = response.body()
|
||||
.asString();
|
||||
|
||||
assertTrue(result.contains(userTom.getEmail()));
|
||||
assertFalse(result.contains(userJohn.getEmail()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenMinAge_whenGettingListOfUsers_thenCorrect() {
|
||||
final Response response = RestAssured.get(URL_PREFIX + "age>25");
|
||||
final String result = response.body()
|
||||
.asString();
|
||||
|
||||
assertTrue(result.contains(userTom.getEmail()));
|
||||
assertFalse(result.contains(userJohn.getEmail()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFirstNamePrefix_whenGettingListOfUsers_thenCorrect() {
|
||||
final Response response = RestAssured.get(URL_PREFIX + "firstName:jo*");
|
||||
final String result = response.body()
|
||||
.asString();
|
||||
|
||||
assertTrue(result.contains(userJohn.getEmail()));
|
||||
assertFalse(result.contains(userTom.getEmail()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFirstNameSuffix_whenGettingListOfUsers_thenCorrect() {
|
||||
final Response response = RestAssured.get(URL_PREFIX + "firstName:*n");
|
||||
final String result = response.body()
|
||||
.asString();
|
||||
|
||||
assertTrue(result.contains(userJohn.getEmail()));
|
||||
assertFalse(result.contains(userTom.getEmail()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFirstNameSubstring_whenGettingListOfUsers_thenCorrect() {
|
||||
final Response response = RestAssured.get(URL_PREFIX + "firstName:*oh*");
|
||||
final String result = response.body()
|
||||
.asString();
|
||||
|
||||
assertTrue(result.contains(userJohn.getEmail()));
|
||||
assertFalse(result.contains(userTom.getEmail()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAgeRange_whenGettingListOfUsers_thenCorrect() {
|
||||
final Response response = RestAssured.get(URL_PREFIX + "age>20,age<25");
|
||||
final String result = response.body()
|
||||
.asString();
|
||||
|
||||
assertTrue(result.contains(userJohn.getEmail()));
|
||||
assertFalse(result.contains(userTom.getEmail()));
|
||||
}
|
||||
|
||||
private final String ADV_URL_PREFIX = "http://localhost:8082/spring-rest-query-language/auth/users/spec/adv?search=";
|
||||
|
||||
@Test
|
||||
public void givenFirstOrLastName_whenGettingAdvListOfUsers_thenCorrect() {
|
||||
final Response response = RestAssured.get(ADV_URL_PREFIX + "firstName:john OR lastName:doe");
|
||||
final String result = response.body()
|
||||
.asString();
|
||||
assertTrue(result.contains(userJohn.getEmail()));
|
||||
assertTrue(result.contains(userTom.getEmail()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFirstOrFirstNameAndAge_whenGettingAdvListOfUsers_thenCorrect() {
|
||||
final Response response = RestAssured.get(ADV_URL_PREFIX + "( firstName:john OR firstName:tom ) AND age>22");
|
||||
final String result = response.body()
|
||||
.asString();
|
||||
assertFalse(result.contains(userJohn.getEmail()));
|
||||
assertTrue(result.contains(userTom.getEmail()));
|
||||
}
|
||||
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
package com.baeldung.persistence.query;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.collection.IsIn.isIn;
|
||||
import static org.hamcrest.core.IsNot.not;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.test.annotation.Rollback;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.baeldung.persistence.dao.UserRepository;
|
||||
import com.baeldung.persistence.dao.rsql.CustomRsqlVisitor;
|
||||
import com.baeldung.persistence.model.User;
|
||||
import com.baeldung.spring.PersistenceConfig;
|
||||
|
||||
import cz.jirutka.rsql.parser.RSQLParser;
|
||||
import cz.jirutka.rsql.parser.ast.Node;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = { PersistenceConfig.class })
|
||||
@Transactional
|
||||
@Rollback
|
||||
public class RsqlIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private UserRepository repository;
|
||||
|
||||
private User userJohn;
|
||||
|
||||
private User userTom;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
userJohn = new User();
|
||||
userJohn.setFirstName("john");
|
||||
userJohn.setLastName("doe");
|
||||
userJohn.setEmail("john@doe.com");
|
||||
userJohn.setAge(22);
|
||||
repository.save(userJohn);
|
||||
|
||||
userTom = new User();
|
||||
userTom.setFirstName("tom");
|
||||
userTom.setLastName("doe");
|
||||
userTom.setEmail("tom@doe.com");
|
||||
userTom.setAge(26);
|
||||
repository.save(userTom);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFirstAndLastName_whenGettingListOfUsers_thenCorrect() {
|
||||
final Node rootNode = new RSQLParser().parse("firstName==john;lastName==doe");
|
||||
final Specification<User> spec = rootNode.accept(new CustomRsqlVisitor<User>());
|
||||
final List<User> results = repository.findAll(spec);
|
||||
|
||||
assertThat(userJohn, isIn(results));
|
||||
assertThat(userTom, not(isIn(results)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFirstNameInverse_whenGettingListOfUsers_thenCorrect() {
|
||||
final Node rootNode = new RSQLParser().parse("firstName!=john");
|
||||
final Specification<User> spec = rootNode.accept(new CustomRsqlVisitor<User>());
|
||||
final List<User> results = repository.findAll(spec);
|
||||
|
||||
assertThat(userTom, isIn(results));
|
||||
assertThat(userJohn, not(isIn(results)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenMinAge_whenGettingListOfUsers_thenCorrect() {
|
||||
final Node rootNode = new RSQLParser().parse("age>25");
|
||||
final Specification<User> spec = rootNode.accept(new CustomRsqlVisitor<User>());
|
||||
final List<User> results = repository.findAll(spec);
|
||||
|
||||
assertThat(userTom, isIn(results));
|
||||
assertThat(userJohn, not(isIn(results)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFirstNamePrefix_whenGettingListOfUsers_thenCorrect() {
|
||||
final Node rootNode = new RSQLParser().parse("firstName==jo*");
|
||||
final Specification<User> spec = rootNode.accept(new CustomRsqlVisitor<User>());
|
||||
final List<User> results = repository.findAll(spec);
|
||||
|
||||
assertThat(userJohn, isIn(results));
|
||||
assertThat(userTom, not(isIn(results)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenListOfFirstName_whenGettingListOfUsers_thenCorrect() {
|
||||
final Node rootNode = new RSQLParser().parse("firstName=in=(john,jack)");
|
||||
final Specification<User> spec = rootNode.accept(new CustomRsqlVisitor<User>());
|
||||
final List<User> results = repository.findAll(spec);
|
||||
|
||||
assertThat(userJohn, isIn(results));
|
||||
assertThat(userTom, not(isIn(results)));
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package com.baeldung.web;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.response.Response;
|
||||
import io.restassured.specification.RequestSpecification;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
|
||||
import com.baeldung.persistence.model.MyUser;
|
||||
|
||||
@ActiveProfiles("test")
|
||||
public class MyUserLiveTest {
|
||||
|
||||
private final MyUser userJohn = new MyUser("john", "doe", "john@doe.com", 11);
|
||||
private String URL_PREFIX = "http://localhost:8082/spring-rest-query-language/auth/api/myusers";
|
||||
|
||||
@Test
|
||||
public void whenGettingListOfUsers_thenCorrect() {
|
||||
final Response response = givenAuth().get(URL_PREFIX);
|
||||
final MyUser[] result = response.as(MyUser[].class);
|
||||
assertEquals(result.length, 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFirstName_whenGettingListOfUsers_thenCorrect() {
|
||||
final Response response = givenAuth().get(URL_PREFIX + "?firstName=john");
|
||||
final MyUser[] result = response.as(MyUser[].class);
|
||||
assertEquals(result.length, 1);
|
||||
assertEquals(result[0].getEmail(), userJohn.getEmail());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPartialLastName_whenGettingListOfUsers_thenCorrect() {
|
||||
final Response response = givenAuth().get(URL_PREFIX + "?lastName=do");
|
||||
final MyUser[] result = response.as(MyUser[].class);
|
||||
assertEquals(result.length, 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenEmail_whenGettingListOfUsers_thenIgnored() {
|
||||
final Response response = givenAuth().get(URL_PREFIX + "?email=john");
|
||||
final MyUser[] result = response.as(MyUser[].class);
|
||||
assertEquals(result.length, 2);
|
||||
}
|
||||
|
||||
private RequestSpecification givenAuth() {
|
||||
return RestAssured.given().auth().preemptive().basic("user1", "user1Pass");
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user