私はRESTとHTTPを介して通信するサーバークライアントアプリケーションを構築しています。 問題は、私はタスクを作成しようとしています。私は、クライアントから送信されたJSONは次のようになります。ドキュメントを読み取れませんでした。com.fasterxml.jackson.databind.JsonMappingException
{
"title": "Message Not Readable",
"status": 400,
"detail": "Could not read document: N/A (through reference chain: de.name.supervisor.rest.domain.Task[\"author\"]->de.name.supervisor.rest.domain.User[\"assignedTasks\"]->java.util.HashSet[0]->de.name.supervisor.rest.domain.Task[\"author\"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: N/A (through reference chain: de.name.supervisor.rest.domain.Task[\"author\"]->de.name.supervisor.rest.domain.User[\"assignedTasks\"]->java.util.HashSet[0]->de.name.supervisor.rest.domain.Task[\"author\"])","timeStamp": 1466859943472,
"developerMessage": "org.springframework.http.converter.HttpMessageNotReadableException",
"errors": {}
}
私は見当がつかない、正確に何を動作しません:
{
"taskType": "USER_STORY",
"headLine": "ew",
"taskText": "wewe",
"author": {
"id": 1,
"confirmed": false,
"email": "[email protected]",
"userName": "Daniel",
"password": "test",
"creationTime": 1466843454239,
"assignedTasks": [
{
"id": 1,
"possibleTaskTypes": [
"USER_STORY",
"TECHNICAL_STORY",
"BUG"
],
"possibleTaskContainer": [
"PRODUCT_BACKLOG",
"SELECTED_BACKLOG",
"SPRINT"
],
"taskType": "USER_STORY",
"headLine": "123",
"taskText": "fsfd",
"possibleworkFlowStati": [
"START",
"READY_FOR_ESTIMATION",
"READY_FOR_SPRINT",
"OPEN",
"IN_PROGRESS",
"DONE"
],
"author": {
"id": 1,
"confirmed": false
},
"assignee": {
"id": 1,
"confirmed": false
},
"comments": [],
"creationTime": 1466843507898
}
],
"createdTasks": [
{
"id": 1,
"possibleTaskTypes": [
"USER_STORY",
"TECHNICAL_STORY",
"BUG"
],
"possibleTaskContainer": [
"PRODUCT_BACKLOG",
"SELECTED_BACKLOG",
"SPRINT"
],
"taskType": "USER_STORY",
"headLine": "123",
"taskText": "fsfd",
"possibleworkFlowStati": [
"START",
"READY_FOR_ESTIMATION",
"READY_FOR_SPRINT",
"OPEN",
"IN_PROGRESS",
"DONE"
],
"author": {
"id": 1,
"confirmed": false
},
"assignee": {
"id": 1,
"confirmed": false
},
"comments": [],
"creationTime": 1466843507898
}
]
},
"assignee": {
"id": 1,
"confirmed": false,
"email": "[email protected]",
"userName": "Daniel",
"password": "test",
"creationTime": 1466843454239,
"assignedTasks": [
{
"id": 1,
"possibleTaskTypes": [
"USER_STORY",
"TECHNICAL_STORY",
"BUG"
],
"possibleTaskContainer": [
"PRODUCT_BACKLOG",
"SELECTED_BACKLOG",
"SPRINT"
],
"taskType": "USER_STORY",
"headLine": "123",
"taskText": "fsfd",
"possibleworkFlowStati": [
"START",
"READY_FOR_ESTIMATION",
"READY_FOR_SPRINT",
"OPEN",
"IN_PROGRESS",
"DONE"
],
"author": {
"id": 1,
"confirmed": false
},
"assignee": {
"id": 1,
"confirmed": false
},
"comments": [],
"creationTime": 1466843507898
}
],
"createdTasks": [
{
"id": 1
}
]
}
}
私はサーバーから取得エラー-のメッセージはこれです。私は単一のユーザーを投稿するとき、私は問題はありません。
威張っ-UIによって生成された例JSONは次のとおりです。
{
"comments": [
"string"
],
"creationTime": 0,
"possibleTaskContainer": [
"string"
],
"author": {
"password": "string",
"creationTime": 0,
"createdTasks": [
{}
],
"id": 0,
"userName": "string",
"confirmed": true,
"email": "string",
"assignedTasks": [
{}
]
},
"sprint": {
"inProgress": [
{}
],
"creationTime": 0,
"endDate": {
"dayOfWeek": "MONDAY",
"month": "JANUARY",
"year": 0,
"dayOfMonth": 0,
"era": {
"value": 0
},
"dayOfYear": 0,
"monthValue": 0,
"chronology": {
"id": "string",
"calendarType": "string"
},
"leapYear": true
},
"allTasks": [
{}
],
"sprintName": "string",
"id": 0,
"toDos": [
{}
],
"done": [
{}
],
"startDate": {
"dayOfWeek": "MONDAY",
"month": "JANUARY",
"year": 0,
"dayOfMonth": 0,
"era": {
"value": 0
},
"dayOfYear": 0,
"monthValue": 0,
"chronology": {
"id": "string",
"calendarType": "string"
},
"leapYear": true
}
},
"taskContainer": "string",
"headLine": "string",
"taskType": "string",
"id": 0,
"possibleTaskTypes": [
"string"
],
"assignee": {
"password": "string",
"creationTime": 0,
"createdTasks": [
{}
],
"id": 0,
"userName": "string",
"confirmed": true,
"email": "string",
"assignedTasks": [
{}
]
},
"possibleworkFlowStati": [
"string"
],
"taskText": "string",
"status": "string"
}
はおそらく唯一のIDがあり、フィールドを確認し、クライアントから送信されたassingeeとJSON内のユーザーオブジェクトの問題ですか?これが理由なら、私のコントローラーは機能しません。 POSTリクエストのためのしたがって、ここでコントローラ方法:
public HttpResponse postTask(Task task)throws ClientProtocolException, IOException{
HttpClient client = HttpClients.createDefault();
HttpPost post = new HttpPost(TASK_URI_V1);
Gson gson = new Gson();
String json = gson.toJson(task);
logger.info("Request-Body created: "+json);
post.setEntity(new StringEntity(json));
post.setHeader("Content-type", "application/json");
HttpResponse response = client.execute(post);
logger.info("Response from Web-Service after executing postTask request: "+response.getStatusLine().toString());
logger.info("Response Head from Web-Service after executing postTask request: "+response.toString());
logger.info("Response Body from Web-Service after executing postTask request: "+RestControllerUtils.getResponseBodyAsString(response));
return response;
}
そして、ここでは、クライアントのユーザー・モデル:
@JsonIgnoreProperties(ignoreUnknown = true)
public class User {
public User(){};
public User(int id){
setId(new Long(id));
}
private Long id;
private boolean confirmed;
private String email;
private String userName;
private String password;
private Long creationTime;
private Set<Task> assignedTasks;
private Set<Task> createdTasks;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public boolean isConfirmed() {
return confirmed;
}
public void setConfirmed(boolean confirmed) {
this.confirmed = confirmed;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Long getCreationTime() {
return creationTime;
}
public void setCreationTime(Long creationTime) {
this.creationTime = creationTime;
}
public Set<Task> getAssignedTasks() {
return assignedTasks;
}
public void setAssignedTasks(Set<Task> assignedTasks) {
this.assignedTasks = assignedTasks;
}
public void addAssignedTasks(Task task){
addAssignedTasks(task,true);
}
void addAssignedTasks(Task task, boolean set){
if(task != null){
getAssignedTasks().add(task);
if(set){
task.setAssignee(this);
}
}
}
public void removeAssidnedTask(Task task) {
getAssignedTasks().remove(task);
task.setAssignee(null);;
}
public Set<Task> getCreatedTasks() {
return createdTasks;
}
public void setCreatedTasks(Set<Task> createdTasks) {
this.createdTasks = createdTasks;
}
public void addCreatedTask(Task task){
addCreatedTask(task,true);
}
void addCreatedTask(Task task, boolean set){
if(task != null){
getCreatedTasks().add(task);
if(set){
task.setAuthor(this);
}
}
}
public void removeCreatedTask(Task task) {
getCreatedTasks().remove(task);
task.setAuthor(null);
}
}
およびサーバーのユーザーモデル:
@Entity
@Table(name="User")
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class,property="@id", scope = User.class)
public class User {
@Id
@GeneratedValue
@Column(name="USER_ID")
private Long id;
@Column(name="CONFIRMATION")
private boolean confirmed;
@Column(name = "EMAIL",nullable = false)
private String email;
@Column(name = "USERNAME",nullable = false)
@NotNull
private String userName;
@Column(name="PASSWORD",nullable = false)
@NotNull
private String password;
@Column(name="TIMESTAMP")
private Long creationTime;
@OneToMany(cascade={CascadeType.DETACH,CascadeType.MERGE,CascadeType.REFRESH }, mappedBy="author",fetch=FetchType.EAGER)
private Set<Task>assignedTasks;
@OneToMany(cascade={CascadeType.DETACH,CascadeType.MERGE,CascadeType.REFRESH }, mappedBy="assignee",fetch=FetchType.EAGER)
private Set<Task>createdTasks;
public User() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Long getCreationTime() {
return creationTime;
}
public void setCreationTime(Long creationTime) {
this.creationTime = creationTime;
}
public boolean isConfirmed() {
return confirmed;
}
public void setConfirmed(boolean confirmed) {
this.confirmed = confirmed;
}
public Set<Task> getAssignedTasks() {
return assignedTasks;
}
public void setAssignedTasks(Set<Task> assignedTasks) {
this.assignedTasks = assignedTasks;
}
public void addAssignedTasks(Task task){
addAssignedTasks(task,true);
}
void addAssignedTasks(Task task, boolean set){
if(task != null){
getAssignedTasks().add(task);
if(set){
task.setAssignee(this);
}
}
}
public void removeAssidnedTask(Task task) {
getAssignedTasks().remove(task);
task.setAssignee(null);;
}
public Set<Task> getCreatedTasks() {
return createdTasks;
}
public void setCreatedTasks(Set<Task> createdTasks) {
this.createdTasks = createdTasks;
}
public void addCreatedTask(Task task){
addCreatedTask(task,true);
}
void addCreatedTask(Task task, boolean set){
if(task != null){
getCreatedTasks().add(task);
if(set){
task.setAuthor(this);
}
}
}
public void removeCreatedTask(Task task) {
getCreatedTasks().remove(task);
task.setAuthor(null);
}
@Override
public String toString() {
return "User [id=" + id + ", confirmed=" + confirmed + ", email=" + email + ", userName=" + userName
+ ", password=" + password + "]";
}
}
サーバーのタスククラス:
@Entity
@Table(name="Task")
//@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class,property="@id", scope = Task.class)
public class Task {
@Id
@GeneratedValue
@Column(name="TASK_ID")
private Long id;
@Transient
private List<String> possibleTaskTypes = TaskType.getTaskTypesAsString();
@Transient
private List<String>possibleTaskContainer = TaskContainer.getTaskContainerAsString();
@Column(name="TASK_Container")
private String taskContainer;
@Column(name="TASK_TYPE")
private String taskType;
@Column(name="HEAD_LINE")
private String headLine;
@Column(name="TASK_TEXT")
private String taskText;
@Transient
private List<String> possibleworkFlowStati = WorkFlowStatus.getWorkFlowsStatiAsString();
@Column(name="WORKFLOW_STATUS")
private String status;
@ManyToOne(cascade = {CascadeType.DETACH,CascadeType.MERGE,CascadeType.REFRESH })
private User author;
@ManyToOne(cascade = {CascadeType.DETACH,CascadeType.MERGE,CascadeType.REFRESH }) //TODO Check wether remove too.
private User assignee;
@Column(name="COMMENTS")
@ElementCollection(targetClass=String.class)
private List<String>comments;
@ManyToOne(cascade=CascadeType.ALL)
private Sprint sprint;
@Column(name="TIMESTAMP")
private Long creationTime;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getHeadLine() {
return headLine;
}
public void setHeadLine(String headLine) {
this.headLine = headLine;
}
public String getTaskText() {
return taskText;
}
public void setTaskText(String taskText) {
this.taskText = taskText;
}
public User getAuthor() {
return author;
}
public void setAuthor(User author) {
setAuthor(author, true);
}
void setAuthor(User author, boolean add){
this.author = author;
if(author !=null&&add){
author.addCreatedTask(this, false);
}
}
public User getAssignee() {
return assignee;
}
public void setAssignee(User assignee) {
setAssignee(assignee,true);
}
void setAssignee(User assignee, boolean add){
this.assignee = assignee;
if(assignee != null && add){
assignee.addAssignedTasks(this,false);
}
}
public List<String> getComments() {
return comments;
}
public void setComments(List<String> comments) {
this.comments = comments;
}
public Sprint getSprint() {
return sprint;
}
public void setSprint(Sprint sprint) {
this.sprint = sprint;
}
public Long getCreationTime() {
return creationTime;
}
public void setCreationTime(Long creationTime) {
this.creationTime = creationTime;
}
public String getTaskType() {
return taskType;
}
public void setTaskType(String taskType) {
this.taskType = taskType;
}
public List<String> getPossibleTaskTypes() {
return possibleTaskTypes;
}
public void setPossibleTaskTypes(List<String> possibleTaskTypes) {
this.possibleTaskTypes = possibleTaskTypes;
}
public List<String> getPossibleworkFlowStati() {
return possibleworkFlowStati;
}
public void setPossibleworkFlowStati(List<String> possibleworkFlowStati) {
this.possibleworkFlowStati = possibleworkFlowStati;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public List<String> getPossibleTaskContainer() {
return possibleTaskContainer;
}
public void setPossibleTaskContainer(List<String> possibleTaskContainer) {
this.possibleTaskContainer = possibleTaskContainer;
}
public String getTaskContainer() {
return taskContainer;
}
public void setTaskContainer(String taskContainer) {
this.taskContainer = taskContainer;
}
@Override
public String toString() {
return "Task [id=" + id + ", possibleTaskTypes=" + possibleTaskTypes + ", possibleTaskContainer="
+ possibleTaskContainer + ", taskContainer=" + taskContainer + ", taskType=" + taskType + ", headLine="
+ headLine + ", taskText=" + taskText + ", possibleworkFlowStati=" + possibleworkFlowStati + ", status="
+ status + ", author=" + author + ", assignee=" + assignee + ", comments=" + comments + ", sprint="
+ sprint + ", creationTime=" + creationTime + "]";
}
}
はい、もちろんです。私はちょうどポストユーザーとタスクを質問ポストに追加しました。 – n00bst3r
はい、@JsonIgnoreで解決し、作成者と譲受人のためにREST-Templateを構築しました。だからあなたは自分の要求でそれらを設定しなければなりません。 – n00bst3r