英文:
Form data to rest PUT method in java
问题
我是Java和REST API的初学者。我有一个问题,无法将表单数据从HTML传递到REST的`PUT`方法。当我搜索关于这个问题时,大多数可用的解决方案都是针对`POST`方法的,推荐使用`FormParam`。在我的情况下,会显示以下错误:
> 请求行中收到的方法为源服务器所知,但目标资源不支持该方法。
即使我使用`PathParam`,也会返回相同的错误:
> 请求行中收到的方法为源服务器所知,但目标资源不支持该方法。
还有一些针对Spring Boot的解决方案。但我没有使用那个。
**PUT方法:**
```java
@PUT
@Path("/update")
@Produces(MediaType.TEXT_HTML)
public String updCard(@PathParam("cardNo") String cardNo,
@PathParam("reportId") int reportId
) throws SQLException {
Card c = new Card(cardNo, reportId);
System.out.println(cardNo + reportId);
return "";
}
表单:
<form method="PUT" action="rest/card/update">
<label for="cardNo">Card No: </label> <input type="text" name="cardNo" id="cardNo"><br/>
<label for="reportId">Report Id:</label> <input type="text" name="reportId" id="reportId"> <br/>
<button type="submit">Update</button>
那么,在Jersey中如何在PUT
方法中获取表单数据呢?
<details>
<summary>英文:</summary>
I am beginner for Java and REST API. I have a problem passing form data from HTML to rest `PUT` method. When I google about this, most solutions available are for `POST` method, that recommended to use `FormParam`. In my case, it shows below error:
> The method received in the request-line is known by the origin server but not supported by the target resource.
Even I use `PathParam`, same error is returned:
> The method received in the request-line is known by the origin server but not supported by the target resource.
And some solution for Spring Boot. But I did not use that.
**PUT method:**
@PUT
@Path("/update")
@Produces(MediaType.TEXT_HTML)
public String updCard(@PathParam("cardNo") String cardNo,
@PathParam("reportId") int reportId
) throws SQLException {
Card c = new Card(cardNo, reportId);
System.out.println(cardNo + reportId);
return "";
}
**Form:**
<form method="PUT" action="rest/card/update">
<label for = "cardNo">Card No: </label> <input type="text" name = "cardNo" id = "cardNo"><br/>
<label for = "reportId">Report Id:</label> <input type="text" name = "reportId" id = "reportId"> <br/>
<button type="submit">Update</button>
So, how do I get the form data in `PUT` method in Jersey?
</details>
# 答案1
**得分**: 1
如许多人在[在HTML表单中使用PUT方法][stack-put]中提到的,HTML标准目前不支持PUT方法。大多数框架将提供一种变通方法。Jersey框架通过其[HttpMethodOverrideFilter][jersey-filter]提供了这样的解决方法。你需要做的是使用POST方法并添加一个 `_method=put` 查询参数,过滤器将把POST请求转换为PUT请求。
你首先需要注册这个过滤器。如果你正在使用`ResourceConfig`,只需执行以下操作:
```java
@ApplicationPath("api")
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
...
register(HttpMethodOverrideFilter.class);
}
}
如果你在使用web.xml
,则需要执行以下操作:
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.server.filter.HttpMethodOverrideFilter</param-value>
</init-param>
然后在你的HTML中,只需在URL中添加 _method=put
查询参数。以下是我用来测试的示例:
<form method="post" action="/api/form?_method=put">
<label>
Name:
<input type="text" name="name"/>
</label>
<label>
Age:
<input type="number" name="age"/>
</label>
<br/>
<input type="submit" value="Submit"/>
</form>
在你的资源方法中,你将使用 @PUT
和 @FormParam
来处理参数:
@PUT
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response form(@FormParam("name") String name,
@FormParam("age") String age,
@Context UriInfo uriInfo) {
URI redirectUri = UriBuilder
.fromUri(getBaseUriWithoutApiRoot(uriInfo))
.path("redirect.html")
.queryParam("name", name)
.queryParam("age", age)
.build();
return Response.temporaryRedirect(redirectUri).build();
}
private static URI getBaseUriWithoutApiRoot(UriInfo uriInfo) {
String baseUri = uriInfo.getBaseUri().toASCIIString();
baseUri = baseUri.endsWith("/")
? baseUri.substring(0, baseUri.length() - 1)
: baseUri;
return URI.create(baseUri.substring(0, baseUri.lastIndexOf("/")));
}
根据我的测试,这应该可以正常工作。
英文:
As mentioned by many in Using PUT method in HTML form, PUT is not currently supported by the HTML standard. What most frameworks will do is offer a workaround. Jersey has such a workaround with its HttpMethodOverrideFilter. What you must do is use a POST method and add a _method=put
query parameter and the filter will switch the POST to a PUT.
You first need to register the filter. If you are using a ResourceConfig just do
@ApplicationPath("api")
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
...
register(HttpMethodOverrideFilter.class);
}
}
If you are using a web.xml, then do
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.server.filter.HttpMethodOverrideFilter</param-value>
</init-param>
Then in your HTML, you will just add the _method=put
query param to the URL. Below is an example I used to test
<form method="post" action="/api/form?_method=put">
<label>
Name:
<input type="text" name="name"/>
</label>
<label>
Age:
<input type="number" name="age"/>
</label>
<br/>
<input type="submit" value="Submit"/>
</form>
And in your resource method you will use @PUT
and @FormParam
s for the paramters
@PUT
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response form(@FormParam("name") String name,
@FormParam("age") String age,
@Context UriInfo uriInfo) {
URI redirectUri = UriBuilder
.fromUri(getBaseUriWithoutApiRoot(uriInfo))
.path("redirect.html")
.queryParam("name", name)
.queryParam("age", age)
.build();
return Response.temporaryRedirect(redirectUri).build();
}
private static URI getBaseUriWithoutApiRoot(UriInfo uriInfo) {
String baseUri = uriInfo.getBaseUri().toASCIIString();
baseUri = baseUri.endsWith("/")
? baseUri.substring(0, baseUri.length() - 1)
: baseUri;
return URI.create(baseUri.substring(0, baseUri.lastIndexOf("/")));
}
It should work from what I tested
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论