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

Migrated to Spring

parent 9a7c5ed9
plugins {
id "java"
id "war" // for REST
id 'java'
id 'org.springframework.boot' version '2.4.0'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}
group 'org.example'
version '1.0-SNAPSHOT'
group = 'org.example'
version = '1.0-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
compile 'com.google.code.gson:gson:2.7'
// 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'
// Spring Web for REST
implementation 'org.springframework.boot:spring-boot-starter-web'
// MQTT
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5'
}
test {
useJUnitPlatform()
}
\ No newline at end of file
}
beans/Word.java
beans.Word
services/StartServer.java
services.StartServer
beans/Dictionary.java
beans.Dictionary
services/DictionaryRestService.java
services.DictionaryRestService
server/Application.java
server.Application
server/DictionaryController.java
server.DictionaryController
server/Word.java
server.Word
server/Dictionary.java
server.Dictionary
client/MyClient.java
client.MyClient
package client;
import beans.Word;
import com.google.gson.Gson;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientHandlerException;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;
import server.Word;
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";
Word word = new Word("computer","an electronic machine that can store and arrange large amounts of information");
clientResponse = postRequest(client,serverAddress+postPath,word);
System.out.println(clientResponse.toString());
Word word = new Word("computer", "an electronic machine that can store and arrange large amounts of information");
ResponseEntity<String> postResponse = postRequest(serverAddress + postPath, word);
System.out.println(postResponse);
//GET #1
// GET #1
String getPath = "/dictionary/get/computer";
clientResponse = getRequest(client,serverAddress+getPath);
System.out.println(clientResponse.toString());
String response = clientResponse.getEntity(String.class);
System.out.println(response);
ResponseEntity<String> getResponse = getRequest(serverAddress + getPath);
System.out.println(getResponse);
System.out.println(getResponse.getBody());
//PUT
// PUT
String putPath = "/dictionary/modify";
word = new Word("computer","little box with many wires and a huge number of bright lights");
clientResponse = putRequest(client, serverAddress+putPath, word);
System.out.println(clientResponse.toString());
word = new Word("computer", "little box with many wires and a huge number of bright lights");
ResponseEntity<String> putResponse = putRequest(serverAddress + putPath, word);
System.out.println(putResponse);
//GET #2
clientResponse = getRequest(client,serverAddress+getPath);
System.out.println(clientResponse.toString());
response = clientResponse.getEntity(String.class);
System.out.println(response);
// GET #2
getResponse = getRequest(serverAddress + getPath);
System.out.println(getResponse);
System.out.println(getResponse.getBody());
//DELETE #1
// DELETE
String deletePath = "/dictionary/delete/computer";
clientResponse = deleteRequest(client, serverAddress+deletePath);
System.out.println(clientResponse);
//GET #3
clientResponse = getRequest(client,serverAddress+getPath);
System.out.println(clientResponse.toString());
response = clientResponse.getEntity(String.class);
System.out.println(response);
ResponseEntity<String> deleteResponse = deleteRequest(serverAddress + deletePath);
System.out.println(deleteResponse);
// 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){
WebResource webResource = client.resource(url);
String input = new Gson().toJson(w);
public static ResponseEntity<String> postRequest(String url, Word word) {
try {
return webResource.type("application/json").post(ClientResponse.class, input);
} catch (ClientHandlerException e) {
System.out.println("Server not available");
return null;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Word> request = new HttpEntity<>(word, headers);
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){
WebResource webResource = client.resource(url);
public static ResponseEntity<String> getRequest(String url) {
try {
return webResource.get(ClientResponse.class);
} catch (ClientHandlerException e) {
System.out.println("Server not available");
return null;
return restTemplate.getForEntity(url, String.class);
} catch (Exception e) {
System.out.println("Server not available: " + e.getMessage());
return new ResponseEntity<>(HttpStatus.SERVICE_UNAVAILABLE);
}
}
public static ClientResponse putRequest(Client client, String url, Word word){
WebResource webResource = client.resource(url);
String input = new Gson().toJson(word);
public static ResponseEntity<String> putRequest(String url, Word word) {
try {
return webResource.type("application/json").put(ClientResponse.class, input);
} catch (ClientHandlerException e) {
System.out.println("Server not available");
return null;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Word> request = new HttpEntity<>(word, headers);
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){
WebResource webResource = client.resource(url);
try{
return webResource.delete(ClientResponse.class);
}catch(ClientHandlerException e){
System.out.println("Server not available");
return null;
public static ResponseEntity<String> deleteRequest(String url) {
try {
restTemplate.delete(url);
return new ResponseEntity<>("DELETE successful", HttpStatus.OK);
} catch (Exception e) {
System.out.println("Server not available: " + e.getMessage());
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;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
package server;
import java.util.HashMap;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Dictionary {
@XmlElement(name = "dictionary")
private HashMap<String, String> dictionary;
import org.springframework.stereotype.Service;
private static Dictionary instance;
public Dictionary(){
dictionary = new HashMap<String, String>();
}
public Dictionary(HashMap<String, String> dict){
dictionary = dict;
}
@Service //Spring automatically makes this class a singleton bean
public class Dictionary {
//See the singleton pattern
public synchronized static Dictionary getInstance(){
if(instance==null){
instance = new Dictionary();
}
return instance;
}
private final HashMap<String, String> dictionary = new HashMap<String, String>();;
public int addWord(String w, String d){
synchronized (this) {
......@@ -66,5 +46,4 @@ public class Dictionary {
public void deleteWord(String 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 {
private String word;
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