我正在尝试使用 jersey 框架实现 jax-rs Web 服务。我已经编写了 Web 服务,但我不完全理解 web.xml 标签的含义,所以我不知道我是否已正确配置它,但当我尝试访问该服务时,我收到错误。这是网络服务:
package org.LMS.Controller;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path ("/test")
public class Test {
private String name = "Worked";
@GET
@Produces (MediaType.APPLICATION_XHTML_XML)
public String getTest ()
{
return name;
}
}
Run Code Online (Sandbox Code Playgroud)
我的 web.xml 是:
<!-- Test web service mapping -->
<servlet>
<display-name>Test</display-name>
<servlet-name>Test</servlet-name>
<servlet-class>org.LMS.Controller</servlet-class>
<init-param>
<param-name>org.LMS.Controller.Test</param-name>
<param-value>eduscope</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Test</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping>
<!--end Test web service mapping -->
Run Code Online (Sandbox Code Playgroud)
这是我尝试访问我的应用程序时遇到的错误: HTTP Status 500 - type Exception report message …
MediaTypes我的服务方法 产生它可能产生的其中之一pdf或excel文件或其他。
@Produces({"application/pdf","application/vnd.ms-excel"...
Run Code Online (Sandbox Code Playgroud)
我的问题
我的服务返回响应类型为application/pdfalways,即使它产生excel. 为什么?
比我重新安排MediaTypes。
@Produces({"application/vnd.ms-excel","application/pdf",...
Run Code Online (Sandbox Code Playgroud)
现在它application/vnd.ms-excel再次为所有响应提供类型,为什么?
我正在com.sun.jersey为客户端使用 API 并通过使用获取类型
clientResponse.getType()
Run Code Online (Sandbox Code Playgroud)
可能我认为我误解了注释的概念@Produces。
请澄清。
以下是我的服务方法的代码。
response = Response.ok((Object) file);//file is Object of File
response.header("Content-Disposition","attachment; filename="+filename);
//filename can be a.pdf b.xlsx etc
return response.build();
Run Code Online (Sandbox Code Playgroud) JAX-RS 提供了 StreamingOutput 接口,我们可以实现它来对我们的响应主体进行原始流式处理。
public interface StreamingOutput {
void write(OutputStream output)
}
Run Code Online (Sandbox Code Playgroud)
我不确定他们为什么要构建一个接口来公开响应输出流。为什么不直接注入一个 OutputStream ,我们可以简单地写入它!
我正在尝试确定与变量为 的 Jersey 客户端端点交互的最佳方式Collection<String>。我不是 100% 确定这样做是正确的,但我想知道这是否可能/实现这一目标的正确方法是什么 - 也许@POST带有消息正文?
我的方法DAO是Set<Foo> retrieveByKeys(Collection<String> keys). 因此,我试图找出为此创建端点的最佳方法。第一个想法是:
@POST
@Path('/foos')
@Consumes(MediaType.APPLICATAION_JSON)
@Produces(MediaType.APPLICATAION_JSON)
Response retrieveByKeys(Collection<String> keys) {
... //do things
}
Run Code Online (Sandbox Code Playgroud)
或者:
@GET
@Path('/foos')
Response retrieveByKeys(@QueryParam('keys') Collection<String> keys) {
... //do things
}
Run Code Online (Sandbox Code Playgroud)
我不太确定您是否可以执行第二个操作,但有人建议将其作为可能的解决方案。
无论哪种方式都很好,但同时我的另一种方法DAO是List<Foo> retrievePageStartingFrom(String startKey, int pageSize). 我知道在可能的情况下重用 url 是最佳的休息实践,这就是我试图用这两个做的。我只是在努力寻找一种方法来区分这两种方法,但要保持相同的 url。
我想知道是否有可能用其他方式重载端点,@QueryParams但这次是:
@GET
@Path('/foos')
Response retrievePageStartingFrom(@QueryParam('startKey') String startKey, @QueryParam('pageSize') int pageSize) {
... //do things
}
Run Code Online (Sandbox Code Playgroud)
并且 Jersey 客户端会知道区分这两个调用,因为第一个方法有一个参数,第二个方法有两个也是不同类型的参数。
我想我想我想要做的最好的方法是在 java …
当我有一个非常基本的Application. Jersey 时,它会自动发现项目中的所有 REST 资源,而我不必手动注册它们:
import javax.ws.rs.ApplicationPath;
@ApplicationPath("/rest")
public class Application extends javax.ws.rs.core.Application {
}
Run Code Online (Sandbox Code Playgroud)
但是当我切换到使用 Jersey specific 时ResourceConfig,自动发现似乎不起作用。我必须#registerClasses()或者添加如下所示的包:
@ApplicationPath("rest")
public class ResourceConfig extends org.glassfish.jersey.server.ResourceConfig {
public ResourceConfig() {
super();
register(RolesAllowedDynamicFeature.class);
super.packages(true, "org.example");
}
}
Run Code Online (Sandbox Code Playgroud)
有没有办法ResourceConfig自动发现 REST 资源,例如Application无需单独注册类或添加应用程序包?
对于基于角色的 RESTful API 访问,将访问权限存储在数据库表中是否是常见做法(并被认为是安全的)?我指的是用于限制用户访问某些端点、HTTP 方法(GET、POST、PUT、DELETE)或限制在查询中接受/返回哪些字段的访问权限。
或者访问权限是否更典型地存储在应用程序代码中(即,基于角色的逻辑编译到 API 本身中)?更一般地说,处理 RESTful API 的自定义访问权限的推荐方法是什么?
我不是指 API 本身的用户身份验证或基于 OAuth 的授权,这将通过标准的基于令牌的机制处理。
我们正在 Java EE 7 中构建一个 RESTful API,它包括一个基于角色的访问控制机制,以确定在查询中接受/返回哪些端点、HTTP 方法和字段。在我们最初的设计中,我们在端点方法上使用容器请求过滤器读取的自定义注释来根据用户的角色确定用户的权限,并在(反)序列化过程中使用JsonView来过滤特定的实体字段。
该系统有效,但我们觉得它变得过于复杂且难以维护。我们已经讨论过将此授权信息移动到几个数据库表中,最重要的是一个存储表和列访问权限(PK 和 FK 列摘录)的表。
AccessPermissions
========================
| Column | Type |
========================
| TableName | varchar |
| ColumnName | varchar |
| HasCreate | bit |
| HasRead | bit |
| HasUpdate | bit |
| HasDelete | bit |
Run Code Online (Sandbox Code Playgroud)
每个角色(表未显示)可能会引用该AccessPermissions表中的许多行,以便端点方法访问和(反)序列化都可以通过询问用户是否具有允许请求访问的查询表和列名的条目来实现。
例如,POST /endpoint1with{"field1": …
请不要将其视为重复请求,因为我已经浏览了 stackoverflow 中的所有帖子,但没有人回答。我没有找到任何回应。
问题是:
我面临一个非常奇怪的问题,通过独立应用程序(在 main() 内)使用相同的代码段发出 GET 请求。它的工作原理就像将相同的代码放在 Java EE 应用程序中并部署在 Wildfly 10 服务器上一样,它会给出错误
“无法找到内容类型为 text/html 且类型为接口 java.util.List 的 MessageBodyReader”
代码:
ClientConfig configuration = new ClientConfig();
configuration.property(ClientProperties.CONNECT_TIMEOUT, 10000);
configuration.property(ClientProperties.READ_TIMEOUT, 10000);
Client iexRestClient=ClientBuilder.newClient(configuration);
WebTarget webTarget =
iexRestClient.target("https://api.iextrading.com/1.0/ref-data/symbols/");
Response response =
webTarget.request().accept(MediaType.APPLICATION_JSON).get(Response.class);
System.out.println("response status "+response.getStatus());
List<IEXTicker> tickers = response.readEntity(new
GenericType<List<IEXTicker>>(){});
System.out.println("size of tickers "+tickers.size());
Run Code Online (Sandbox Code Playgroud)
所需的 jars(pom.xml 文件)
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.26</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>2.26</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.26</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
模型类:IEX_Ticker.java
@Entity
@Table(name = "IEX_Ticker")
@JsonIgnoreProperties(ignoreUnknown = true)
public …Run Code Online (Sandbox Code Playgroud) 我有一个使用 Jersey v2.25.1 的项目。我使用 Jersey 的内置 HK2 注入来执行依赖注入,一切正常。快进到现在,我决定更新到 Jersey v2.27。
当我运行我的项目时,出现以下异常:
java.lang.IllegalStateException: InjectionManagerFactory not found
Run Code Online (Sandbox Code Playgroud)
经过一番谷歌搜索,我发现我需要添加jersey-hk2依赖项。这样做使我得到以下异常:
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=<MyClass>,parent=<MyClass>,qualifiers={},position=0,optional=false,self=false,unqualified=null,1044705957)
Run Code Online (Sandbox Code Playgroud)
将我的所有依赖项恢复到 Jersey v2.25.1 后,一切正常。我需要做什么来修复这些错误,以便我可以使用 Jersey v2.27?
编辑:我不使用 Maven,所以我不能真正发布一个pom.xml.
在 REST 服务中处理异常的一种典型方法是定义自定义异常类型(通常来自RuntimeException),然后实现一个映射器类来生成 HTTP 代码,例如:
public class MyExceptionMapper implements ExceptionMapper<MyException> {
@Override
public Response toResponse(MyExceptionex) {
return Response.status(400).entity("bad request")
.type(MediaType.APPLICATION_JSON).build();
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我有两个问题:
Throwable为了生成 HTTP 500 而实现一个 for时,它不会再次捕获我自己的异常吗?或者可以定义映射器工作的顺序?EJBException或一些Transaction...Exception包裹?我正在尝试从头开始一个基于 Jersey/1.7 的项目(而不是复制现有项目并在顶部添加新代码,这是我的客户通常所做的),以了解工作原理。我陷入了一个非常早期的阶段,试图处理一个简单的 HTTP 请求:
package com.example.foo.view.rest;
import javax.ws.rs.Path;
import javax.annotation.security.RolesAllowed; // package javax.annotation.security does not exist
@Path("user")
@RolesAllowed("valid-users") // cannot find symbol
public class UserService extends BaseService {
public UserService() {
super();
}
}
Run Code Online (Sandbox Code Playgroud)
我从另一个项目复制了这些文件:
asm-3.1.jar
jackson-core-asl-1.9.2.jar
jackson-jaxrs-1.9.2.jar
jackson-mapper-asl-1.9.2.jar
jackson-xc-1.9.2.jar
jersey-client-1.17.jar
jersey-core-1.17.jar
jersey-json-1.17.jar
jersey-multipart-1.17.jar
jersey-server-1.17.jar
jersey-servlet-1.17.jar
jettison-1.1.jar
jsr311-api-1.1.1.jar
Run Code Online (Sandbox Code Playgroud)
项目身份验证与 Oracle SSO(Oracle 身份目录)一起使用。
javax.annotation.security.RolesAllowed我唯一能找到的是一个接口,我当然在我的代码库中的任何地方都看不到实际的实现。事实上,整个javax.annotation.security包裹都不见了。我什至不知道应该提供什么图书馆。
我很感激任何提示,无论它看起来多么明显。
jax-rs ×10
java ×8
jersey ×4
rest ×3
annotations ×1
hk2 ×1
jakarta-ee ×1
javax ×1
jboss ×1
jdeveloper ×1
jersey-2.0 ×1
oid ×1
servlets ×1
weblogic11g ×1
wildfly-10 ×1