gpt4 book ai didi

java - RESTEasy - 在@GET/@POST 时重用方法参数

转载 作者:行者123 更新时间:2023-12-03 23:15:04 25 4
gpt4 key购买 nike

我的 RESTEasy 服务中有一个方法,我想将它用作 @GET/@POST,它的数据可能来自查询字符串和请求正文。

@GET
@POST
public String myMethod(@QueryParam("param1") @FormParam("param1") String param1,
@QueryParam("param2") @FormParam("param1") String param2) {
// ...do things
}

但是,我还没有找到不执行以下操作的方法:

@GET
public String myMethod(@QueryParam("param1") String param1, @QueryParam("param2") String param2) {
// ...do things
}

@POST
public String myMethod2(@FormParam("param1") String param1, @FormParam("param2") String param2) {
return this.myMethod(param1, param2);
}

有谁知道如何使第一个示例工作,或者使用尽可能少的代码的其他方法?

最佳答案

引用RESTful Java with JAX-RS这本书:

JAX-RS defines five annotations that map to specific HTTP operations:

  • @javax.ws.rs.GET
  • @javax.ws.rs.PUT
  • @javax.ws.rs.POST
  • @javax.ws.rs.DELETE
  • @javax.ws.rs.HEAD

(...)
The @GET annotation instructs the JAX-RS runtime that this Java method will process HTTP GET requests to the URI. You would use one of the other five annotations described earlier to bind to different HTTP operations. One thing to note, though, is that you may only apply one HTTP method annotation per Java method. A deployment error occurs if you apply more than one.

(以上文字由 ​​RESTEasy 的创建者编写。)

并且,简而言之,由于 RESTEasy 符合 JAX-RS,您不能使用多个 HTTP 动词注释一个方法。

如果你不相信,看看@GET注解,你会发现它只是一个元注解@HttpMethod.

/**
* Indicates that the annotated method responds to HTTP GET requests
* @see HttpMethod
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@HttpMethod(HttpMethod.GET)
public @interface GET {
}

如果你打开@HttpMethod,检查javadoc(如果一个方法被多个注解注解是错误的HttpMethod.):

/**
* Associates the name of a HTTP method with an annotation. A Java method annotated
* with a runtime annotation that is itself annotated with this annotation will
* be used to handle HTTP requests of the indicated HTTP method. It is an error
* for a method to be annotated with more than one annotation that is annotated
* with {@code HttpMethod}.
*
* @see GET
* @see POST
* @see PUT
* @see DELETE
* @see HEAD
*/
@Target({ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface HttpMethod
{

所以,就是这样,你不能在同一个方法中同时使用它们。


就是说,如果您真的必须这样做,您可以通过将在 JAX-RS 方法之前调用的 PreProcessInterceptor 来实现。

不过,这种方式要复杂得多(因为您必须自己解析参数)并且可维护性要差得多(服务在拦截器上交付!?)。

总而言之,据我所知,您的解决方案是最优的。

检查我在下面的测试中所说的内容:

public class QueryAndFormParamTest  {

@Path("/")
public static class InterceptedResource {
@GET
//@Path("/stuff") // uncomment this and it will not work
public String otherService(@QueryParam("yadda") String name){
return "Im never called in this example" + name;
}
}

public static class MyInterceptor implements PreProcessInterceptor, AcceptedByMethod {
@Override
public boolean accept(Class declaring, Method method) {
System.out.println("Accepted by method "+method.getName());
// you can check if this interceptor should act on this method here
return true; // it'll act everytime
}

@Override
public ServerResponse preProcess(HttpRequest request, ResourceMethod method)
throws Failure, WebApplicationException {

// parsing form parameters
if (request.getHttpHeaders().getMediaType() != null && request.getHttpHeaders().getMediaType().isCompatible(MediaType.valueOf("application/x-www-form-urlencoded"))) {
MultivaluedMap<String, String> formParameters = request.getFormParameters();
if (formParameters != null) {
for (String key : formParameters.keySet()) {
System.out.println("[FORM] "+key + ": "+formParameters.get(key));
}
}
}

// parsing query parameters
MultivaluedMap<String, String> queryParameters = request.getUri().getQueryParameters();
if (queryParameters != null)
for (String key : queryParameters.keySet()) {
System.out.println("[QUERY] "+key + ": "+queryParameters.get(key));
}

String responseText = "do something: " + request.getUri().getQueryParameters().getFirst("test");
return new ServerResponse(responseText, 200, new Headers<Object>());
}
}

@Test
public void test() throws Exception {
Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();
dispatcher.getProviderFactory().getServerPreProcessInterceptorRegistry().register(new MyInterceptor());
dispatcher.getRegistry().addSingletonResource(new InterceptedResource());

MockHttpRequest request = MockHttpRequest.get("/?test=someStuff");
MockHttpResponse response = new MockHttpResponse();

dispatcher.invoke(request, response);

System.out.println(response.getContentAsString());
Assert.assertEquals("do something: someStuff", response.getContentAsString());
}
}

关于java - RESTEasy - 在@GET/@POST 时重用方法参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16483370/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com