JRE does not come bundled with Windows or Mac OS X. In Linux, it depends on the distribution. • Java EE for Enterprise • Platform for developing backend services • Good compability with legacy systems • Web servers, application servers • Java ME for Mobile • Android uses Java language (Altough Kotlin is preferred), but does not support Java ME! • Support today....? 2
• Former name: Java 2 Platform Enterprise Edition (J2EE) • Set of specifications for enterprise applications • Java EE apps runs on application servers • https://javaee.github.io/tutorial/toc.html • Eclipse Foundation: Jakarta EE 8 • From 2019 Java EE was rebranded to Jakarta EE • Oracle does not maintain Java EE anymore • Eclipse does not own trademark Java, so Jakarta is used • https://eclipse-ee4j.github.io/jakartaee-tutorial/toc.html • Spring Boot is maybe more popular choice for backend
6 2011 (5 years) Java SE 7 2014 (4 years) Java SE 8 (LTS) 2017 September (3 years) Java SE 9 2018 March (6 months) Java SE 10 2018 September (6 months) Java SE 11 (LTS) 2019 March (6 months) Java SE 12 2019 September (6 months) Java SE 13 2020 March (6 months) Java SE 14 2020 September (6 months) Java SE 15 2021 March (6 months) Java SE 16 2021 September (6 months) Java SE 17 (LTS) 2022 March (6 months) Java SE 18 2022 September (6 months) Java SE 19
JSRs • There may be different vendor implementations for these specifications • For example object to relational database mapping has a specification JPA • Hibernate, EclipseLink, etc are the implementations of the JPA • Advantage: you can change the implementation! • Disadvantage: slow progress on specifications
by Sun Microsystems for Java EE • Reference implementation of Java EE • Supports • JAX-RS, EJB, JavaServer Faces / Pages, RMI, Servlets etc.. • Allows developers to create enterprise apps that are portable and scalable • Download • https://glassfish.java.net/download.html • Next version of GlassFish (Java EE 8) is under development and will be published in GitHub: • https://github.com/glassfish
features can be used with Java SE • Features embedded server • Alternative approach for EJBs and App Servers • Possible to create war packages that can be run on App Servers • Lot of modules • Data Access, Web ...
for creating stand-alone Spring Apps • Opinionated view of the Spring Platform • Features • Embed Tomcat or Jetty directly (no need for WAR files) • Provides POM files for Maven • Tries to automatically configure Spring whenever possible • No requirement for xml generation
tools like maven or gradle • Spring provides Spring Tool Suite (STS) which is basically an Eclipse Java EE with Spring plug-in • Or you can use Netbeans or IntelliJ IDEA CE / Ultimate
"modern" build tools • Very popular among Java • Easy, uses procedural programming idea • Uses XML which is not very good on the concept of procedural programming • XML can began to be very big • Maven (2004) • Uses also XML, but structure is different • Relies conventions and provides available targets (goals) • Has repository support (dependencies) • Gradle (2007) • Uses DSL instead of XML
build process • Maven offers sensible default behavior for projects • Maven creates a default project structure • Developer adds files to directories and writes configuration to pom.xml
• Base directory of your project • Information about the project and compiling process • Defines dependencies • The pom.xml can inherit a super pom, which provides basic configuration
<version>1.0</version> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> </properties> <dependencies> </dependencies> </project> artifact is a file and each artifact has a group id, usually like package in Java. Also version is defined. GroupId + artifactId + version creates uniquely identified artifact. Project's dependencies are specified as artifacts
static void main(String [] args) { try { String data = makeHttpRequest("https://jsonplaceholder.typicode.com/todos/"); // Output the first title JSONArray allTodos = new JSONArray(data); JSONObject todo = allTodos.getJSONObject(0); System.out.println(todo.getString("title")); } catch(URISyntaxException | IOException | InterruptedException e) { e.printStackTrace(); } } Will Fail! This is not part of java se!
main(String[] args) { SpringApplication.run(Application.class, args); } } Attempts to automatically configure your Spring application based on the jar dependencies that you have added. For example, If HSQLDB is on your classpath, and you have not manually configured any database connection beans, then we will auto-configure an in- memory database.
main(String[] args) { SpringApplication.run(Application.class, args); } } Indicates that a class declares one or more @Bean methods and may be processed by the Spring container to generate bean definitions and service requests for those beans at runtime. At this time no beans.
main(String[] args) { SpringApplication.run(Application.class, args); } } Search for other components, configurations in the specified package. If no package is specified, current class is taken as the root package.
org.springframework.context.annotation.Bean; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Bean public CommandLineRunner doIt() { class MyCommandLineRunner implements CommandLineRunner { public void run(String... args) { System.out.println("Hello World from @Bean!"); } } return new MyCommandLineRunner(); } } @SpringBootApplication contains @Configuration, so it detects methods with @Bean. The method is invoked for you and a new bean is created to container. The Bean created here implements special CommandLineRunner which creates a bean that is run when app starts
org.springframework.context.annotation.Bean; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Bean public CommandLineRunner doIt() { return (args) -> System.out.println("Hello World from @Bean!"); } } Using Java 8 Lambda
MyCommandLineRunner implements CommandLineRunner { public void run(String... args) { System.out.println("Hello World!"); } } Indicates that an annotated class is a Spring Bean "Component". Spring will create an object from this class for you calling the default constructor. Such classes are considered as candidates for auto-detection when using annotation-based configuration and classpath scanning.
Boot Developer Tools • Property defaults • Caching in templates is a good thing in production. In development phase it can be a bad thing. Developer tools disables caching. • Automatic restart • Restart server automatically when changes in classpath • LiveReload • Includes a embedded LiveReload server that triggers a browser refresh! • Needs browser extension from livereload.com
problems with annotations • Place main app class in the root package com +- example +- myproject +- Application.java | +- domain | +- Customer.java | +- CustomerRepository.java | +- service | +- CustomerService.java | +- web +- CustomerController.java
underlying implementation open • Default implementations are Java Util Logging, Log4J2 and Logback • By default, if you use spring- boot-starter-logging in pom.xml this is preconfigured to use Logback <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> <version>1.5.3.RELEASE</version> </dependency>
@SpringBootApplication public class LoggingDemoApplication implements CommandLineRunner { private Log logger = LogFactory.getLog(LoggingDemoApplication.class); public static void main(String[] args) { SpringApplication.run(LoggingDemoApplication.class, args); } @Override public void run(String... strings) throws Exception { logger.debug("This is a debug message"); logger.info("This is an info message"); logger.warn("This is a warn message"); logger.error("This is an error message"); } }
other part of the system • Changes break other parts of the system • Reuse is hard because components are tied up • Solution • Depend on abstractions, not concretions • Java: use interfaces, not implementations • Spring: Use spring container where beans are stored
the Spring Framework • Container will • create objects • wire them together • configure them • manage lifecycle • Objects in the Spring Container are called Spring Beans • What objects to instantiate? Configuration metadata • Can be xml, java annotations or java code
Car implements Movable { public void move() { System.out.println("Car is moving!"); } } Candidate for auto-detection when using annotation-based configuration and classpath scanning. Holds business logic.
Movable someMovebleObject; public void run(String... args) { someMovebleObject.move(); } } Candidate for auto-detection when using annotation-based configuration and classpath scanning. General Component. Marks a constructor, field, setter method or config method as to be autowired by Spring's dependency injection facilities.
void move() { System.out.println("Human is moving"); } } @Service("Car") public class Car implements Movable { public void move() { System.out.println("Car is moving!"); } }
classpath scanning • Special cases: • @Service • For businesslogic, no additional behaviour • @Repository • For data access object • @Controller • Used as a controller in Spring Web MVC
myBeanLogger; public void run(String... args) { System.out.println( myBeanLogger.getAllBeans() ); } } Common Bean that is created and added to Spring Container Interface used to indicate that a bean should run when it is contained within a SpringApplication. Inject here some bean that implements MyBeanLogger Use the implementation of the interface
@Override public String getAllBeans() { String allBeans = ""; String[] beanNames = applicationContext.getBeanDefinitionNames(); for (String beanName : beanNames) { allBeans += beanName + " : " + applicationContext.getBean(beanName).getClass().toString() + "\n"; } return allBeans; } } This is a bean that provides business logic Inject here some bean that implements ApplicationContext
it will have source of bean specifications • You may have one @Configuration or many • @Bean is a method level annotation • But in simple cases you don't need any configurations
return new Human(); } } Define a configuration of our beans. Now we dont' need the @Service in Human and it's possible to create the object in more detail (not just default constructor)
new operator and finalize() is invoked when garbage collector cleans the object • In Spring: define methods for init and destroy • @Bean: custom init() and destroy() • Or you can use @PostConstruct and @PreDestroy
a scope • Options • Singleton • Only single instance of the class, default • Prototype • Can have many any number of object instances • Note: Spring does not manage the complete lifecycle of a prototype bean: the container instantiates, configures, decorates and otherwise assembles a prototype object, hands it to the. Spring will not call destroy methods • For Web Development • request, session, global-session
private Car mercedes; @Autowired private Car bmw; public void run(String... args) { System.out.println(mercedes); System.out.println(mercedes.getMotor()); System.out.println(bmw); System.out.println(bmw.getMotor()); } } It is not necessary to use interfaces, but usually wise to do!
motor; public Car() { System.out.println("Constructor!, motor = " + motor); } public Motor getMotor() { return this.motor; } public void move() { System.out.println("Car is moving!"); } } It's null!
@Autowired public Car(Motor motor) { System.out.println("Constructor!"); this.motor = motor; } public Motor getMotor() { return this.motor; } public void move() { System.out.println("Car is moving!"); } } Use constructor based autowiring!
Controller architecture for Web apps • Separating • Model – POJO • View – Some View Engine, you can choose • Controller - @Controller • Framework is designed around DispatchServlet that handles all the HTTP requests and responses
to call appropriate Controller • Controller takes the request, makes perhaps business-logic calls and returns a View Name to the DispatcherServlet. Controller also modifies Model data. • DispatcherServlet takes the name and by using ViewResolver to pickup the the defined view • DispatcherServlet has the view and model data and it will create a view which can be rendered
web UI controllers or HTTP-based remote service exporters. • Is an actual Servlet that inherites HttpServlet • It can use any HandlerMapping implementation - pre-built or provided as part of an application - to control the routing of requests to handler objects • This is provided for you
a mapping between requests and handler objects. • This class can be implemented by application developers, although this is not necessary • Responsible for mapping the routes in @RequestMapping
you typically define through a service interface. • Controllers interpret user input and transform it into a model that is represented to the user by the view. • The @Controller annotation indicates that a particular class serves the role of a controller • Spring does not require you to extend any controller base class or reference the Servlet API
org.springframework.web.bind.annotation.ResponseBody; // This class acts as a controller. // Usually when using @Controller, you will use also @RequestMapping @Controller public class MyController { // When HTTP GET, POST, PUT or OTHER request happens // to http://localhost:8080/greeting // invoke this method @RequestMapping("/greeting") // The return value will be the HTTP Body @ResponseBody public String greeting() { return "Hello World"; } }
htmlHelper; @RequestMapping(value = "/something", method = RequestMethod.GET) @ResponseBody public String getData(@RequestParam("name") String name, @RequestParam("age") String age) { return htmlHelper.createHtmlPage("Hello World", "my name is " + name + " and age is " + age); } } This is just my own component that has basic HTML functionality like printing out valid HTML5 page. Normally you would use some view technology for this
htmlHelper; @RequestMapping(value = "/something", method = RequestMethod.POST) @ResponseBody public String getData(@RequestParam("name") String name, @RequestParam("age") String age) { return htmlHelper.createHtmlPage("Hello World", "my name is " + name + " and age is " + age); } } You can also send these via POST
a pool of Threads which it uses to respond to connections (HTTP Requests) • When request arrives, one thread is picked up and in the dispatches the @Controller instance methods • If the nature of the controller is stateless, singleton is the way to go • You can change this by using @Scope("prototype")
inside of Java -> Bad practice • Idea is to separate the HTML from the Java • The view layer may use different technologies to render the view • JSP, Thymeleaf, Tiles, Freemarker, Velocity
This class acts as a controller. // Usually when using @Controller, you will use also @RequestMapping @Controller public class MyController { // When HTTP GET, POST, PUT or OTHER request happens // to http://localhost:8080/greeting // invoke this method @RequestMapping("/greeting") @ResponseBody // By default the method will return the file name of the view! public String greeting() { return "view"; } }
responsible for selecting a view to be rendered • In addition to this, class is responsible for preparing a model map with data • The model map allows abstraction of the view technology • It is transformed to a Thymeleaf Context Object
getView() { // Holder for both Model and View in the web MVC framework ModelAndView mav = new ModelAndView(); // return view.html mav.setViewName("view"); // add object with name = jack value mav.addObject("name", "Jack"); return mav; } }
annotation is looked up • Finds a match, calls corresponding method • Once the method is figured out, it will read the method signature • What arguments should I pass to the method so I can invoke it? • So when you have Model model in arguments, Spring will automatically create a object for you!
{} var jack = new User("jack", "[email protected]"); out.println(jack.name()); out.println(jack.email()); out.println(jack.toString()); out.println(jack.equals(jack));
= "Please enter your name.") private String name; @NotEmpty(message = "Please enter your email.") @Email(message = "Please correct your email.") private String email; }
A user session contains information about the user across multiple HTTP requests. • To do this in Java EE Servlets and in Spring you can use HttpServletRequest • HttpSession session = request.getSession(); • session.setAttribute("userName", "theUserName"); • String userName = (String) session.getAttribute("userName");
public ModelAndView showView() { // Get or create the session HttpSession session = request.getSession(true); // Get integer value from the session Integer integerValue = (Integer) session.getAttribute("value"); // If not found, set it to 0 if(integerValue == null) { integerValue = 0; } integerValue++; // Add it to session session.setAttribute("value", integerValue); ModelAndView mav = new ModelAndView(); mav.setViewName("view"); mav.addObject("integerValue", integerValue); return mav; } } Inject the HttpServletRequest
singleFieldPage() { return new ModelAndView("myform"); } @GetMapping("remember") public ModelAndView receiveName(@RequestParam("name") String name) { ModelAndView mav = new ModelAndView(); mav.setViewName("myform"); // This will go to session! mav.addObject("name", name); return mav; } } This will typically list the names of model attributes which should be transparently stored in the session
public String getName() { return name; } public void setName(String name) { this.name = name; } } This Bean is NOT singleton or protytype. It's scope is Session!
Customer customer; @RequestMapping("showcustomer") @ResponseBody public String showcustomer() { return customer.toString(); } } @Component @Scope("prototype") public class Customer { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } Several instances can be created from the class Always the same instance because the customer is injected only once
customer; @RequestMapping("showcustomer") @ResponseBody public String showcustomer() { return customer.toString(); } } @Component @Scope("prototype") public class Customer { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } Several instances can be created from the class Now on each request, different object For each request, create new controller
@RequestMapping("showcustomer") @ResponseBody public String showcustomer() { return context.getBean("this-is-my- customer").toString(); } @Component("this-is-my-customer") @Scope("prototype") public class Customer { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } Get the bean on each http request Context can be used to look up beans in runtime
@Autowired WebApplicationContext context; @RequestMapping("showcustomer") @ResponseBody public String showcustomer() { return context.getBean("this-is-my- customer").toString(); } @Component("this-is-my-customer") @Scope("session") public class Customer { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } Now this works! We will get a different customer object for each browser session!
@Autowired Customer customer; @RequestMapping("showcustomer") @ResponseBody public String showcustomer() { return customer.toString(); } } @Component @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) public class Customer { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } Let's add proxy here This will use a proxy. Proxy will then fetch the real Customer object.
2000 by Roy Fielding in his theses: • http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_st yle.htm • Way of providing interoperability between computer systems • Does not restrict communication to a particular protocol • Http Web Service API that follows REST principals are called RESTful APIs
Stateless 3. Cacheable 4. Layered system 5. Code on demand (optional) 6. Uniform Interface 1. Identification of resources 2. Manipulation of resources through representations 3. Self-descriptive messages 4. Hypermedia as the engine of application state
in nature • No session data stored on the server • Each request from client to server must contain all the information necessary to understand the request
architecture layers • Restrict knowledge of the system to one layer • Client -> Cache -> Middleware -> Server -> DB • For example the middleware can be a cache • Client cannot tell if it's connected to end server or middleware
Identication of resources • Every resource has unique URI 2. Manipulation of resources through representations • Representation can be in various formats and is de-coupled from the identification 3. Self-descriptive messages • Each message has enough information to describe how to process the message, for example by using content-type 4. Hypermedia as the engine of application state (HATEOAS) • Server respondes with a set of links what other actions are available
unique URI • http://company.com/employees/ • URI is an identifier • Result is the resource • Notice that resource is not 'storage object', it's entity • Resources are just some item that can be accessed
formats, like HTML, XML, JSON, SVG, PNG • RESTful apps can send accept header where it defines what kind of data it can handle • Server can send Content-type where it defines the type of the resource • De-coupling the representation of the resource from the URI is key aspect of REST
the API • Include links to the responses • What other • REST client needs no prior information about the service • REST client enters app by simplex fixed URI • All future actions may be discovered within the response • Nearly ALL popular WEB APIs violate HATEOAS
1, "name" : "A", "_links" : { "self" : { "href" : "http://localhost:8080/customers/1" } } }, { "id" : 2, "name" : "A", "_links" : { "self" : { "href" : "http://localhost:8080customers/2" } } } ] }, "_links" : { "self" : { "href" : "http://localhost:8080/customers" } } } Spring HATEAOS uses HAL format. _embedded means that all the resources are embedded in the response (instead of URIs) Links are given with _links and usually have self relationship. You can define more links like next and prev relationships
to each resource • Categorize if resources are needed to view and/or update • All HTTP Get should be side-effect free • Put hyperlinks to resource representation to enable clients to drill down for more information • Specify the format of response data • Create documentation how to use the service
use browser • For more complicated services, you can use tools called cURL: http://curl.haxx.se/ • Via command line you can create HTTP GET, POST, DELETE, PUT commands: • curl GET http://localhost:8080/rest/cars • curl POST –d "{brand: 'skoda'}" http://localhost:8080/rest/cars • curl DELETE http://localhost:8080/rest/cars/0 • Or if you prefer GUI, use Postman Chrome - extension
of basic dependencies needed to develop web-applications with spring. These basic dependencies are: • jackson-databind • hibernate-validator • spring-core • spring-web • spring-webmvc • spring-boot-starter • spring-boot-starter-tomcat Jackson provides automatic mapping between pojo to json!
pom.xml it will be used to render to xml • If not, it uses JAXB that requires that class is annotated with @XmlRootElement @RestController public class MyRestController { @RequestMapping(value="location", produces = MediaType.APPLICATION_XML_VALUE) public Location getLocation() { return new Location(60,60); } } <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> </dependency>
init() { locations = new ArrayList<>(); locations.add(new Location()); } @PostMapping("/locations") public void saveLocation(@RequestBody Location c) { locations.add(c); } @GetMapping("/locations") public Iterable<Location> fetchLocation() { return locations; } @GetMapping("/locations/{userId}") public Location fetchLocation(@PathVariable int userId) { for(Location c : locations) { if(c.getId() == userId) { return c; } } return null; } } RestController is a singleton, this is not thread safe
{ @Autowired LocationRepository locationRepository; @PostMapping("/locations") public void saveLocation(@RequestBody Location location, UriComponentsBuilder b) { locationRepository.saveEntity(location); } @GetMapping("/locations") public Iterable<Location> fetchLocation() { return locationRepository.findAll(); } @GetMapping("/locations/{userId}") public Location fetchLocation(@PathVariable int locationId) { return locationRepository.findOne(userId); } } Let's separate the "database" into separate service
T saveEntity(T entity); public void delete(ID id) throws IllegalArgumentException; public Iterable<T> findAll(); public Optional<T> findOne(ID id); } This will work as a base interface. Notice that we can reuse this to work with different entities
ticket, user or group • Identify what actions can user apply to them • GET /employees/ • GET /employees/1 • POST /employees • PUT /employees/1 • DELETE /employees/1 • Use plurals in the endpoint name! • So do not: employee/1 vs employees/ • person / people vs goose / geese
resource to the client • In case of HTTP POST, return 201 and include Location Header that points to the URL of the resource • In case of HTTP DELETE • 204: no response body • 200: response body with the deleted resource
-d '{"latitude": 80, "longitude": 80}' http://localhost:8080/locations @PostMapping("/locations") public ResponseEntity<Void> saveLocation(@RequestBody Location c, UriComponentsBuilder b) { locations.add(c); UriComponents uriComponents = b.path("/locations/{id}").buildAndExpand(c.getId()); HttpHeaders headers = new HttpHeaders(); headers.setLocation(uriComponents.toUri()); return new ResponseEntity<Void>(headers, HttpStatus.CREATED); } To build the location uri. One of the biggest advantages of UriComponentsBuild er is that we can inject it right into a controller method Creates a response with void body, location header and status 201
(HTTP POST) • 204 No Content (For example Delete) • 400 Bad Request • 401 Unauthorized • 403 Forbidden • 404 Not Found • 405 Method not found (when method is not allowed for authenticated user) • 409 Conflict • 410 Gone (older apis) • 429 Too many requests
deleteLocation(@PathVariable int locationId) { locationRepository.delete(locationId); return new ResponseEntity<Void>(HttpStatus.NO_CONTENT); } This will throw an exception if userId is not found
ex) { ErrorInfo e = new ErrorInfo("Could not found location with id " + ex.getLocationId()); return new ResponseEntity<ErrorInfo>(e, HttpStatus.NOT_FOUND); } } This method will catch if our own exception is thrown! End result is 404 NOT Found and ErrorInfo POJO in JSON
{ public static void main(String[] args) { SpringApplication.run(CustomerRestApplication.class, args); } } Inspects every bean for a presence of a @Cache annotation of public methods. Proxy is automatically created to intercept the method call and handle the caching behavior
Location findOne(Integer id) { simulateSlowService(); Location locationTobeFound = null; for(Location loc : this.locations) { if (loc.getId() == id) { locationTobeFound = loc; } } return locationTobeFound; } The result of this method is cached. When invocation comes for the second time, cache is used. In here findOne is assosiated with cache named "locations". The cache fetching is not synchronized by default, we can enable it.
• For example, you can use low level JdbcTemplate class or you can use ORM mapping (Hibernate) • Spring Data provides you additional functionality where it creates Repository methods for you directly from interfaces • Spring has great support for embedded in-memory databases • Spring boot autoconfigures H2, HSQL and Derby. You don't need to provide any connection urls, just dependency is enough • In real life, when using real db, you can set connection url's and other stuff in application.properties
the connection. X Specify the SQL statement. X Declare parameters and provide parameter values X Prepare and execute the statement. X Set up the loop to iterate through the results (if any). X Do the work for each iteration. X Process any exception. X Handle transactions. X Close the connection, statement and resultset. X
is installed in every JDK • Start Network Server • Windows • java -jar "%DERBY_HOME%\lib\derbyrun.jar" server start • Mac • java -jar $DERBY_HOME/lib/derbyrun.jar server start • Notice that the directory where you start your server is important. • All the databases are saved to the dir where you started the network server • Once your network server runs, open another terminal window and start ij and connect & create database • CONNECT 'jdbc:derby://localhost:1527/mydb;create=true';
--> <dependency> <groupId>org.apache.derby</groupId> <artifactId>derbyclient</artifactId> <version>10.13.1.1</version> </dependency> Apache Derby Database and Embedded Driver Only client driver. Database is installed via JDK and running in network mode
describes management of relational data in apps using Java • Basic idea is simple, save objects to relational database • JPA is a specification, hibernate is implementation of this specification. • By default, Spring uses hibernate • When using JPA you will also have to declare the driver for the database • Spring Data JPA enhances JPA
Java • Mapping Java classess to databatase tables • Mapping is done by using • 1) XML configuration or • 2) Java annotations • Classes must have no-argument constructor • Collections are stored in Set or List, also generics are supported
is standard Java EE API • javax.persistence.*; • @Entitity marks the class as entity bean, it must have a no-argument constructor! • @Table annotation you can set name, catalogue, schema, constraints • @Id and @GeneratedValue • Every entity bean must have primary key! Use @Id • You will have different primary key strategies, by using @GeneratedValue, let hibernate decide what is the best way for the primary key • @Column annotation specifies the details of the column, like name, length, nullable etc. • Only @Id and @Entity here are mandatory!
static void main( String[ ] args ) { EntityManagerFactory emfactory = Persistence.createEntityManagerFactory( "Eclipselink_JPA" ); EntityManager entitymanager = emfactory.createEntityManager( ); entitymanager.getTransaction( ).begin( ); Employee employee = new Employee( ); employee.setEid( 1201 ); employee.setEname( "Gopal" ); employee.setSalary( 40000 ); employee.setDeg( "Technical Manager" ); entitymanager.persist( employee ); entitymanager.getTransaction( ).commit( ); entitymanager.close( ); emfactory.close( ); } } XML file persistence.xml holds persistence units that has information about which DB to use etc Transaction management is mandatory Persists the pojo to the db defined in persistence.xml
List<Employee> results = entitymanager.createQuery("FROM Employee").getResultList(); • SELECT • List<String> results = entitymanager.createQuery("SELECT firstName FROM Employee").getResultList(); • WHERE • List<Employee> results = entitymanager.createQuery("FROM Employee WHERE ID = 10").getResultList(); • You will get a warning: [unchecked] unchecked conversion because hibernate is not type safe by design. Solution: • @SuppressWarnings("unchecked")
and the standard Hibernate property values are none, validate, update, create, create- drop. Spring Boot chooses a default value for you based on whether it thinks your database is embedded (default create-drop) or not (default none). An embedded database is detected by looking at the Connection type: hsqldb, h2 and derby are embedded, the rest are not
signicantly reduces the amount of boilerplate code when implementing data access layers • Spring data will create a class for you that handles all the saving and opening • You can define your own methods to a interface and Spring Data will create the method for you!
public static void main(String[] args) { SpringApplication.run(App.class, args); } @Override public void run(String... strings) throws Exception { springDatarepository.save(new Location(...)); springDatarepository.save(new Location(...)); Iterable<Location> list = springDatarepository.findAll(); list.forEach(System.out::println); } } Spring Data will create a implementation for the interface and injects it here!
findByLatitude(double lat); } find..By, read...By, query...By, count..By, get...By methods are read by Spring Data and Spring Data will implement this method for you!
Client does not need prior knowledge of how to interact with the server • The server provides links to the client • Spring HATEOAS tries to address link creation and representation assembly
userId) { Location location = locationRepository.findOne(userId); Link link = ControllerLinkBuilder.linkTo(MyRestControllerSpringData.class).slash(location.getId()).withSelfRel(); LocationDTO locationDTO = new LocationDTO(location); locationDTO.add(link); return new ResponseEntity<LocationDTO>(locationDTO, HttpStatus.OK); } The manual wrapping between DTO and Entity can be a pain. Spring provides you the wrapper: Resources<T>
{ Location location = locationRepository.findOne(userId); Link link = ControllerLinkBuilder.linkTo(MyRestControllerSpringData.class).slash(location.getId()).withSelfRel(); Resource<Location> locationDTO = new Resource<>(location); locationDTO.add(link); return new ResponseEntity<Resource<Location>>(locationDTO, HttpStatus.OK); }
You may change this from application.properties • springdoc.api-docs.path=/api-docs • And now they are available • http://localhost:8080/api-docs/ • To see HTML doc • http://localhost:8080/swagger-ui.html
<packaging>war</packaging> • Give command again • mvn clean package • And now in target/ dir you should a war • The dir structure of war differs from jar • war contains WEB-INF/classes • But it still contains tomcat libraries!
tomcat libraries to different folder • Works both in jar and in war! • Add dependency <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> • This will include the libraries but put them in lib-provided/
scope) contains the following provided libraries: • JUnit 5: The de-facto standard for unit testing Java applications. • Spring Test & Spring Boot Test: Utilities and integration test support for Spring Boot applications. • AssertJ: A fluent assertion library. • Hamcrest: A library of matcher objects (also known as constraints or predicates). • Mockito: A Java mocking framework. • JSONassert: An assertion library for JSON. • JsonPath: XPath for JSON.
environment, no real http communication • WebTestClient • Originally testing tool for spring webflux endpoint, but can be used also for running servlet. • TestRestTemplate • Uses real http communication. Will be depricated.
application context (primary job is to manage beans). It searches for @SpringBootConfiguration (which is under @SpringBootApplication) and starts the app context in very similar way than production environment. We can now do integration tests!
/ LDAP / OAuth, Tokens/JWT • Allow/bock access to URSL to logged in users • Allow/block access to URLs to logged in users AND with certain roles • Handels common vulnerabilities by default • Session fixation • Clickjacking • Click site request forgery • Method level security
verifies that someone or something is who they say they are • On arrival, you knock on the door, and your friend opens it. She recognizes you (authentication) and greets you. • User name / password (knowledge based authentication) • Authorization / Access Control (Can this user do this?) • Process that determines a user or service's level of access • For example, you may enter the kitchen area, but you cannot go into her private office. In other words, you have the authorization to enter the kitchen, but access to her private office is prohibited.
App remembers the principal for the user so that name/password is not asked every page load • Granted Authority • What the user can do • List of authorities • Role • Group of authorities • admin role has authorities A, B, C,D • user role has authorities A, B
Supports • Authentication (logint and logout functionality) • Process that verifies that someone or something is who they say they are • On arrival, you knock on the door, and your friend opens it. She recognizes you (authentication) and greets you. • Authorization / Access Control • Process that determines a user or service's level of access • For example, you may enter the kitchen area, but you cannot go into her private office. In other words, you have the authorization to enter the kitchen, but access to her private office is prohibited.
users (may be in the database) • You may hard code users in memory testing • Spring Security < 5.7 • WebSecurityConfigurerAdapter • Spring Secury >= 5.7 • Component-based security configuration
a servlet Filters as a bean names SpringSecurityFilterChain • Responsible for all the security • protecting app urls • validating username and pws • Creates UserDetailsService bean with a username of user and randomly generated passsword that is logged to the console
with the app • Generate a default login form for you • User with user and password like 8e557245-... • Protectst the password storage using BCrypt • Lets the user log out • CSRF attact, Session Fixation prevention and protection
apps underneath • Any Spring Web App is just one servlet • DispatcherServlet (Spring) redeirect incoming HTTP requests to your @Controller or @RestController • You can put filters in front of servlets • Browser -> Filter -> DispatcherServlet -> @Controller
monster filter, split these! • First, go through a LoginMethodFilter… • Then, go through an AuthenticationFilter… • Then, go through an AuthorizationFilter… • Finally, hit your servlet.
@Bean public InMemoryUserDetailsManager inMemoryUserDetailsManager() { var admin = User .withUsername("admin") .password(passwordEncoder().encode("admin")) .roles("admin", "user").build(); var user = User .withUsername("jack") .password(passwordEncoder().encode("jack")) .roles("user").build(); return new InMemoryUserDetailsManager(List.of(admin, user)); } No encoding at all! (you should not use this)
} @Bean public InMemoryUserDetailsManager inMemoryUserDetailsManager() { var admin = User .withUsername("admin") .password(passwordEncoder().encode("admin")) .roles("admin", "user").build(); var user = User .withUsername("jack") .password(passwordEncoder().encode("jack")) .roles("user").build(); return new InMemoryUserDetailsManager(List.of(admin, user)); } You can decide encoder
EmbeddedDatabaseBuilder is a Spring builder which provides convenient // API to create an embedded database in a Spring application. return new EmbeddedDatabaseBuilder() .setType(EmbeddedDatabaseType.H2) // H2, HSQL, Derby .addScript(JdbcDaoImpl.DEFAULT_USER_SCHEMA_DDL_LOCATION) // data.sql .build(); }
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, username VARCHAR(45) NOT NULL, password VARCHAR(245) NOT NULL, enabled INT NOT NULL ); CREATE TABLE authorities ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, username VARCHAR(45) NOT NULL, authority VARCHAR(45) NOT NULL );
all the beans configured in our application. • env: provides information about the Spring Environment properties. • health: Shows application health • info: Displays application information, we can configure this in Spring environment properties. • mappings: Displays the list of all @RequestMapping paths. • shutdown: allows us to gracefully shutdown the application. • threaddump: provides the thread dump of the application.
• Connection stays open until client or server decides to close connection • Typical use case • Multiple users communication with each other, like chat
work with web sockets • Similar to HTTP, works over TCP using the following commands • SEND, SUBSCRIBE, UNSUBSCRIBE... • Example SEND destination:/queue/a content-type:text/plain hello world
Thread.sleep(1000); return new Greeting("Hello, " + message.getName()); } If message is sent to /hello destination, greeting() method is called Return value is broadcast to all subscribers of /topic/greetings
{ @Override public void configureMessageBroker(MessageBrokerRegistry config) { // Enable a simple memory-based message broker to carry the greeting messages // back to the client on destinations prefixed with /topic config.enableSimpleBroker("/topic"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { // The client will attempt to connect to /my-websocket-service registry.addEndpoint("/my-websocket-service").withSockJS(); }