From what I have seen so far, creating a custom ServerMessageDeliverer
seems to be the more complicated solution. Actually it looks like the correct solution is to override CoapResource#getChild(String)
so it returns the resource you want to be associated with that name. The ServerMessageDeliverer
looks to me more like the way to implement some sort of controller that delivers or distribute requests in a more complicated environment.
For the question where the last part of the URI is the parameter, the solution could look like this:
public class UriParameterResource extends CoapResource {
public UriParameterResource() {
super("foo");
}
@Override
public void handleGET(CoapExchange exchange) {
List<String> uriPath = exchange.getRequestOptions().getUriPath();
// check if there is a sub-resource given, and if so use it for processing
if (uriPath.size() > 1) {
exchange.respond("Process " + uriPath.get(1));
} else {
exchange.respond(ResponseCode.NOT_IMPLEMENTED);
}
}
@Override
public Resource getChild(String name) {
// even sub-resources will land in the GET of this resource
return this;
}
}
Regarding the the answer from @Copernic, I personally think it does not match the idea of REST. Each part of the URI path should return its own resource related to its parent, which makes it a tree structure per definition and not a flat list that simply inspects parts of the path as some sort of parameter.
IMHO even the sensors example could be resolved by using CoapResource
implementations where the variable child resource could be dynamically resolved. The snippet below is just an example, of course this would need to be dependent on the real situation where a house and its rooms would need to register somehow.
public class HousesResource extends CoapResource {
public HousesResource() {
super("houses");
}
@Override
public void handleGET(CoapExchange exchange) {
// could return a list of available houses
exchange.respond(ResponseCode.NOT_IMPLEMENTED);
}
@Override
public Resource getChild(String name) {
Resource child = super.getChild(name);
if (child == null) {
child = new HouseResource(name);
add(child);
}
return child;
}
class HouseResource extends CoapResource {
public HouseResource(String name) {
super(name);
add(new RoomsResource());
}
@Override
public void handleGET(CoapExchange exchange) {
exchange.respond(ResponseCode.NOT_IMPLEMENTED);
}
}
class RoomsResource extends CoapResource {
public RoomsResource() {
super("rooms");
}
@Override
public void handleGET(CoapExchange exchange) {
// could return a list of available rooms
exchange.respond(ResponseCode.NOT_IMPLEMENTED);
}
@Override
public Resource getChild(String name) {
Resource child = super.getChild(name);
if (child == null) {
child = new RoomResource(name);
add(child);
}
return child;
}
}
class RoomResource extends CoapResource {
public RoomResource(String roomName) {
super(roomName);
add(new SensorsResource());
}
@Override
public void handleGET(CoapExchange exchange) {
// could return a summary board about the room
exchange.respond(ResponseCode.NOT_IMPLEMENTED);
}
}
class SensorsResource extends CoapResource {
public SensorsResource() {
super("sensors");
add(new TemperatureResource());
}
@Override
public void handleGET(CoapExchange exchange) {
// this could return a list of registered sensors
exchange.respond(ResponseCode.NOT_IMPLEMENTED);
}
}
class TemperatureResource extends CoapResource {
public TemperatureResource() {
super("temperature");
}
@Override
public void handleGET(CoapExchange exchange) {
// as the structure is fixed we know that two levels up
// there is the room, and four levels up there is the house
String room = getParent().getParent().getName();
String house = getParent().getParent().getParent().getParent().getName();
exchange.respond("The temperature of the " + house + " in the " + room + " is : 25 degree");
}
}
}
In that example the resources are dynamically created if they did not exist before. This could be also exchanged with some lookup or register mechanism (e.g. a house is registered via PUT or PUSH).
Don't misunderstand me here. The solution by @Copernic seems to work and is probably a suitable solution for some scenarios (e.g. each house has its own server and the requests need to be redirected), but for a rather simple scenario it looks to me that it is not the correct way to go.