# JAX-RS



## fsicher (9. Aug 2011)

Hallo 

Ich möchte mit JAX-RS ein WebService zur Verüfigung stellen, mit dem beispielsweise Benutzer angelegt, editiert, gesucht und gelöscht werden können. Um es kurz zu machen, möchte ich folgende zwei Möglichkeiten haben, eine Ressource zu finden (findById-Methode):

- *http://localhost:8080/myapp/user/7*

und auch 

- *http://localhost:8080/myapp/user?id=7
*

Im zweiten Fall könnte ich z.B. die Id in einem Formular eingeben, der Erste Fall ergibt sich nach dem Erstellen der Ressource (die URI kann aus Headers abgefragt werden). 

Meine Frage: 
Muss ich, um dies zu erreichen, zwei Methoden zur Verfügung stellen, bei der einmal der Id-Wert durch *@PathParam* und das andere Mal durch *@QueryParam* injiciert wird? Und, die Methoden müssten unterschiedlich heissen und unterschiedliche *@Path*-Werte haben? Oder, kann man das doch mit nur einer Methode erschlagen?

Danke.


----------



## Gelöschtes Mitglied 5909 (9. Aug 2011)

Meines wissens geht das nicht, da das REST mäßig eine andere bedeutung hat.
PathParam werden als "Subresource" verwendunt und queryparams werden für die "Suche".

Würde also nur so gehn:


```
@Path("/user")
public class UserResource {


@GET
Response getUserById(@QueryParam("id") Long id);

@GET
@Path("/{id}")
Response getUser(@PathParam("id") Long id);

}
```

Das was du machen willst ist imo im strengen sinne nicht 100%ig RESTful. Ich würde den weg über PathParam gehen und für das formular eine extra methode machen und dann auch FormParams nehmen


----------



## fsicher (9. Aug 2011)

Danke erstmal. 

Wenn ich dich richtig verstanden habe, könnte die zweite Methode (für die Suche aus einem Formular, in dem ich die Id eingeben) wie folgt aussehen: 


```
@Path("/user")
public class UserResource {
 
// Die erste: [url]http://localhost:8080/myapp/user/7[/url]

@GET
@Path("/{id}")
Response getUser(@PathParam("id") Long id); 



// Die zweite: [url]http://localhost:8080/myapp/user?id=7[/url]

@GET
@Path("/single/{id}")
Response getUserForm(@FormParam("id") Long id);

}
```

Nun, habe ich es irgendwie nicht zum Laufen gebracht: etwas habe ich noch nicht ganz verstanden. 

Zum Beispiel, worin besteht der Unterschied, wenn ich bei der zweiten Methode *@PathParam* durch *@QueryParam* ersetzte? Ist der Unterschied eher semantisch? Oder, bin ich voll auf dem Holzweg ... ???:L


----------



## Gelöschtes Mitglied 5909 (10. Aug 2011)

```
@GET
@Path("/form1")
Response getUserForm(@FormParam("id") Long id);
```

FormParams sind teil des bodys, nicht der url


----------



## fsicher (10. Aug 2011)

Vielen Dank.

Es will aber immer noch nicht ...

[XML]
exception

javax.servlet.ServletException: com.sun.jersey.api.container.ContainerException: Exception obtaining parameters
	com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:425)
	com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
	com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

root cause

com.sun.jersey.api.container.ContainerException: Exception obtaining parameters
	com.sun.jersey.server.impl.inject.InjectableValuesProvider.getInjectableValues(InjectableValuesProvider.java:54)
	com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$EntityParamInInvoker.getParams(AbstractResourceMethodDispatchProvider.java:153)
	com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:183)
	com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
	com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288)
	com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
	com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
	com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
	com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
	com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1465)
	com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1396)
	com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1345)
	com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1335)
	com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
	com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
	com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

root cause

java.lang.IllegalStateException: The @FormParam is utilized when the content type of the request entity is not application/x-www-form-urlencoded
	com.sun.jersey.server.impl.model.parameter.FormParamInjectableProvider$FormParamInjectable.getValue(FormParamInjectableProvider.java:81)
	com.sun.jersey.server.impl.inject.InjectableValuesProvider.getInjectableValues(InjectableValuesProvider.java:46)
	com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$EntityParamInInvoker.getParams(AbstractResourceMethodDispatchProvider.java:153)
	com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:183)
	com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
	com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288)
	com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
	com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
	com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
	com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
	com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1465)
	com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1396)
	com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1345)
	com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1335)
	com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
	com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
	com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699)
[/XML]

Meine Methode:


```
@GET
@Path("/form1")
public Response getByIdForm(@FormParam("id") Long id) {

	// ...
}
```

Und das eifache Formular: 

[XML]
<h3>Show User</h3>
<form action="http://localhost:8080/myapp/form1" method="get" >
	<table>
		<tr>
			<td>User Id:</td>
			<td><input type="text" name="id" /></td>
			<td><input type="submit" value="Show" /></td>
		</tr>
	</table>
</form>
[/XML]


Wenn ich anstatt *@GET* die *@POST* nehme, funktioniert es. Und, das ist wiederum nicht REST-Like ...


```
@POST
@Path("/form1")
@Consumes({ "application/x-www-form-urlencoded" })  // Zeile A
public Response getByIdForm(@FormParam("id") Long id) {
    // ...
}
```

Und, die "Zeile A" darf auch nicht fehlen, da ansonsten "UnsuportedMedia ..." Ausnahme geworfen wird.

Noch ein weiterer Punkt, den ich nicht ganz verstehe und um Aufklärung froh wäre: 


> FormParams sind teil des bodys, nicht der url



Ich war der Meinung, dass HTTP Methode GET immer dazu führt, dass die im Formular eingegebenen Werte als URL-Anhang übermittelt werden (sichtbar). Wenn ich im meinem Formular mit *method="get"* arbeite (muss ich wegen *@GET*), werden die eingegebenen Werte so angehängt und übermittelt. Und, woher soll jetzt *@FormParam* Werte auslesen, wenn sie im Body nicht zu finden sind (da Teil der URL)? Oder, kann man das doch?


----------

