默认情况下发生的情况是抛出异常,但没有处理程序正在侦听它。结果,此类请求到达 JAR-RS 方法,但提交的字段 thad 的值“不正确”,设置为 NULL。
我在 JAVADOC 中读到,必须设置一个处理程序,以便在发生这种情况时我可以做一些事情。但我找不到有关如何设置此类处理程序的信息。
我的端点是这样的:
@Path("/path")
public class MyResource {
@POST
@Path("something")
public Response postSomething(JaxbAnnotatedRequest request) {
//processing....
}
}
Run Code Online (Sandbox Code Playgroud) 我将通过举个例子来解释我的疑问。
假设我正在设计一个资源端点POST,student并且作为 POST 端点的一部分,我希望teacher传递一个 uuid(除了其他细节之外),这是一个必填字段。这样我就可以将 与 关联student起来teacher。现在,如果teacher给定的资源uuid不存在于我的数据库中,那么我应该抛出什么:
400 (Bad request)
404 (Not found).
Run Code Online (Sandbox Code Playgroud)
我认为400这是正确的事情。
如果我有一个像下面这样的请求,那么我会抛出 404 类似
GET /xyy/teachers/{uuid of a teacher}。
如果我错了请纠正我。谢谢。
我公司有代理
proxy=myProxy
port=myProxyPort
username=me
password=myPassword
Run Code Online (Sandbox Code Playgroud)
我尝试使用简单的 java.net 函数访问外部世界,它成功了!
System.setProperty("http.proxyHost", myProxy);
System.setProperty("http.proxyPort", myProxyPort);
Authenticator.setDefault(new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new
PasswordAuthentication(me,myPasssword.toCharArray());
}});
URL u = new URL("http://www.google.com");
HttpURLConnection con = (HttpURLConnection) u.openConnection();
DataInputStream di = new DataInputStream(con.getInputStream());
byte[] b = new byte[1024*512];
while(-1 != di.read(b,0,1024*512)) {
System.out.print(new String(b));
Run Code Online (Sandbox Code Playgroud)
不是我尝试使用 Jax-RS Resteasy 实现来做到这一点,如下所示:
Client client = new ResteasyClientBuilder().defaultProxy(myProxy, myProxyPort).build();
System.out.println(client.target("https://www.google.com").request().get().readEntity(String.class));
Run Code Online (Sandbox Code Playgroud)
我收到以下错误
Cache Access Denied
ERR_CACHE_ACCESS_DENIED
(squid/3.1.6)
Sorry, you are not currently allowed to request https://www.google.com/* from this cache until you …Run Code Online (Sandbox Code Playgroud) 我的问题很简单,但我没有设法找到响应...是否可以使用 JAX-RS (使用 CXF 实现)从 @BeanParam 带注释的参数访问 HTTP 请求正文?
我尝试了这个,但它不起作用:
@Path("/courses")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class CarsResource {
@POST
@Path("/{id}")
public Course update(@BeanParam CarUpdateRequest request){
...
}
}
public class CarUpdateRequest {
@PathParam("id")
private String id;
private CarUpdateData data; // inject here the body using JsonProvider
}
Run Code Online (Sandbox Code Playgroud)
这似乎是一个 helloword 示例,但我找不到任何有效的示例。奇怪的是 JAX-RS 没有 @BodyParam...
我有一些网络服务(JAX-RS、WildFly 9、Resteasy)
@RequestScoped
public class SomeService{
// operations
}
Run Code Online (Sandbox Code Playgroud)
现在我想提取上下文信息,例如用户代理,这可以使用
@Context
private HttpHeaders httpHeaders;
Run Code Online (Sandbox Code Playgroud)
似乎只能在 JAX-RS 相关类中注入此上下文,但不能在 Web 服务调用的 CDI bean 中注入。可以将其放入 Web 服务中,但这会使服务与与服务的核心响应无关的内容变得混乱。
经过一番搜索,我最终使用了javax.ws.rs.ext.Provider注释。看起来生成的ContextInformation对象可以在其他 CDI-bean 中使用,而不仅仅是在 JAX-RS bean 中。
@Provider
public class ContextInformationProducer {
@Produces
@RequestScoped
public ContextInformation create() {
ContextInformation contextInformation = new ContextInformation();
contextInformation.setBrowserUserAgent(httpHeaders.getHeaderString("User-Agent"));
}
Run Code Online (Sandbox Code Playgroud)
问题是这是否是好的做法?或者这只是巧合?如果这不是好的做法,我怎样才能以更好的方式做到这一点?查看JAX-RS 中的 Provider 是什么意思?,我不确定我是否在“扩展和定制 JAX-RS 运行时”。应用程序开发人员应该使用它吗?
我实现了一个项目,它使用一个非常简单的 JAX-RS 后端来向基于 AngularJS 的 UI 提供数据。这些是独立的模块并部署在 Wildfly 9 上。为了为 REST 端点提供一个很好的文档,我发现 swagger.io 似乎很合适。但是,我在按照文档和示例设置 swagger 时遇到了困难,因为我的项目结构略有不同。
当前状态
我可以访问返回的http://localhost:8080/service/swagger.json
{
"swagger": "2.0",
"info": {
"version": "1.0.0",
"title": ""
},
"host": "localhost:8080",
"basePath": "/service",
"schemes": ["http"]
}
Run Code Online (Sandbox Code Playgroud)
但是 swagger-ui (swagger.json 已正确链接)不显示我的任何 REST 端点。
我认为这个问题可能与为 Wildfly 设置的 basePath 或 contextRoot 有关,但这只是一个模糊的猜测。除此之外,我什至不确定要使用哪种 swagger JAX-RS 实现。我想既然我使用 Wildfly (JBoss),它应该是 Resteasy,但 swagger Jersey 设置文档似乎更合适。
我的 REST 端点看起来像http://localhost:8080/service/users/register
相关资源
pom.xml
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-core</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-jaxrs</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.5.4</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
网络.xml …
我正在使用最新版本的 Jersey 作为 API 服务器。我定义了下一个资源:
@javax.ws.rs.Path("/myPath")
public class MyResource {
@GET
@Consumes({MediaType.WILDCARD, MediaType.TEXT_PLAIN, MediaType.TEXT_HTML})
@Produces(MediaType.TEXT_PLAIN)
public Response method1(@Context Request request) {
}
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public MyObject method2() {}
}
Run Code Online (Sandbox Code Playgroud)
现在假设我使用下一个标头调用此资源:
<header>
<name>Accept</name>
<value>text/html, application/xhtml+xml, */*</value>
</header>
Run Code Online (Sandbox Code Playgroud)
在没有方法注释匹配的情况下,Jersey 如何知道要匹配哪一个Producer?我这样问是因为有一次服务器响应了方法2,重新启动后,它响应了方法1。
我正在尝试测试抛出我自己编写的 RuleCheckerException 的方法。
方法:
@Override
public RuleCheckerService checkStartEndDateRule(String fieldStartDate, String fieldEndDate, Object o) throws RuleCheckerException {
Date startDate = new Date();
Date endDate = new Date();
try {
startDate = (Date) ObjectOperationUtil.getFieldValue(fieldStartDate, o);
endDate = (Date) ObjectOperationUtil.getFieldValue(fieldEndDate, o);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();}
if (startDate.getTime() >= endDate.getTime()) {
CDMResponse response = new CDMResponse(ResponseMessageType.START_END_DATE.getMessageTypeId(), ResponseMessageType.START_END_DATE.getRuleDefinition(), null);
String errorMessage = ResponseMessageType.START_END_DATE.getRuleDefinition() + ": " + fieldStartDate + ": " + startDate + " cannot be later than " + …Run Code Online (Sandbox Code Playgroud) 在 Spring 中将分页和 HATEOAS 添加到 REST 资源非常简单,并且开箱即用:
@RequestMapping(value = "/pages", method = RequestMethod.GET)
PagedResources<NoteResource> allPaged(@PageableDefault Pageable p, PagedResourcesAssembler<Note> pagedAssembler) {
Page<Note> pageResult = noteRepository.findAll(p);
return pagedAssembler.toResource(pageResult, noteResourceAssembler);
}
Run Code Online (Sandbox Code Playgroud)
就是这样。我可以调用localhost:8080/notes/pages?page=0&size=2并获取以下 JSON:
{
"_embedded": {
"noteList": [
{
"id": 1,
"title": "firstNote",
"body": "lala",
"_links": {
"self": {
"href": "http://localhost:8080/notes/1"
},
"note-tags": {
"href": "http://localhost:8080/notes/1/tags"
}
}
},
{
"id": 2,
"title": "secondNote",
"body": "blabla",
"_links": {
"self": {
"href": "http://localhost:8080/notes/2"
},
"note-tags": {
"href": "http://localhost:8080/notes/2/tags"
}
}
}
] …Run Code Online (Sandbox Code Playgroud) 我有一个接受多部分表单数据类型的方法。此方法的参数之一是file表单数据参数,如下所示
@FormDataParam("file") InputStream inputStream,
@FormDataParam("file") FormDataContentDisposition contentDispositionHeader
Run Code Online (Sandbox Code Playgroud)
我希望有时能够在不提供表单数据参数的情况下到达此端点file,但现在当我忽略它时,该方法会立即返回 400 bad request。有什么方法可以设置它以便我可以将其省略吗?或者有什么方法可以为此设置默认值(即为空?)。任何帮助,将不胜感激。我的方法声明如下:
@POST
@Path("/publish")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response publish(@Auth Key key,
@QueryParam("email") String email,
@HeaderParam("password") String password,
@QueryParam("type") PublishType type,
@QueryParam("message") String message,
@FormDataParam("file") InputStream inputStream,
@FormDataParam("file") FormDataContentDisposition
contentDispositionHeader,
@FormDataParam("title") @DefaultValue("") String videoTitle) {
// code here
}
Run Code Online (Sandbox Code Playgroud)
最后,我想创建一个端点,用户可以在其中将文本发布到数据库,并且可以选择包含图像或某种类型的媒体。让我知道是否有其他方法可以实现这一目标。
谢谢你!
jax-rs ×10
java ×8
rest ×4
resteasy ×2
wildfly ×2
annotations ×1
cdi ×1
cxf ×1
hateoas ×1
http ×1
http-status ×1
jakarta-ee ×1
jaxb ×1
jboss ×1
jersey ×1
jersey-2.0 ×1
junit ×1
pagination ×1
squid ×1
swagger ×1