我正在使用CXF 2.2.5中的JAX-RS支持来调用REST Web服务。我为需要与之通信的每个终结点(通常是一个或两个终结点,对于任何给定的部署)创建一个org.apache.cxf.jaxrs.client.WebClient实例,并为每个Web服务调用重用此客户端。
我面临的问题是,尽管使用了保持活动设置,客户端仍在为每个请求创建与服务器的新TCP连接。在高流量水平下,这会引起问题。下面是我的客户代码的摘录。
我试图通过CXF资源进行挖掘,以找出问题所在,但目前无可救药地迷失了方向。任何想法表示赞赏。
谢谢,FB
ConcurrentMap<String, WebClient> webclients = new ConcurrentHashMap<String, WebClient>();
public void dispatchRequest(MyRequestClass request, String hostAddress) {
// Fetch or create the web client if we don't already have one for this hostAddress
// NOTE: WebClient is only thread-safe if not changing the URI or headers between calls!
// http://cxf.apache.org/docs/jax-rs-client-api.html#JAX-RSClientAPI-ThreadSafety
WebClient client = webclients.get(hostAddress);
if (client == null) {
String serviceUrl = APP_HTTP_PROTOCOL + "://" + hostAddress + ":" + APP_PORT + "/" + APP_REQUEST_PATH;
WebClient newClient …Run Code Online (Sandbox Code Playgroud) 我想从java服务器(Restful Jax-rs)发送一个图像.我的客户端是Android.
@GET
public Response getUserImage() {
byte[] image =new byte[1024];
return Response.ok(image, MediaType.APPLICATION_OCTET_STREAM).header("content-attachment; filename=image_from_server.png") .build();
Run Code Online (Sandbox Code Playgroud)
但这里有一个下载框即将推出.所以我想下载没有下载框,当我在浏览器上运行请求URL时,它应该自动打开.谢谢.
我试图将一些自定义标头参数添加到HTTP 303(重定向)响应.但是,新标题似乎从响应中被剥离.
此代码用于接收请求并返回HTTP 303响应:
@POST
@Path("/authorize")
@Produces("application/x-www-form-urlencoded")
public Response getOAuthGrant(@HeaderParam(OAuth2.AUTHORIZATION) @DefaultValue("") String authorization,
@HeaderParam(OAuth2.CLIENT_ID) @DefaultValue("") String clientId,
@HeaderParam(OAuth2.CLIENT_SECRET) @DefaultValue("") String clientSecret,
@HeaderParam(OAuth2.GRANT_TYPE) @DefaultValue("") String grantType) throws InternalServerException, UnauthorizedException {
OAuth2.validateGrantRequest(clientId, clientSecret, authorization, grantType);
ApiTokenV2 apiTokenV2 = new ApiTokenV2();
try {
apiTokenV2 = TokenManager.getApiToken(clientId);
if (apiTokenV2 != null) {
apiTokenV2.generateAccessGrant(clientId);
} else {
logger.error("Error in TokenEndpoint. Retrieved token is null.");
throw new InternalServerException("A server error occurred while trying to authorize the requester. Could not find 'generateAccessGrant' method");
}
} catch (NamingException …Run Code Online (Sandbox Code Playgroud) 为@Path("<what_regex>")捕获所有可能的路径参数深度而设置的正则表达式是什么(除了某些特定路径要由其他方法处理)?
喜欢:
/{path1}/{path1}/{path1}/{path1}/{path1}/ 等等
虽然仍然映射这些:
/create
/read
/update
/delete
Run Code Online (Sandbox Code Playgroud)
其他Jax-rs资源方法.
@Singleton
@Path("/")
public class MyRest {
@GET
@Path({pathParam}) /* This works */
public Response getSomething(...){}
@POST
@Path("create") /* Along with this */
public Response createSomething(...){}
// and so on
}
Run Code Online (Sandbox Code Playgroud) 我得到了所有服务的wadl.现在我需要为我的网络应用程序生成服务列表.如何在我的网络应用程序中配置它.我已经看过http://cxf.apache.org/docs/jaxrs-services-description.html#JAXRSServicesDescription-ServicelistingsandWADLqueries,但它有点混乱.任何人都可以简化它.
我需要将一个文件附加到我的服务端点.我通过POSTMAN(chrome浏览器插件测试休息服务)测试了功能,它运行正常.
但是我需要用JUNIT测试它.对于这种情况,我使用的是RESTeasy客户端.
我正在尝试使用此代码:
StringBuilder sb = new StringBuilder();
BufferedReader br = new BufferedReader(new FileReader("C:/Temp/tempfile.txt"));
try {
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
}
finally {
br.close();
}
byte[] file = sb.toString().getBytes();
Client client = ClientBuilder.newClient();
Invocation.Builder builder = client.target(webTarget.getUri()
+ "/attachment" ).request(MediaType.MULTIPART_FORM_DATA_TYPE);
Response response = builder.post(Entity.entity(file, MediaType.MULTIPART_FORM_DATA), Response.class);
Run Code Online (Sandbox Code Playgroud)
但我收到一个错误:
org.apache.commons.fileupload.FileUploadException:请求被拒绝,因为没有找到多部分边界
这有什么解决方案吗?
或者任何人都可以提供示例RESTeasy rest客户端代码来附加文件?
我正在编写一个JAX-RS库(不是应用程序).
我有:
abstract class A {
@PostConstruct
private void constructed_a() {} // not invoked
@Inject
private Some some;
}
public abstract class B extends A {
@PostConstruct
private void constructed_b() {} // not invoked
}
Run Code Online (Sandbox Code Playgroud)
和测试类:
@Path("c")
public class C extends B {
@PostConstrct
private void constructed_c() {} // invoked
}
Run Code Online (Sandbox Code Playgroud)
我正在测试jersey测试框架v2.17
我发现只constructed_c()调用它并且不调用祖先定义的那些方法.请注意,在类中some声明的field()已正确注入.@InjectA
这是正常的吗?我该怎么办?
结论
我使用embedded-glassfish进行了测试,发现正如Antonin Stefanutti指出的那样,这些回调方法按预期顺序调用.
constructed_a()
constructed_b()
constructed_c()
Run Code Online (Sandbox Code Playgroud) 这是我的Web服务方法:
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@POST
@Path("login")
public Response login(@NotNull @Valid Credentials credentials) {
// do login
}
Run Code Online (Sandbox Code Playgroud)
这是客户端代码的片段:
WebTarget loginTarget = baseTarget
.path("base")
.path("login");
Credentials credentials = new Credentials(username, password);
Response resp = loginOperation
.request()
.post(
Entity.entity(credentials, MediaType.APPLICATION_JSON_TYPE)
);
Run Code Online (Sandbox Code Playgroud)
当我发帖时,它没有到达登录方法.服务器返回400错误,空体.
当我@NotNull @Valid从凭证参数中删除注释时,它可以工作.
我注意到Entity#entity方法有一个重载版本,它接受Annotation[]第三个参数.然后我遇到了Jersey文档的这一部分.所以我按照教程中的建议继续创建了一个注释工厂:
public static class ValidFactory extends AnnotationLiteral<Valid> implements Valid {
public static ValidFactory get() {
return new ValidFactory();
}
}
Run Code Online (Sandbox Code Playgroud)
然后将客户端代码更改为:
.post(
Entity.entity(credentials, MediaType.APPLICATION_JSON_TYPE,
new Annotation[] {
AuthenticationResource.NotNullFactory.get(),
AuthenticationResource.ValidFactory.get()
}
)
)
Run Code Online (Sandbox Code Playgroud)
不幸的是导致了同样的错误.谷歌搜索没有产生任何结果,我没有太多时间挖掘泽西岛的源代码.那么,也许知道解决方案的人会分享它,好吗? …
我是Web服务的新手。因此,我从一个如下的小程序开始。
它可以在GlassFish服务器中正常运行,但不能在Tomcat中运行(我想在Tomcat上运行)。这是一个简单的程序,仅给出如何运行Web服务应用程序的想法。
FirstRestService.java:
package com.sandy.demo;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("/resources")
public class FirstRestService extends Application {
}
Run Code Online (Sandbox Code Playgroud)
员工.java:
package com.sandy.demo;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
@Path("/employees")
public class Employees {
@GET
public String getEmployeesNames() {
return "Hello World";
}
}
Run Code Online (Sandbox Code Playgroud)
我已经包含了jsr311-api-1.1.1.jar(JAX-RS API JAR文件)。
我获取了该应用程序的有效WAR文件,并将其部署在GlassFish Server中。然后,我使用URL运行服务器:http://localhost:8080/MyFirstRestApplication/resources/employees。
但是我无法在Tomcat中执行相同的操作。
我已经实现了一个ContainerRequestFilter执行基于JWT的身份验证:
@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
AuthenticationResult authResult = ...
if (authResult.isSuccessful()) {
// Client successfully authenticated.
// Now update the security context to be the augmented security context that contains information read from the JWT.
requestContext.setSecurityContext(new JwtSecurityContect(...));
} else {
// Client provided no or an invalid authentication token.
// Deny request by sending a 401 response.
requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());
}
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我更新了SecurityContext请求,JwtSecurityContext如果身份验证成功,则将其设置为我自己的自定义实现()的实例.此实现添加了额外的身份验证和授权数据,我希望稍后在后续过滤器和我的资源方法中访问这些数据. …
jax-rs ×10
java ×6
jersey ×3
cxf ×2
rest ×2
web-services ×2
api ×1
cdi ×1
http-headers ×1
jersey-2.0 ×1
junit ×1
keep-alive ×1
redirect ×1
regex ×1
resteasy ×1
service ×1
tcp ×1
unit-testing ×1