找不到使用域类资源创建的Grails REST API返回

问题描述

我正在尝试创建用于用户编辑的REST api。

我决定使用文档中所述的方法

https://docs.grails.org/3.3.11/guide/REST.html#domainResources(我使用的是较旧的grailsversion = 3.3.11)

所以我继续并创建了这样的域类(域类是由grails s2-quickstart com.mastiko.auth用户角色命令创建的)

package com.mastiko.auth


import grails.rest.Resource

@Resource(uri = '/api/users',formats=['json'])
class User implements Serializable {

    private static final long serialVersionUID = 1

    String username
    String password
    String mems****ApiUser
    String mems****ApiPassword
    boolean enabled = true
    boolean accountExpired
    boolean accountLocked
    boolean passwordExpired

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

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

    static mapping = {
        password column: '`password`'
    }
}

我的application.groovy看起来像这样:



// Added by the Spring Security Core plugin:
grails.plugin.springsecurity.userLookup.userDomainClassName = 'com.mastiko.auth.User'
grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'com.mastiko.auth.UserRole'
grails.plugin.springsecurity.authority.className = 'com.mastiko.auth.Role'
grails.plugin.springsecurity.controllerAnnotations.staticrules = [
    [pattern: '/',access: ['permitAll']],[pattern: '/dbconsole/**',[pattern: '/error',[pattern: '/index',[pattern: '/index.gsp',[pattern: '/shutdown',[pattern: '/assets/**',[pattern: '/**/js/**',[pattern: '/**/css/**',[pattern: '/**/images/**',[pattern: '/**/favicon.ico',access: ['permitAll']]
]

grails.plugin.springsecurity.filterChain.chainMap = [
    [pattern: '/assets/**',filters: 'none'],[pattern: '/**',filters: 'JOINED_FILTERS']
]

此外,我将此配置添加到application.yml中,因为没有它我无法使spring security rest api插件正常工作

plugin:
  springsecurity:
    controllerAnnotations:
      chainMap:
        '/api/**': 'JOINED_FILTERS,-anonymousAuthenticationFilter,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter'
        '/**': 'JOINED_FILTERS,-restTokenValidationFilter,-restExceptionTranslationFilter'

我的urlmappings.groovy

package mems****eprojects (censored)

class UrlMappings {

    static mappings = {
        delete "/$controller/$id(.$format)?"(action:"delete")
        get "/$controller(.$format)?"(action:"index")
        get "/$controller/$id(.$format)?"(action:"show")
        post "/$controller(.$format)?"(action:"save")
        put "/$controller/$id(.$format)?"(action:"update")
        patch "/$controller/$id(.$format)?"(action:"patch")

        "/"(controller: 'application',action:'index')
    }
}

现在,当我尝试使用对http:// localhost:8080 / api / users的POST请求访问我的api时,我总是得到404 not found响应:

{
    "timestamp": 1598893213831,"status": 404,"error": "Not Found","message": "No message available","path": "/api/users"
}

我尝试执行命令grails url-mappings-report,结果是肯定的:

Dynamic Mappings
 |   GET    | /${controller}(.${format)?            | Action: index                 |
 |   POST   | /${controller}(.${format)?            | Action: save                  |
 |  DELETE  | /${controller}/${id}(.${format)?      | Action: delete                |
 |   GET    | /${controller}/${id}(.${format)?      | Action: show                  |
 |   PUT    | /${controller}/${id}(.${format)?      | Action: update                |
 |  PATCH   | /${controller}/${id}(.${format)?      | Action: patch                 |

Controller: application
 |    *     | /                                     | Action: index                 |

Controller: restOauth
 |    *     | /oauth/access_token                   | Action: accesstoken           |
 |    *     | /oauth/${action}/${provider}          | Action: (default action)      |

Controller: user
 |   GET    | /api/users/create                     | Action: create                |
 |   GET    | /api/users/${id}/edit                 | Action: edit                  |
 |   POST   | /api/users                            | Action: save                  |
 |   GET    | /api/users                            | Action: index                 |
 |  DELETE  | /api/users/${id}                      | Action: delete                |
 |  PATCH   | /api/users/${id}                      | Action: patch                 |
 |   PUT    | /api/users/${id}                      | Action: update                |
 |   GET    | /api/users/${id}                      | Action: show                  |

我还很陌生,这是我的第一个应用程序。

很抱歉,如果缺少某些重要的代码部分,请在需要时将其发布。你能帮我么?我已经尝试了好几个小时。

//编辑1 我忘了添加我的build.gradle

buildscript {
    repositories {
        mavenLocal()
        maven { url "https://repo.grails.org/grails/core" }
        maven { url "https://plugins.gradle.org/m2/" }
    }
    dependencies {
        classpath "org.grails:grails-gradle-plugin:$grailsversion"
        classpath "com.moowork.gradle:gradle-node-plugin:1.2.0"
        classpath "org.grails.plugins:hibernate5:${gormVersion-".RELEASE"}"
        classpath "org.grails.plugins:views-gradle:1.2.9"
    }
}

version "0.1"
group "mem****eprojects"

apply plugin:"eclipse"
apply plugin:"idea"
apply plugin:"war"
apply plugin:"org.grails.grails-web"
apply plugin:"com.moowork.node"
apply plugin:"org.grails.plugins.views-json"

repositories {
    mavenLocal()
    maven { url "https://repo.grails.org/grails/core" }
}

dependencies {
    compile "org.springframework.boot:spring-boot-starter-logging"
    compile "org.springframework.boot:spring-boot-autoconfigure"
    compile "org.grails:grails-core"
    compile "org.springframework.boot:spring-boot-starter-actuator"
    compile "org.springframework.boot:spring-boot-starter-tomcat"
    compile "org.grails:grails-plugin-url-mappings"
    compile "org.grails:grails-plugin-rest"
    compile "org.grails:grails-plugin-codecs"
    compile "org.grails:grails-plugin-interceptors"
    compile "org.grails:grails-plugin-services"
    compile "org.grails:grails-plugin-datasource"
    compile "org.grails:grails-plugin-databinding"
    compile "org.grails:grails-web-boot"
    compile "org.grails:grails-logging"
    compile "org.grails.plugins:cache"
    compile "org.grails.plugins:async"
    compile "org.grails.plugins:hibernate5"
    compile "org.hibernate:hibernate-core:5.1.16.Final"
    compile "org.grails.plugins:views-json"
    compile "org.grails.plugins:views-json-templates"
    compile "org.grails.plugins:spring-security-core:3.2.0"
    compile "org.grails.plugins:spring-security-rest:2.0.0.M2"
    console "org.grails:grails-console"
    profile "org.grails.profiles:vue"
    runtime "org.glassfish.web:el-impl:2.1.2-b03"
    runtime "com.h2database:h2"
    runtime "org.apache.tomcat:tomcat-jdbc"
    testCompile "org.grails:grails-gorm-testing-support"
    testCompile "org.grails:grails-datastore-rest-client"
    testCompile "org.grails:grails-web-testing-support"
}

bootRun {
    jvmArgs('-Dspring.output.ansi.enabled=always')
    addResources = true
    String springProfilesActive = 'spring.profiles.active'
    systemProperty springProfilesActive,System.getProperty(springProfilesActive)
}

添加了spring-security-rest插件,以便能够使用/ api / login端点从vuejs前端进行身份验证。我检索了令牌,然后尝试使用标头中的令牌向/ api / users端点发出请求。所以也许问题可能是由这个插件引起的

解决方法

所以我能够解决这个问题,从application.yml中删除代码

plugin:
  springsecurity:
    controllerAnnotations:
      chainMap:
        '/api/**': 'JOINED_FILTERS,-anonymousAuthenticationFilter,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter'
        '/**': 'JOINED_FILTERS,-restTokenValidationFilter,-restExceptionTranslationFilter'

并将以下代码添加到application.groovy

grails.plugin.springsecurity.filterChain.chainMap = [
        //Stateless chain
        [ pattern: '/api/**',filters: 'JOINED_FILTERS,-securityContextPersistenceFilter,-rememberMeAuthenticationFilter'],//Traditional chain
        //[ pattern: '/**',-restExceptionTranslationFilter']
]

我不确定我为什么首先将chainMap放在application.yml中。

感谢您阅读本文并尽力帮助我