标签: jax-rs

适用于RESTful GUI应用程序的最先进的Java Web框架?

是的,我知道,最好的网络框架的老问题......但让我解释一下.

我正在寻找基于Java Servlet的Web框架,它允许RESTful交互,也适合构建Web GUI.

我想要的是:

  • REST支持与http内容协商和良好的URL映射
  • 从请求参数到域对象的数据转换(理想情况下也是另一个方向)
  • 无需将域对象复制为Web的接口(如struts)
  • 易于EJB集成
  • 依赖注入应该由Java EE服务器执行
  • 可理解的代码(我不喜欢Spring MVC类路径中组件的魔法线路)
  • 易于配置(在Spring中没有配置的神奇配置在容器中是繁琐的 - 我更喜欢直接依赖)
  • 不应该重新发明轮子,例如应该使用JPA和BeanValidation之类的东西,而不是框架重新发明,或者至少这些标准应该易于使用.
  • 验证支持,在表单中显示错误
  • 支持国际化

候选人:

  • Spring MVC功能强大,但我厌倦了Spring配置,不喜欢编程模型.我认为它有点过于抽象和灵活,因此需要进行大量配置.我不喜欢Spring MVC使用注释的方式.但是也存在一些设计缺陷,比如return通过输出参数返回值的方法- 真的很难看!我认为使用Spring MVC和Java EE依赖注入并不容易,因为Spring MVC严重依赖于Spring DI.

  • Roo似乎很酷,但它只是创建一个Spring MVC应用程序的另一种方式,它用AOP做了一些奇怪的事情.

  • Struts有点尴尬和outdatet.

  • Stripes ActionBean方法看起来并不比Struts好多少.我不喜欢它.

  • Grails很好,但是马车(至少在1.2之前).重新发明轮子:例如,我更喜欢JPA胜过Gorm.

另请参阅10个最佳Java Web框架

我不是在服务器上寻找具有UI状态的框架,如Wicket,Tapestry或JSF.我认为这种方法与网络的基本原则相矛盾!

那么该怎么办?从头开始编写框架?嗯......

我想拥有像JAX-RS这样的东西,支持经典的浏览器GUI.例如,框架应支持验证并将验证错误放入重新显示的表单中.有类似的东西吗?有什么建议?

java frameworks servlets jax-rs

12
推荐指数
2
解决办法
5061
查看次数

JAX-RS/Rest:多次设置一个参数,还是使用一个逗号分隔的参数?

我读到在请求中传递数组的HTTP方法是多次设置一个参数:

1) GET /users?orderBy=last_name&orderBy=first_name
Run Code Online (Sandbox Code Playgroud)

但是,我也看到了逗号分隔的参数(我觉得这是"更干净"):

2) GET /users?orderBy=last_name,first_name
Run Code Online (Sandbox Code Playgroud)

我想实现多排序(通过last_name排序用户,然后复制last_names由first_name排序).代码方面,这很容易(谷歌的番石榴图书馆拯救),但我应该如何揭露这个?第一种方法是否保留字段的顺序(按last_name排序,然后按first_name排序)?

如果在请求中多次设置,Spring会将参数神奇地转换为String []数组:

... @RequestParam("orderBy") String[] orderBy ... becomes ["last_name","first_name"]
Run Code Online (Sandbox Code Playgroud)

这让我相信第一种方式被认为是最佳实践,尽管我喜欢第二种方式......

parameters jax-rs

12
推荐指数
2
解决办法
1万
查看次数

12
推荐指数
1
解决办法
1万
查看次数

为什么Jersey的UriBuilder.build方法编码#'和%',但不是/?

我有一个相当典型的REST API,除了资源的id不是整数,而是字符串,通常包含/字符.因此,如果客户的ID是string/with/slashes该客户的URI应该是http://localhost/customers/string%2Fwith%2Fslashes.返回客户列表时,我想用UriBuilder构造URI,这样我就可以把它放在ATOM风格的链接元素的href中.但它不太有效; 这是一个小测试类,显示我的意思:

@Path("/customers")
public class JerseyTest {

  @Path("{id}")
  public Customer getCustomer(@PathParam("{id}") String id) {
    return null;
  }

  public static void main(String[] args) {
    buildURI("string#with#hashes"); // => http://localhost/customers/string%23with%23hashes
    buildURI("string/with/slashes"); // => http://localhost/customers/string/with/slashes
  }

  public static void buildURI(String id) {
    UriBuilder builder = UriBuilder.fromUri("http://localhost");
    builder.path(JerseyTest.class).path(JerseyTest.class, "getCustomer");
    URI uri = builder.build(id);
    System.out.println(uri);
  }
}
Run Code Online (Sandbox Code Playgroud)

#太棒了,我们编码为我所期望的,但/我们做不.我尝试使用builder.build(URLEncoder.encode(id)),但随后UriBuilder编码了%,所以你得到了.../string%252Fwith%252Fslashes!

在我看来,不一致的,它编码#%而不是/,但我怀疑是有很好的理由对此我没有看到.所以我的问题是:

  1. 我怎样才能得到UriBuilder给我.../string%2Fwith%2Fslashes …

rest jax-rs urlencode jersey

12
推荐指数
1
解决办法
5040
查看次数

是否可以使用JAX-RS设置ETag而无需使用Response对象?

在我发现的关于JAX-RS和缓存的少数几个问题(有答案)中,生成ETag(用于缓存)的答案是在Response对象上设置一些值.如下所示:

@GET
@Path("/person/{id}")
public Response getPerson(@PathParam("id") String name, @Context Request request){
  Person person = _dao.getPerson(name);

  if (person == null) {
    return Response.noContent().build();
  }

  EntityTag eTag = new EntityTag(person.getUUID() + "-" + person.getVersion());

  CacheControl cc = new CacheControl();
  cc.setMaxAge(600);

  ResponseBuilder builder = request.evaluatePreconditions(person.getUpdated(), eTag);

  if (builder == null) {
    builder = Response.ok(person);
  }

  return builder.cacheControl(cc).lastModified(person.getUpdated()).build();
}
Run Code Online (Sandbox Code Playgroud)

问题是对我们不起作用,因为我们对SOAP和REST服务使用相同的方法,通过使用@WebMethod(SOAP),@ GET(以及我们可能需要公开服务的任何其他方法)来注释方法.以前的服务对我们来说是这样的(不包括标题的创建):

@WebMethod
@GET
@Path("/person/{id}")
public Person getPerson(@WebParam(name="id") @PathParam("id") String name){
  return _dao.getPerson(name);
}
Run Code Online (Sandbox Code Playgroud)

有没有办法 - 通过一些额外的配置 - 设置这些标题?这是我第一次发现使用Response对象实际上只比自动转换有一些好处...

我们正在使用Apache CXF.

java etag caching cxf jax-rs

12
推荐指数
1
解决办法
5991
查看次数

使用Joda DateTime作为Jersey参数?

我想DateTime在泽西岛使用Joda的查询参数,但泽西开箱即用不支持.我假设实现一个InjectableProvider是添加DateTime支持的正确方法.

可有人点我一个很好的实现的InjectableProviderDateTime?或者是否有值得推荐的替代方法?(我知道我可以转换DateString在我的代码,但是这似乎是一个更小的解决方案).

谢谢.

解:

我在下面修改了Gili的答案,使用@ContextJAX-RS中的注入机制而不是Guice.

更新:如果未在服务方法参数中注入UriInfo,则可能无法正常工作.

import com.sun.jersey.core.spi.component.ComponentContext;
import com.sun.jersey.spi.inject.Injectable;
import com.sun.jersey.spi.inject.PerRequestTypeInjectableProvider;
import java.util.List;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.ext.Provider;
import org.joda.time.DateTime;

/**
 * Enables DateTime to be used as a QueryParam.
 * <p/>
 * @author Gili Tzabari
 */
@Provider
public class DateTimeInjector extends PerRequestTypeInjectableProvider<QueryParam, DateTime>
{
    private final UriInfo uriInfo;

    /**
     * Creates a new …
Run Code Online (Sandbox Code Playgroud)

java jax-rs jersey jodatime

12
推荐指数
1
解决办法
6496
查看次数

Jax-rs自动解码路径参数

我有一个jax-rs服务,它接收路径中的一组参数pathparameters.这些参数可能是包含不适合url的值的字符串,因此它们在客户端使用java.net.UrlEncoder进行urlencoded,如下所示:

String param = URLEncoder.encode(o.toString(), "UTF-8");
Run Code Online (Sandbox Code Playgroud)

这用于构建URL supplier/group/param1/param2/param3.如果其中一个因urlencoding而被更改,例如,如果它只是一个空格,则在服务上接收的字符串是一个+符号.

@GET
@Path("{supplierId}/{groupCode}/{groupId}")
@Produces({MediaType.APPLICATION_XML, MediaType.TEXT_XML})
public SupplierGroup getSupplierGroup(@PathParam("supplierId") BigDecimal supplierId,
        @PathParam("groupCode") String groupCode,
        @PathParam("groupId") BigDecimal groupId) {
    //now groupCode is "+", not " "
}
Run Code Online (Sandbox Code Playgroud)

我希望jaxrs能够自动解码编码路径参数.

编辑:测试更多我发现,当发送使用%20空间时,它能够解码参数.

encoding jax-rs

12
推荐指数
1
解决办法
1万
查看次数

javax.ws.rs.NotFoundException:无法使用RESTEasy和Wildfly 8.1.0.Final查找完整路径的资源

我正面临以下问题.我已经花了3天多的时间,但找不到解决方案.请指导我在这里做错了什么.我是野生蝇新来的Resteasy.

这是堆栈跟踪

19:05:57,610 WARN  [org.jboss.resteasy.core.ExceptionHandler] (default task-14) failed to execute: javax.ws.rs.NotFoundException: Could not find resource for full path: http://localhost:8080/admin-ws/services/user/getUser
    at org.jboss.resteasy.core.registry.ClassNode.match(ClassNode.java:73) [resteasy-jaxrs-3.0.8.Final.jar:]
    at org.jboss.resteasy.core.registry.RootClassNode.match(RootClassNode.java:48) [resteasy-jaxrs-3.0.8.Final.jar:]
    at org.jboss.resteasy.core.ResourceMethodRegistry.getResourceInvoker(ResourceMethodRegistry.java:444) [resteasy-jaxrs-3.0.8.Final.jar:]
    at org.jboss.resteasy.core.SynchronousDispatcher.getInvoker(SynchronousDispatcher.java:234) [resteasy-jaxrs-3.0.8.Final.jar:]
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:171) [resteasy-jaxrs-3.0.8.Final.jar:]
    at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:220) [resteasy-jaxrs-3.0.8.Final.jar:]
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56) [resteasy-jaxrs-3.0.8.Final.jar:]
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51) [resteasy-jaxrs-3.0.8.Final.jar:]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) [jboss-servlet-api_3.1_spec-1.0.0.Final.jar:1.0.0.Final]
    at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:61) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:113) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:56) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:45) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:61) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:70) …
Run Code Online (Sandbox Code Playgroud)

java rest jax-rs resteasy wildfly-8

12
推荐指数
2
解决办法
3万
查看次数

ExceptionMapper的执行顺序

我有一个异常映射器如下

import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;

@Provider
public class NotFoundMapper implements ExceptionMapper<NotFoundException> {

    private final Logger log = LoggerFactory.getLogger(getClass());
    private final MapperResponseBuilder responseBuilder = new MapperResponseBuilder();

    @Override
    public Response toResponse(NotFoundException ex) {
        log.warn("NotFoundException : " + ex.getMessage(), ex);
        return responseBuilder.buildErrorResponse(ex.getMessage(), Status.BAD_REQUEST);
    }
}
Run Code Online (Sandbox Code Playgroud)

所以NotFoundException是一个RuntimeException.我想有3个异常映射器,它们映射

  1. 具有高优先级的NotFoundException
  2. 具有下一个优先级的RuntimeException
  3. 最后是例外

有没有办法优先考虑那些?

java jax-rs

12
推荐指数
1
解决办法
2630
查看次数

使用外部枚举定义从JAX-RS端点生成Swagger

我想通过外部枚举定义从JAX-RS端点生成一个招摇,但生成的swagger直接包含枚举到模型的定义中.这意味着不会生成枚举文档,而是在客户端复制相同的枚举.

我使用swagger-jaxrs依赖项来扫描我的端点并生成swagger json文件.此GitHub 存储库可用于重现该问题.我还在swagger-core存储库上创建了一个GitHub 问题.

JAX-RS端点

@Api("hello")
@Path("/helloSwagger")
public class HelloSwagger {

    @ApiOperation(value = "Get all unique customers", notes = "Get all customers matching the given search string.", responseContainer = "Set", response = User.class)
    @GET
    @Path("/getUniqueUsers")
    @Produces(MediaType.APPLICATION_JSON)
    public Set<User> getUniqueUsers(
            @ApiParam(value = "The search string is used to find customer by their name. Not case sensitive.") @QueryParam("search") String searchString,
            @ApiParam(value = "Limits the size of the result set", defaultValue = "50") @QueryParam("limit") int limit
    ) { …
Run Code Online (Sandbox Code Playgroud)

java rest enums jax-rs swagger

12
推荐指数
1
解决办法
1584
查看次数