I have the following method to modify a user in my Postgres database:
public void modifyUser(User usr){
try (Connection conn = sql2o.beginTransaction()){
conn.createQuery("update public.\"user\" set name=:name, lastname=:lastname, email=:email where id=:id")
.addParameter("id", usr.getId())
.addParameter("name", usr.getName())
.addParameter("lastname", usr.getLastname())
.addParameter("email", usr.getEmail())
.executeUpdate();
conn.commit();
}
}
that is called by this method:
//update
put("/users", (request, response) -> {
response.type("application/json");
User user = new Gson().fromJson(request.body(), User.class);
model.modifyUser(user);
return new Gson().toJson(response);
});
I use Postman to specify the body, this way:
{ "id": 3,
"name": "Mary",
"lastname": "Changed",
"email": "email"
}
But, even if the post method is working fine, this "put" operation throws the following error:
spark.http.matching.MatcherFilter - The requested route [/users/] has not been mapped in Spark for Accept: [*/*]
I don't get what the error is. I couldn't find ny solution.
I know this is an old thread but I was hoping to provide some extra info on the topic.
The path's "/users" and "/users/" are 2 different paths, thus optionally allowing 2 different spark routes (spark's actually really well made like that, in my opinion).
Below is an example of how I typically address this [pun intended, not sorry] in my spark servers when I do NOT want 2 different routes for these:
path("/user", () ->
{
get("", GenericRoutes.redirectToSlashIndex);
get("/index.html", GenericRoutes.pathGet_index);
get("/*", GenericRoutes.redirectToIndex);
});
The idea here is that the first ("") sends to the second ("/index.html") and the third ("/*") sends any non-existing paths to the second ("/index.html") as well.
Then in Generic Routes class you'd have something like:
public static final Route redirectToIndex = new Route()
{
@Override
public Object handle(Request request, Response response) throws Exception
{
String path = request.pathInfo();
path = path.substring(0, path.lastIndexOf('/')+1)+"index.html";
response.redirect(path, 301);
return "<html>Redirecting...</html>";
}
};
public static final Route redirectToSlashIndex = new Route()
{
@Override
public Object handle(Request request, Response response) throws Exception
{
response.redirect(request.pathInfo() + "/index.html", 301);
return "<html>Redirecting...</html>";
}
};
I've simplified some of what I usually do here (you may want some more error handling in those routes and auth checks via 'before' outside of those routes). However here is a small sample of how this works:
So you can see how using something like this will allow you to send the traffic to where you'd expect. There's some things to keep in mind, however:
Mine is intentionally a bit more complicated than yours, here's how you could handle yours:
path("/user", () ->
{
/*Looks like you mentioned you had a post with the 'first version', so I think like this?*/
post("", UserRoutes.postUsers); //post: /users
put("", UserRoutes.putUsers); //put: /users
put("/*", UserRoutes.putUsers); //put: /users/
});
Note that in the last put example above you could do "/*" or just "/". With * you'll catch any path starting "/users/" whereas without * you only allow "/users/" through. So with * you could do "/users/e13a319e-16d9-3ff5-a83c-96564007998e" and it would trigger the endpoint but that same path would fail without *, this directly relates to #1 above.
So which method you go with really depends on the intent of your site and what you do or do not want those hitting your endpoints to do & see. Happy coding!
Don't know the exact reason why, but the problem was in
put("/users", (request, response) -> {
Spark wants it, in this case, to be written as
put("/users/", (request, response) -> {
Differently from "post" method that accept the first version.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With