Commit 0bff4e06 authored by Michele Fiori's avatar Michele Fiori

Migrated to Spring

parent 9a7c5ed9
plugins { plugins {
id "java" id 'java'
id "war" // for REST id 'org.springframework.boot' version '2.4.0'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
} }
group 'org.example' group = 'org.example'
version '1.0-SNAPSHOT' version = '1.0-SNAPSHOT'
sourceCompatibility = '1.8'
repositories { repositories {
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0' // Spring Web for REST
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine' implementation 'org.springframework.boot:spring-boot-starter-web'
// MQTT
compile 'com.google.code.gson:gson:2.7' implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5'
// REST Dependencies
// https://mvnrepository.com/artifact/org.codehaus.jackson/jackson-core-asl
compile group: 'org.codehaus.jackson', name: 'jackson-core-asl', version: '1.9.2'
// https://mvnrepository.com/artifact/org.codehaus.jackson/jackson-jaxrs
compile group: 'org.codehaus.jackson', name: 'jackson-jaxrs', version: '1.9.2'
// https://mvnrepository.com/artifact/org.codehaus.jackson/jackson-mapper-asl
compile group: 'org.codehaus.jackson', name: 'jackson-mapper-asl', version: '1.9.2'
// https://mvnrepository.com/artifact/org.codehaus.jackson/jackson-xc
compile group: 'org.codehaus.jackson', name: 'jackson-xc', version: '1.9.2'
// https://mvnrepository.com/artifact/com.sun.jersey/jersey-client
compile group: 'com.sun.jersey', name: 'jersey-client', version: '1.19.1'
// https://mvnrepository.com/artifact/com.sun.jersey/jersey-core
compile group: 'com.sun.jersey', name: 'jersey-core', version: '1.19.1'
// https://mvnrepository.com/artifact/com.sun.jersey/jersey-json
compile group: 'com.sun.jersey', name: 'jersey-json', version: '1.19.1'
// https://mvnrepository.com/artifact/com.sun.jersey/jersey-server
compile group: 'com.sun.jersey', name: 'jersey-server', version: '1.19.1'
// https://mvnrepository.com/artifact/com.sun.jersey/jersey-servlet
compile group: 'com.sun.jersey', name: 'jersey-servlet', version: '1.19.1'
// https://mvnrepository.com/artifact/org.codehaus.jettison/jettison
compile group: 'org.codehaus.jettison', name: 'jettison', version: '1.1'
// https://mvnrepository.com/artifact/javax.ws.rs/jsr311-api
compile group: 'javax.ws.rs', name: 'jsr311-api', version: '1.1.1'
// https://mvnrepository.com/artifact/com.sun.jersey/jersey-server
compile group: 'com.sun.jersey', name: 'jersey-server', version: '1.2'
} }
test { test {
useJUnitPlatform() useJUnitPlatform()
} }
\ No newline at end of file
beans/Word.java server/Application.java
beans.Word server.Application
services/StartServer.java server/DictionaryController.java
services.StartServer server.DictionaryController
beans/Dictionary.java server/Word.java
beans.Dictionary server.Word
services/DictionaryRestService.java server/Dictionary.java
services.DictionaryRestService server.Dictionary
client/MyClient.java client/MyClient.java
client.MyClient client.MyClient
package client; package client;
import beans.Word; import org.springframework.http.*;
import com.google.gson.Gson; import org.springframework.web.client.RestTemplate;
import com.sun.jersey.api.client.Client; import server.Word;
import com.sun.jersey.api.client.ClientHandlerException;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
public class MyClient { public class MyClient {
public static void main(String[] argv){
Client client = Client.create();
String serverAddress = "http://localhost:1337";
ClientResponse clientResponse = null;
//POST private static final RestTemplate restTemplate = new RestTemplate();
private static final String serverAddress = "http://localhost:1337";
public static void main(String[] args) {
// POST
String postPath = "/dictionary/add"; String postPath = "/dictionary/add";
Word word = new Word("computer","an electronic machine that can store and arrange large amounts of information"); Word word = new Word("computer", "an electronic machine that can store and arrange large amounts of information");
clientResponse = postRequest(client,serverAddress+postPath,word); ResponseEntity<String> postResponse = postRequest(serverAddress + postPath, word);
System.out.println(clientResponse.toString()); System.out.println(postResponse);
//GET #1 // GET #1
String getPath = "/dictionary/get/computer"; String getPath = "/dictionary/get/computer";
clientResponse = getRequest(client,serverAddress+getPath); ResponseEntity<String> getResponse = getRequest(serverAddress + getPath);
System.out.println(clientResponse.toString()); System.out.println(getResponse);
String response = clientResponse.getEntity(String.class); System.out.println(getResponse.getBody());
System.out.println(response);
//PUT // PUT
String putPath = "/dictionary/modify"; String putPath = "/dictionary/modify";
word = new Word("computer","little box with many wires and a huge number of bright lights"); word = new Word("computer", "little box with many wires and a huge number of bright lights");
clientResponse = putRequest(client, serverAddress+putPath, word); ResponseEntity<String> putResponse = putRequest(serverAddress + putPath, word);
System.out.println(clientResponse.toString()); System.out.println(putResponse);
//GET #2 // GET #2
clientResponse = getRequest(client,serverAddress+getPath); getResponse = getRequest(serverAddress + getPath);
System.out.println(clientResponse.toString()); System.out.println(getResponse);
response = clientResponse.getEntity(String.class); System.out.println(getResponse.getBody());
System.out.println(response);
//DELETE #1 // DELETE
String deletePath = "/dictionary/delete/computer"; String deletePath = "/dictionary/delete/computer";
clientResponse = deleteRequest(client, serverAddress+deletePath); ResponseEntity<String> deleteResponse = deleteRequest(serverAddress + deletePath);
System.out.println(clientResponse); System.out.println(deleteResponse);
//GET #3
clientResponse = getRequest(client,serverAddress+getPath);
System.out.println(clientResponse.toString());
response = clientResponse.getEntity(String.class);
System.out.println(response);
// GET #3
getResponse = getRequest(serverAddress + getPath);
System.out.println(getResponse);
System.out.println(getResponse.getBody());
} }
public static ClientResponse postRequest(Client client, String url, Word w){ public static ResponseEntity<String> postRequest(String url, Word word) {
WebResource webResource = client.resource(url);
String input = new Gson().toJson(w);
try { try {
return webResource.type("application/json").post(ClientResponse.class, input); HttpHeaders headers = new HttpHeaders();
} catch (ClientHandlerException e) { headers.setContentType(MediaType.APPLICATION_JSON);
System.out.println("Server not available"); HttpEntity<Word> request = new HttpEntity<>(word, headers);
return null; return restTemplate.postForEntity(url, request, String.class);
} catch (Exception e) {
System.out.println("Server not available: " + e.getMessage());
return new ResponseEntity<>(HttpStatus.SERVICE_UNAVAILABLE);
} }
} }
public static ClientResponse getRequest(Client client, String url){ public static ResponseEntity<String> getRequest(String url) {
WebResource webResource = client.resource(url);
try { try {
return webResource.get(ClientResponse.class); return restTemplate.getForEntity(url, String.class);
} catch (ClientHandlerException e) { } catch (Exception e) {
System.out.println("Server not available"); System.out.println("Server not available: " + e.getMessage());
return null; return new ResponseEntity<>(HttpStatus.SERVICE_UNAVAILABLE);
} }
} }
public static ClientResponse putRequest(Client client, String url, Word word){ public static ResponseEntity<String> putRequest(String url, Word word) {
WebResource webResource = client.resource(url);
String input = new Gson().toJson(word);
try { try {
return webResource.type("application/json").put(ClientResponse.class, input); HttpHeaders headers = new HttpHeaders();
} catch (ClientHandlerException e) { headers.setContentType(MediaType.APPLICATION_JSON);
System.out.println("Server not available"); HttpEntity<Word> request = new HttpEntity<>(word, headers);
return null; restTemplate.put(url, request);
return new ResponseEntity<>("PUT successful", HttpStatus.OK);
} catch (Exception e) {
System.out.println("Server not available: " + e.getMessage());
return new ResponseEntity<>(HttpStatus.SERVICE_UNAVAILABLE);
} }
} }
public static ClientResponse deleteRequest(Client client, String url){ public static ResponseEntity<String> deleteRequest(String url) {
WebResource webResource = client.resource(url); try {
try{ restTemplate.delete(url);
return webResource.delete(ClientResponse.class); return new ResponseEntity<>("DELETE successful", HttpStatus.OK);
}catch(ClientHandlerException e){ } catch (Exception e) {
System.out.println("Server not available"); System.out.println("Server not available: " + e.getMessage());
return null; return new ResponseEntity<>(HttpStatus.SERVICE_UNAVAILABLE);
} }
} }
} }
package server;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
System.out.println("Server running on http://localhost:8080");
}
}
package beans; package server;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.HashMap; import java.util.HashMap;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Dictionary {
@XmlElement(name = "dictionary") import org.springframework.stereotype.Service;
private HashMap<String, String> dictionary;
private static Dictionary instance;
public Dictionary(){ @Service //Spring automatically makes this class a singleton bean
dictionary = new HashMap<String, String>(); public class Dictionary {
}
public Dictionary(HashMap<String, String> dict){
dictionary = dict;
}
//See the singleton pattern private final HashMap<String, String> dictionary = new HashMap<String, String>();;
public synchronized static Dictionary getInstance(){
if(instance==null){
instance = new Dictionary();
}
return instance;
}
public int addWord(String w, String d){ public int addWord(String w, String d){
synchronized (this) { synchronized (this) {
...@@ -66,5 +46,4 @@ public class Dictionary { ...@@ -66,5 +46,4 @@ public class Dictionary {
public void deleteWord(String w){ public void deleteWord(String w){
dictionary.remove(w); dictionary.remove(w);
} }
} }
package server;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/dictionary")
public class DictionaryController {
private final Dictionary dictionary;
@Autowired//tells Spring to automatically resolve and inject the required bean (object) into the class where it's used
public DictionaryController(Dictionary dictionary) {
this.dictionary = dictionary;
}
@PostMapping(value = "/add", consumes = {"application/json", "application/xml"})
public ResponseEntity<Void> addWord(@RequestBody Word word) {
int result = dictionary.addWord(word.getWord().toLowerCase(), word.getDefinition());
if (result == -1) {
return ResponseEntity.status(HttpStatus.NOT_ACCEPTABLE).build();
} else {
return ResponseEntity.ok().build();
}
}
@PutMapping(value = "/modify", consumes = {"application/json", "application/xml"})
public ResponseEntity<Void> changeDefinition(@RequestBody Word word) {
int result = dictionary.changeWordDefinition(word.getWord().toLowerCase(), word.getDefinition());
if (result == -1) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
} else {
return ResponseEntity.ok().build();
}
}
@GetMapping(value = "/get/{word}", produces = "text/plain")
public ResponseEntity<String> getDefinition(@PathVariable("word") String word) {
String definition = dictionary.viewDefinition(word.toLowerCase());
if (definition == null) {
return ResponseEntity.ok("Word not in dictionary");
}
return ResponseEntity.ok("Definition of " + word + ": " + definition);
}
@DeleteMapping("/delete/{word}")
public ResponseEntity<Void> deleteWord(@PathVariable("word") String word) {
dictionary.deleteWord(word.toLowerCase());
return ResponseEntity.ok().build();
}
}
package beans; package server;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Word { public class Word {
private String word; private String word;
private String definition; private String definition;
......
package services;
import beans.Dictionary;
import beans.Word;
import javax.ws.rs.*;
import javax.ws.rs.core.Response;
@Path("dictionary")
public class DictionaryRestService {
@Path("add")
@POST
@Consumes({"application/json", "application/xml"})
public Response addWord(Word w){
Dictionary dict = Dictionary.getInstance();
int ret = dict.addWord(w.getWord().toLowerCase(), w.getDefinition());
if(ret == -1){
return Response.status(Response.Status.NOT_ACCEPTABLE).build();
}else{
return Response.ok().build();
}
}
@Path("modify")
@PUT
@Consumes({"application/xml", "application/json"})
public Response changeDefinition(Word w){
Dictionary dict = Dictionary.getInstance();
int ret = dict.changeWordDefinition(w.getWord().toLowerCase(), w.getDefinition());
if(ret == -1){
return Response.status(Response.Status.NOT_FOUND).build();
}else{
return Response.ok().build();
}
}
@Path("get/{word}")
@GET
@Produces({"text/plain"})
public String getDefinition(@PathParam("word") String word){
Dictionary dict = Dictionary.getInstance();
String ret = dict.viewDefinition(word.toLowerCase());
if(ret == null){
return "Word not in dictionary";
}
return "Definition of " + word + ": " + ret;
}
@Path("delete/{word}")
@DELETE
public Response deleteWord(@PathParam("word") String word){
Dictionary dict = Dictionary.getInstance();
dict.deleteWord(word.toLowerCase());
return Response.ok().build();
}
}
package services;
import com.sun.jersey.api.container.httpserver.HttpServerFactory;
import com.sun.net.httpserver.HttpServer;
import java.io.IOException;
public class StartServer {
private static final String HOST = "localhost";
private static final int PORT = 1337;
public static void main(String[] args) throws IOException {
HttpServer server = HttpServerFactory.create("http://"+HOST+":"+PORT+"/");
server.start();
System.out.println("Server running!");
System.out.println("Server started on: http://"+HOST+":"+PORT);
System.out.println("Hit return to stop...");
System.in.read();
System.out.println("Stopping server");
server.stop(0);
System.out.println("Server stopped");
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment