Grails View (show.gsp) 不处理预期类的实例,而是获取 null

标签 grails inheritance gsp

我的 WebApplication 中有一个 User 类和一个 Driver 类,它是 User 的子类。这是代码:

elektrova 包

class User {

String username
String password
String firstName
String lastName
UserRole role

static belongsTo = [
    hauler:Hauler
]

static hasMany = [
    createdJobs:Job,
    activities:UserActivityHistory
]

static mappedBy = [
    createdJobs:'creationUser'
]

static mapping = { tablePerHierarchy false }

static constraints = {
    username(blank:false, size:4..15,matches:/[\S]+/, unique:true)
    password(blank:false, size:4..15,matches:/[\S]+/)
    firstName(blank:false, nullable:false)
    lastName(blank:false, nullable:false)
    role(blank:false, nullable:false)
}

@Override
def encodeAsHTML(){
    firstName + "  " + lastName
}
}



class Driver extends User{


UserRole role = UserRole.DRIVER

static hasMany = [
    assignedJobs:Job
    ]
static mappedBy = [assignedJobs:'assignedUser']
static constraints = {
}
}

这是在 Bootstrap 中创建tesdata:

        User dispo = new Driver(hauler: hauler, firstName: "Dis", lastName: "Po", password: "dispo", role: UserRole.ADMIN, username: "dispo" ).save(failOnError: true)
        Driver driver = new Driver(hauler: hauler, firstName: "Kai", lastName: "Uwe", password: "kauw", role: UserRole.DRIVER, username: "kauw" ).save(failOnError: true)
        Driver driver2 = new Driver(hauler: hauler, firstName: "Hans", lastName: "Juergen", password: "haju", role: UserRole.DRIVER, username: "haju" ).save(failOnError: true)
        User admin = new User(hauler: hauler, firstName: "Ad", lastName: "Min", password: "admin", role: UserRole.ADMIN, username: "admin" ).save(failOnError: true)
        User admin2 = new User(hauler: hauler, firstName: "Ad", lastName: "Min", password: "admin", role: UserRole.ADMIN, username: "admin2" ).save(failOnError: true)

还有 show.gsp:

<%@ page import="elektrova.User"%>
<!DOCTYPE html>
<html>
<head>
<meta name="layout" content="main">
<g:set var="entityName"
value="${message(code: 'user.label', default: 'User')}" />
<title><g:message code="default.show.label" args="[entityName]" /></title>
</head>
<body>
<g:render template="/navi/navbar" />
<a href="#show-user" class="skip" tabindex="-1"><g:message
        code="default.link.skip.label" default="Skip to content&hellip;" /></a>
<div class="nav" role="navigation">
    <ul>

        <li><g:link class="list" action="index">
                <g:message code="view.user.button.label.list" args="[entityName]" />
            </g:link></li>
        <li><g:link class="create" action="create">
                <g:message code="view.user.button.label.create" args="[entityName]" />
            </g:link></li>
    </ul>
</div>
<div id="show-user" class="scaffold-show" role="main">
    <h1>
        <g:message code="default.show.label" args="[entityName]" />${userInstance.toString() }
    </h1>
    <g:if test="${flash.message}">
        <div class="message" role="status">
            ${flash.message}
        </div>
    </g:if>
    <ol class="property-list user">
<% System.out.println "user : " + userInstance %>
        <g:if test="${userInstance?.hauler}">
            <li class="fieldcontain"><span id="hauler-label"
                class="property-label"><g:message code="hauler.label"
                        default="Hauler" /></span> <span class="property-value"
                aria-labelledby="hauler-label"><g:link controller="hauler"
                        action="show" id="${userInstance?.hauler?.id}">
                        ${userInstance?.hauler?.encodeAsHTML()}
                    </g:link></span></li>
        </g:if>

        <g:if test="${userInstance?.username}">
            <li class="fieldcontain"><span id="username-label"
                class="property-label"><g:message code="user.username.label"
                        default="Username" /></span> <span class="property-value"
                aria-labelledby="username-label"><g:fieldValue
                        bean="${userInstance}" field="username" /></span></li>
        </g:if>

        <g:if test="${userInstance?.password}">
            <li class="fieldcontain"><span id="password-label"
                class="property-label"><g:message code="user.password.label"
                        default="Password" /></span> <span class="property-value"
                aria-labelledby="password-label"><g:fieldValue
                        bean="${userInstance}" field="password" /></span></li>
        </g:if>

        <g:if test="${userInstance?.firstName}">
            <li class="fieldcontain"><span id="firstName-label"
                class="property-label"><g:message
                        code="user.firstName.label" default="First Name" /></span> <span
                class="property-value" aria-labelledby="firstName-label"><g:fieldValue
                        bean="${userInstance}" field="firstName" /></span></li>
        </g:if>

        <g:if test="${userInstance?.lastName}">
            <li class="fieldcontain"><span id="lastName-label"
                class="property-label"><g:message code="user.lastName.label"
                        default="Last Name" /></span> <span class="property-value"
                aria-labelledby="lastName-label"><g:fieldValue
                        bean="${userInstance}" field="lastName" /></span></li>
        </g:if>

        <g:if test="${userInstance?.role}">
            <li class="fieldcontain"><span id="role-label"
                class="property-label"><g:message code="user.role.label"
                        default="Role" /></span> <span class="property-value"
                aria-labelledby="role-label"><g:fieldValue
                        bean="${userInstance}" field="role" /></span></li>
        </g:if>


        <g:if test="${userInstance?.createdJobs}">
            <li class="fieldcontain"><span id="createdJobs-label"
                class="property-label"><g:message
                        code="user.createdJobs.label" default="Created Jobs" /></span> <g:each
                    in="${userInstance.createdJobs}" var="c">
                    <span class="property-value" aria-labelledby="createdJobs-label"><g:link
                            controller="job" action="show" id="${c.id}">
                            ${c?.encodeAsHTML()}
                        </g:link></span>
                </g:each></li>
        </g:if>

        <g:if test="${userInstance?.createdJobs}">
            <li class="fieldcontain"><span id="createdJobs-label"
                class="property-label"><g:message
                        code="user.createdJobs.label" default="Created Jobs" /></span> <g:each
                    in="${userInstance.createdJobs}" var="c">
                    <span class="property-value" aria-labelledby="createdJobs-label"><g:link
                            controller="job" action="show" id="${c.id}">
                            ${c?.encodeAsHTML()}
                        </g:link></span>
                </g:each></li>
        </g:if>

    </ol>
    <g:form url="[resource:userInstance, action:'delete']" method="DELETE">
        <fieldset class="buttons">
            <g:link class="edit" action="edit" resource="${userInstance}">
                <g:message code="default.button.edit.label" default="Edit" />
            </g:link>
            <g:actionSubmit class="delete" action="delete"
                value="${message(code: 'default.button.delete.label', default: 'Delete')}"
                onclick="return confirm('${message(code: 'default.button.delete.confirm.message', default: 'Are you sure?')}');" />
        </fieldset>
    </g:form>
</div>

Controller :

import static org.springframework.http.HttpStatus.*
import grails.transaction.Transactional

@Transactional(readOnly = true)
class UserController {

def beforeInterceptor = [action: this.&auth]

def auth = {
    if(!session.user) {
        redirect(controller:"login", action: "index")
    }
}

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



def index(Integer max) {
    params.max = Math.min(max ?: 10, 100)
    model:[userInstanceList: User.list(params),userInstanceCount: User.count()]
}

def show(User userInstance) {
    println 'User: ' + userInstance
    respond userInstance
}

def create() {
    respond new User(params)
}

@Transactional
def save(User userInstance) {
    if (userInstance == null) {
        notFound()
        return
    }

    if (userInstance.hasErrors()) {
        respond userInstance.errors, view:'create'
        return
    }

    userInstance.save flush:true

    request.withFormat {
        form {
            flash.message = message(code: 'default.created.message', args: [message(code: 'userInstance.label', default: 'User'), userInstance.id])
            redirect userInstance
        }
        '*' { respond userInstance, [status: CREATED] }
    }
}

def edit(User userInstance) {
    respond userInstance
}

@Transactional
def update(User userInstance) {
    if (userInstance == null) {
        notFound()
        return
    }

    if (userInstance.hasErrors()) {
        respond userInstance.errors, view:'edit'
        return
    }

    userInstance.save flush:true

    request.withFormat {
        form {
            flash.message = message(code: 'default.updated.message', args: [message(code: 'User.label', default: 'User'), userInstance.id])
            redirect userInstance
        }
        '*'{ respond userInstance, [status: OK] }
    }
}

@Transactional
def delete(User userInstance) {

    if (userInstance == null) {
        notFound()
        return
    }

    userInstance.delete flush:true

    request.withFormat {
        form {
            flash.message = message(code: 'default.deleted.message', args: [message(code: 'User.label', default: 'User'), userInstance.id])
            redirect action:"index", method:"GET"
        }
        '*'{ render status: NO_CONTENT }
    }
}

protected void notFound() {
    request.withFormat {
        form {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'userInstance.label', default: 'User'), params.id])
            redirect action: "index", method: "GET"
        }
        '*'{ render status: NOT_FOUND }
    }
}
}

现在 UserController 中一切正常,正确的 User 实例始终传递到 View 。但是 gsp 对于所有对象都接收 null,除了两个管理员之外,它们都被正确渲染。起初我认为这是因为 View 无法处理子类,但 Dispo User 也没有显示。更改其他实例的角色仍然不会显示它们。 有什么建议吗?

最佳答案

这是一个老问题,但我刚刚遇到了同样的问题,并通过向 respond 语句添加模型参数来“修复”它:

def show(User userInstance) {
    println 'User: ' + userInstance
    respond userInstance, model:[userInstance:userInstance]
}

就我而言,“User”类是一个基类,而我实际上是在基类 Controller 中处理它的继承类。 respond 对此完全感到困惑。

关于Grails View (show.gsp) 不处理预期类的实例,而是获取 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21629521/

相关文章:

java - 构造函数中的静态

grails - Urls包含非法字符未映射到Grails中的 Controller

c++ - 这段 C++ 代码的安全性和独立于编译器的程度如何?

grails - 本地主机突然将您重定向了太多次

可编码类的继承

html - 将 id 字段添加到 GSP <g :form> tag 的 HTML 最终结果

Grails 3.1.8 : Scaffolded edit. gsp 不缩进 hasMany 集

grails - Grails-检查项目是否具有父项

grails - Grails-使用称为创建预订的客户记录名称自动填充字段

grails - Grails 3:控制台插件不在生产模式下出现