gpt4 book ai didi

json - 错误error.GrailsExceptionResolver-JSONException的endArray放错了位置

转载 作者:行者123 更新时间:2023-12-02 15:22:40 25 4
gpt4 key购买 nike

我正在使用Grails和AngularJS创建RESTful twitter / facebook克隆,因此它是标准用户可以发布,用户可以喜欢发布,并且用户可以关注其他用户。

我正在使用JSON对象编码器,以便 Realm 类的hasManybelongsTo的属性将在JSON中呈现。

我已经为类似功能在UserPost域之间插入了必要的关系,当我在Bootstrap.groovy中实现它们时,如果我向GET发送了api/posts/请求,则一切正常,但问题是当我使用按钮实现它们时。
此按钮将PUT请求发送到api/posts/:id,然后转到我的update()PostController方法。像被插入到数据库中,但是如果我再次向GET发送另一个api/posts请求,则会出现此错误

....Error
|
2015-09-26 00:54:35,986 [http-bio-8090-exec-9] ERROR
errors.GrailsExceptionResolver
- JSONException occurred when processing request: [GET] /restsocnet/api/posts
Misplaced endArray.. Stacktrace follows:
Message: Misplaced endArray.
Line | Method
->> 202 | value in grails.converters.JSON
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 162 | convertAnother in ''
| 202 | value . . . . . . in ''
| 162 | convertAnother in ''
| 202 | value . . . . . . in ''
| 162 | convertAnother in ''
| 202 | value . . . . . . in ''
| 162 | convertAnother in ''
| 202 | value . . . . . . in ''
| 162 | convertAnother in ''
| 202 | value . . . . . . in ''
| 162 | convertAnother in ''
| 202 | value . . . . . . in ''
| 162 | convertAnother in ''
| 202 | value . . . . . . in ''
| 162 | convertAnother in ''
| 202 | value . . . . . . in ''
| 134 | render in ''
| 150 | render . . . . . . in ''
| 19 | index in com.patrickjuen.restsocnet.PostController
| 198 | doFilter . . . . . in grails.plugin.cache.web.filter.PageFragmentCachingFilter
| 63 | doFilter in grails.plugin.cache.web.filter.AbstractFilter
| 118 | processFilterChain in grails.plugin.springsecurity.rest.RestTokenValidationFilter
| 84 | doFilter in ''
| 53 | doFilter . . . . . in grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter
| 143 | doFilter in grails.plugin.springsecurity.rest.RestAuthenticationFilter
| 62 | doFilter . . . . . in grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter
| 82 | doFilter in com.brandseye.cors.CorsFilter
| 1142 | runWorker . . . . in java.util.concurrent.ThreadPoolExecutor
| 617 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run . . . . . . . in java.lang.Thread

这些是我的密码

User.groovy
package com.patrickjuen.restsocnet

class User implements Serializable {

private static final long serialVersionUID = 1

transient springSecurityService

String username
String password
boolean enabled = true
boolean accountExpired
boolean accountLocked
boolean passwordExpired
static hasMany = [posts: Post, likedPost: Post]
static mappedBy = [posts: "user"]


User(String username, String password) {
this()
this.username = username
this.password = password
}

@Override
int hashCode() {
username?.hashCode() ?: 0
}

@Override
boolean equals(other) {
is(other) || (other instanceof User && other.username == username)
}

@Override
String toString() {
username
}

Set<Role> getAuthorities() {
UserRole.findAllByUser(this)*.role
}

def beforeInsert() {
encodePassword()
}

def beforeUpdate() {
if (isDirty('password')) {
encodePassword()
}
}

protected void encodePassword() {
password = springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password) : password
}

static transients = ['springSecurityService']

static constraints = {
username blank: false, unique: true
password blank: false
likedPost nullable: true
}

static mapping = {
password column: '`password`'
posts lazy: false, sort: 'dateCreated', order: 'desc'
likedPost lazy: false

}
}



package com.patrickjuen.restsocnet

import grails.converters.JSON

//import grails.plugin.springsecurity.annotation.Secured
import org.springframework.security.access.annotation.Secured


@Secured(['isFullyAuthenticated()'])
class PostController {

static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]


def springSecurityService

def index() {
render Post.list(sort: "dateCreated", order: "desc") as JSON
}

def save(){
def newPost = new Post(request.JSON)
if(!newPost.hasErrors()){
def currentUser = User.get(springSecurityService.principal.id)
println currentUser
newPost.user = currentUser
newPost.save(failOnError: true)

// currentUser.addToPosts(newPost)
render (['success': true] as JSON)
}
}

def show(){
def post = Post.get(params.id)
render post as JSON
}

def update(){
def post = Post.findById(params.id)
if(!post.hasErrors()){
def currentUser = User.get(springSecurityService.principal.id)
post.addToLikers(currentUser)
post.save(flush: true)
render(['success': true] as JSON)
}
}
}

事后
package com.patrickjuen.restsocnet

class Post {

String content
Date dateCreated
User user
static belongsTo = User
static hasMany = [likers: User]
// static mappedBy = [likers: "likedPost"]
static constraints = {
likers nullable: true
}
static mapping = {
likers lazy: false
}
}

Bootstrap.groovy
import com.patrickjuen.restsocnet.Post
import com.patrickjuen.restsocnet.Role
import com.patrickjuen.restsocnet.User
import com.patrickjuen.restsocnet.UserRole
import grails.converters.JSON

class BootStrap {

def init = { servletContext ->

JSON.registerObjectMarshaller(User) {
def returnArray = [:]
returnArray['id'] = it.id
returnArray['username'] = it.username
returnArray['posts'] = it.posts
return returnArray
}
JSON.registerObjectMarshaller(Post) {
def returnArray = [:]
returnArray['id'] = it.id
returnArray['content'] = it.content
returnArray['dateCreated'] = it.dateCreated
returnArray['user'] = it.user
returnArray['likers'] = it.likers
return returnArray
}


def role = new Role(authority: "ROLE_USER")
def user1 = new User(username: "user1", password: "password")
def user2 = new User(username: "user2", password: "password")
role.save()
user1.save()
user2.save()

def post1 = new Post(content: "new post number 1")
def post2 = new Post(content: "new post number 2")
def post3 = new Post(content: "one more ")
def post4 = new Post(content: "i am user2 guys hehehe")
post1.save()
post2.save()
post3.save()
post4.save()

user1.addToPosts(post1)
user1.addToPosts(post2)
user1.addToPosts(post3)
user2.addToPosts(post4)
post2.addToLikers(user2)
post2.addToLikers(user1)
post1.addToLikers(user1)

UserRole.create(user1, role, true)
UserRole.create(user2, role, true)
}
def destroy = {
}
}

PostController.groovy
package com.patrickjuen.restsocnet

import grails.converters.JSON

//import grails.plugin.springsecurity.annotation.Secured
import org.springframework.security.access.annotation.Secured


@Secured(['isFullyAuthenticated()'])
class PostController {

static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]


def springSecurityService

def index() {
render Post.list(sort: "dateCreated", order: "desc") as JSON
}

def save(){
def newPost = new Post(request.JSON)
if(!newPost.hasErrors()){
def currentUser = User.get(springSecurityService.principal.id)
println currentUser
newPost.user = currentUser
newPost.save(failOnError: true)

// currentUser.addToPosts(newPost)
render (['success': true] as JSON)
}
}

def show(){
def post = Post.get(params.id)
render post as JSON
}

def update(){
def post = Post.findById(params.id)
if(!post.hasErrors()){
def currentUser = User.get(springSecurityService.principal.id)
post.addToLikers(currentUser)
post.save(flush: true)
render(['success': true] as JSON)
}
}
}

我尝试删除JSON对象编码器,它不再发出错误,但是我将无法访问 hasMany的属性。所以我想主要的问题是JSON对象编码器。我执行错误吗?还是有使用JSON对象编码器的替代方法?但是再次奏效,因为我在 Bootstrap.groovy中实现了它们
另外,我尝试将 post.save(flush:true)更改为 post.save(),它不会发出错误,但类似内容未保存在数据库中。

以防万一您对呈现的JSON感兴趣。
这是对 GETapi/posts/请求

没有JSON对象编码器
[
{
"class": "com.patrickjuen.restsocnet.Post",
"id": 4,
"content": "i am user2 guys hehehe",
"dateCreated": "2015-09-25T17:39:10Z",
"likers": [],
"user": {
"class": "com.patrickjuen.restsocnet.User",
"id": 2
}
},
{
"class": "com.patrickjuen.restsocnet.Post",
"id": 3,
"content": "one more",
"dateCreated": "2015-09-25T17:39:10Z",
"likers": [],
"user": {
"class": "com.patrickjuen.restsocnet.User",
"id": 1
}
},
{
"class": "com.patrickjuen.restsocnet.Post",
"id": 2,
"content": "new post number 2",
"dateCreated": "2015-09-25T17:39:10Z",
"likers": [
{
"class": "com.patrickjuen.restsocnet.User",
"id": 1
},
{
"class": "com.patrickjuen.restsocnet.User",
"id": 2
}
],
"user": {
"class": "com.patrickjuen.restsocnet.User",
"id": 1
}
},
{
"class": "com.patrickjuen.restsocnet.Post",
"id": 1,
"content": "new post number 1",
"dateCreated": "2015-09-25T17:39:10Z",
"likers": [
{
"class": "com.patrickjuen.restsocnet.User",
"id": 1
}
],
"user": {
"class": "com.patrickjuen.restsocnet.User",
"id": 1
}
}
]

使用JSON对象编码器
[
{
"id": 4,
"content": "i am user2 guys hehehe",
"dateCreated": "2015-09-25T17:50:58Z",
"user": {
"id": 2,
"username": "user2",
"posts": [
{
"_ref": "../../../..",
"class": "com.patrickjuen.restsocnet.Post"
}
]
},
"likers": []
},
{
"id": 3,
"content": "one more",
"dateCreated": "2015-09-25T17:50:58Z",
"user": {
"id": 1,
"username": "user1",
"posts": [
{
"_ref": "../../../..",
"class": "com.patrickjuen.restsocnet.Post"
},
{
"id": 2,
"content": "new post number 2",
"dateCreated": "2015-09-25T17:50:58Z",
"user": {
"_ref": "../../../..",
"class": "com.patrickjuen.restsocnet.User"
},
"likers": [
{
"_ref": "../../../../..",
"class": "com.patrickjuen.restsocnet.User_$$_javassist_5"
},
{
"id": 2,
"username": "user2",
"posts": [
{
"id": 4,
"content": "i am user2 guys hehehe",
"dateCreated": "2015-09-25T17:50:58Z",
"user": {
"_ref": "../../../..",
"class": "com.patrickjuen.restsocnet.User"
},
"likers": []
}
]
}
]
},
{
"id": 1,
"content": "new post number 1",
"dateCreated": "2015-09-25T17:50:58Z",
"user": {
"_ref": "../../../..",
"class": "com.patrickjuen.restsocnet.User"
},
"likers": [
{
"_ref": "../../../../..",
"class": "com.patrickjuen.restsocnet.User_$$_javassist_5"
}
]
}
]
},
"likers": []
},
{
"id": 2,
"content": "new post number 2",
"dateCreated": "2015-09-25T17:50:58Z",
"user": {
"id": 1,
"username": "user1",
"posts": [
{
"id": 3,
"content": "one more",
"dateCreated": "2015-09-25T17:50:58Z",
"user": {
"_ref": "../../../..",
"class": "com.patrickjuen.restsocnet.User"
},
"likers": []
},
{
"_ref": "../../../..",
"class": "com.patrickjuen.restsocnet.Post"
},
{
"id": 1,
"content": "new post number 1",
"dateCreated": "2015-09-25T17:50:58Z",
"user": {
"_ref": "../../../..",
"class": "com.patrickjuen.restsocnet.User"
},
"likers": [
{
"_ref": "../../../../..",
"class": "com.patrickjuen.restsocnet.User_$$_javassist_5"
}
]
}
]
},
"likers": [
{
"id": 1,
"username": "user1",
"posts": [
{
"id": 3,
"content": "one more",
"dateCreated": "2015-09-25T17:50:58Z",
"user": {
"_ref": "../../../..",
"class": "com.patrickjuen.restsocnet.User"
},
"likers": []
},
{
"_ref": "../../../../..",
"class": "com.patrickjuen.restsocnet.Post"
},
{
"id": 1,
"content": "new post number 1",
"dateCreated": "2015-09-25T17:50:58Z",
"user": {
"_ref": "../../../..",
"class": "com.patrickjuen.restsocnet.User"
},
"likers": [
{
"_ref": "../../../../..",
"class": "com.patrickjuen.restsocnet.User_$$_javassist_5"
}
]
}
]
},
{
"id": 2,
"username": "user2",
"posts": [
{
"id": 4,
"content": "i am user2 guys hehehe",
"dateCreated": "2015-09-25T17:50:58Z",
"user": {
"_ref": "../../../..",
"class": "com.patrickjuen.restsocnet.User"
},
"likers": []
}
]
}
]
},
{
"id": 1,
"content": "new post number 1",
"dateCreated": "2015-09-25T17:50:58Z",
"user": {
"id": 1,
"username": "user1",
"posts": [
{
"id": 3,
"content": "one more",
"dateCreated": "2015-09-25T17:50:58Z",
"user": {
"_ref": "../../../..",
"class": "com.patrickjuen.restsocnet.User"
},
"likers": []
},
{
"id": 2,
"content": "new post number 2",
"dateCreated": "2015-09-25T17:50:58Z",
"user": {
"_ref": "../../../..",
"class": "com.patrickjuen.restsocnet.User"
},
"likers": [
{
"_ref": "../../../../..",
"class": "com.patrickjuen.restsocnet.User_$$_javassist_5"
},
{
"id": 2,
"username": "user2",
"posts": [
{
"id": 4,
"content": "i am user2 guys hehehe",
"dateCreated": "2015-09-25T17:50:58Z",
"user": {
"_ref": "../../../..",
"class": "com.patrickjuen.restsocnet.User"
},
"likers": []
}
]
}
]
},
{
"_ref": "../../../..",
"class": "com.patrickjuen.restsocnet.Post"
}
]
},
"likers": [
{
"id": 1,
"username": "user1",
"posts": [
{
"id": 3,
"content": "one more",
"dateCreated": "2015-09-25T17:50:58Z",
"user": {
"_ref": "../../../..",
"class": "com.patrickjuen.restsocnet.User"
},
"likers": []
},
{
"id": 2,
"content": "new post number 2",
"dateCreated": "2015-09-25T17:50:58Z",
"user": {
"_ref": "../../../..",
"class": "com.patrickjuen.restsocnet.User"
},
"likers": [
{
"_ref": "../../../../..",
"class": "com.patrickjuen.restsocnet.User_$$_javassist_5"
},
{
"id": 2,
"username": "user2",
"posts": [
{
"id": 4,
"content": "i am user2 guys hehehe",
"dateCreated": "2015-09-25T17:50:58Z",
"user": {
"_ref": "../../../..",
"class": "com.patrickjuen.restsocnet.User"
},
"likers": []
}
]
}
]
},
{
"_ref": "../../../../..",
"class": "com.patrickjuen.restsocnet.Post"
}
]
}
]
}
]

最佳答案

我刚刚找到了解决方案。只需将此代码插入Config.groovygrails.converters.json.circular.reference.behaviour = "INSERT_NULL"
我在这篇文章的评论之一中看到了它http://manbuildswebsite.com/2010/02/15/rendering-json-in-grails-part-3-customise-your-json-with-object-marshallers/

关于json - 错误error.GrailsExceptionResolver-JSONException的endArray放错了位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32788143/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com