Sam*_*ams 6 java rest json web-services resteasy
我在请求/响应主体中有一个RESTFul API消耗/返回JSON.当客户端发送无效数据(有效的JSON但字段的值无效)时,我希望能够返回JSON结构(以及相关的400+代码).
然后,该结构将允许前端在每个字段的基础上解析错误,并在输入字段旁边呈现错误.
例如理想输出:
{
"errors":{
"name":["invalid chars","too long","etc"]
"otherfield":["etc"]
}
}
Run Code Online (Sandbox Code Playgroud)
我正在使用Resteasy作为API,并且使用违规异常很容易让它呈现JSON错误:
@Provider
@Component
public class ValidationExceptionHandler implements ExceptionMapper<ResteasyViolationException> {
public Response toResponse(ResteasyViolationException exception) {
Multimap<String,String> errors = ArrayListMultimap.create();
Consumer<ResteasyConstraintViolation> consumer = (violation) -> {
errors.put(violation.getPath(), violation.getMessage());
};
exception.getParameterViolations().forEach(consumer);
Map<String, Map<String, Collection<String>>> top = new HashMap<>();
top.put("errors", errors.asMap());
return Response.status(Status.BAD_REQUEST).entity(top)
.build();
}
}
Run Code Online (Sandbox Code Playgroud)
但是,错误路径(violation.getPath())是以属性为中心而不是以XmlElement-name为中心的.
例如以上输出:
{
"errors":{"createCampaign.arg1.name":["invalid chars","etc"]}
}
Run Code Online (Sandbox Code Playgroud)
我已经尝试从最后一个点回来剥离索引以获得"名称"但是该黑客还存在其他问题.
例如,如果我的"名称"属性不是"名称",则它不起作用:
@XmlElement(name="name")
@NotNull
private String somethingelse;
Run Code Online (Sandbox Code Playgroud)
"somethingelse"将返回给客户,但他们的客户不知道那是什么:
{
"errors":{"somethingelse":["cannot be null"]}
}
Run Code Online (Sandbox Code Playgroud)
客户端需要"名称",因为这是在发送字段时调用的字段.
我的资源:
package com.foo.api;
import org.springframework.stereotype.Service;
import javax.validation.Valid;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import com.foo.dto.CarDTO;
@Service
@Path("/car")
public class CarResource {
@POST
@Produces({MediaType.APPLICATION_JSON})
@Consumes(MediaType.APPLICATION_JSON)
public CarDTO create(
@Valid CarDTO car
) {
//do some persistence
return car;
}
}
Run Code Online (Sandbox Code Playgroud)
示例dto:
package com.foo.dto;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Min;
import javax.validation.constraints.Max;
import javax.xml.bind.annotation.XmlElement;
public class CarDTO {
@Min(1)
@Max(10)
@NotNull
@XmlElement(name="gears")
private int cogs;
}
Run Code Online (Sandbox Code Playgroud)
这篇文章很好地描述了您需要做什么。
基本上你应该实现一个ExceptionMapper。
@Provider
public class ValidationExceptionMapper implements ExceptionMapper<ValidationException> {
@Override
public Response toResponse(ValidationException exception) {
Response myResponse;
// build your Response based on the data provided by the exception
return myResponse;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3607 次 |
| 最近记录: |