WebHU - Programozási kérdések és válaszok

Grails nulla mutató kivétel a szerviz hívásakor

Megpróbálok hívni egy vezérlőben létrehozott szolgáltatást. Ez a szolgáltatás:

package matriculation

import grails.transaction.Transactional
import groovy.sql.Sql

@Transactional
class StudNamesService {

    def getNameById(String id) {

        return id
    }
}

És ez a vezérlő része

package matriculation

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

@Transactional(readOnly = true)
class MatrEntryController {

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

    def studNamesService

    def getNameById(String id){
        return studNamesService.getNameById(id)
    }
}

Amikor bármikor meghívom a vezérlőmben a szolgáltatást hívó metódust, a következő hibaüzenetet kapom:

Class: java.lang.NullPointerException
Message: Request processing failed; nested exception is org.grails.gsp.GroovyPagesException: Error evaluating expression [cont.getNameById(matrEntryInstance.peopleCodeId)] on line [61]: Cannot invoke method getNameById() on null object
Caused by:Cannot invoke method getNameById() on null object

Ennek a kérdésnek a kódjában minimális változtatásokat végeztem. Amint láthatja, a vezérlőben lévő hívásnak pontosan ugyanaz a neve, mint a szolgáltatás nevének, ahogy kell. A Grails 3.1.1-et futtatom

1. szerkesztés Ez annak a GSP-oldalnak a része, amely a metódust hívja:

<%@ page import="matriculation.MatrEntryController" %>

<%
    def cont=grailsApplication.classLoader.loadClass("matriculation.MatrEntryController").newInstance()
%>
<!----------------------Skip a few lines----------------------------->
<table>
     <thead>
         <tr>
            <th id="cols">Options</th>
            <g:sortableColumn property="peopleCodeId" title="People Code ID" id="cols"/>
            <g:sortableColumn property="cadetName" title="Cadet Name" id="cols"/>
            <g:sortableColumn property="soff" title="SOFF" id="cols"/>
            <g:sortableColumn property="infirmary" title="Infirmary" id="cols"/>
            <g:sortableColumn property="hsRotc" title="HS ROTC" id="cols"/>
            <g:sortableColumn property="idfy" title="IDFY" id="cols"/>
            <g:sortableColumn property="pao" title="Public Affairs" id="cols"/>
            <g:sortableColumn property="busOffice" title="Business Office" id="cols"/>
            <g:sortableColumn property="telephone" title="Telephone" id="cols"/>
            <g:sortableColumn property="computer" title="Computer" id="cols"/>
            <g:sortableColumn property="athletics" title="Athletics" id="cols"/>
            <g:sortableColumn property="financialAid" title="Financial Aid" id="cols"/>
            <g:sortableColumn property="compass" title="Compass" id="cols"/>
            <g:sortableColumn property="regFlag" title="Registration Flag" id="cols"/>
            <g:sortableColumn property="busOfficeForm" title="${raw('Business<br/>Office Form')}" id="cols"/>
         </tr>
       </thead>
       <tbody>
         <g:each in="${matrEntryList}" status="i" var="matrEntryInstance">
             <tr class="${(i % 2) == 0 ? 'even' : 'odd'}">
                 <td id="cols">
                     <g:form resource="${matrEntryInstance}" method="DELETE">
                        <a href="${createLink(controller:'matrEntry',action:'show')+'/'+matrEntryInstance.id}" class="btn btn-default">Show</a>
                         <a href="${createLink(controller:'matrEntry',action:'edit')+'/'+matrEntryInstance.id}" class="btn btn-default">Edit</a>
                     </g:form>
                   </td>
                   <td id="cols">${matrEntryInstance.peopleCodeId}</td> 
                   <td id="cols">${cont.getNameById(matrEntryInstance.peopleCodeId)}</td>
                   <td id="cols">${matrEntryInstance.soff}</td>
                   <td id="cols">${matrEntryInstance.infirmary}</td>
                   <td id="cols">${matrEntryInstance.hsRotc}</td>
                   <td id="cols">${matrEntryInstance.idfy}</td>
                   <td id="cols">${matrEntryInstance.pao}</td>
                   <td id="cols">${matrEntryInstance.busOffice}</td>
                   <td id="cols">${matrEntryInstance.telephone}</td>
                   <td id="cols">${matrEntryInstance.computer}</td>
                   <td id="cols">${matrEntryInstance.athletics}</td>
                   <td id="cols">${matrEntryInstance.financialAid}</td>
                   <td id="cols">${matrEntryInstance.compass}</td>
                   <td id="cols"><g:formatDate date="${matrEntryInstance.regFlag}" format="dd MMM, yyyy"/></td>
                   <td id="cols">${matrEntryInstance.busOfficeForm}</td>
                 </tr>
               </g:each>
             </tbody>
          </table>
12.12.2016

  • Nézd meg a GSP oldalán. Ezt a módszert próbálja hívni valamire a modellből. További segítségért tegye közzé a GSP oldal kódját. 12.12.2016

Válaszok:


1

Itt az a baj, hogy rosszul közelíted meg a problémát. Ne hozzon létre egy vezérlő példányát a GSP oldalon. Mivel szolgáltatást szeretne hívni, érdemes inkább egy címkekönyvtárat használni.

Íme egy egyszerű példa egy címkekönyvtárra, és annak használatára a GSP-ből:

package com.example

class ExampleTagLib {
    static namespace = "myLookup"
    def exampleService

    def lookupName = { attrs, body ->
        if (!attrs.id) return
        out << exampleService.getNameById(attrs.id)
    }
}

A GSP-ben való használat a következőképpen nézne ki:

<td id="cols">${myLookup.lookupName(id: matrEntryInstance.peopleCodeId)}</td>

Erősen ajánlom, hogy olvassa el a dokumentációt a címkekönyvtárak létrehozásához mielőtt kipróbálnád.

12.12.2016
Új anyagok

A rádiógomb ellenőrzött eseményének használata a jQueryben
Ebben a cikkben látni fogjuk, hogyan kell dolgozni a jquery választógombbal ellenőrzött eseményeivel. A választógombok HTML gombok, amelyek segítenek kiválasztani egyetlen értéket egy csoportból...

Körkörös függőségek megoldása terraformban adatforrásokkal – lépésről lépésre
Mi az a körkörös függőségek Dolgozzunk egy egyszerű eseten, amikor az SQS-sor és az S3-vödör közötti körkörös függőség problémája van egy egymástól függő címkeérték miatt. provider..

Miért érdemes elkezdeni a kódolást 2023-ban?
01100011 01101111 01100100 01100101 — beep boop beep boop Világunk folyamatosan fejlődik a technológia körül, és naponta fejlesztenek új technológiákat a valós problémák megoldására. Amint..

🎙 Random Noise #2  – Örökbefogadás és hit
az analitika íratlan világának gondozása Szeretné, hogy ezek a frissítések a postaládájába kerüljenek? Iratkozzon fel itt . "Ha önvezető autókat gyártanak, akkor mi miért ne..

A legrosszabb politika és prediktív modellek májátültetésre jelöltek számára az Egyesült Államokban
A máj (vagy óangolul lifer) az emberi test legnehezebb belső szervére utal, amely csendesen működik a nap 24 órájában. Mit csinál a máj? 500 feladatot hajt végre a szervezet egészségének..

5 webhely, amely 2022-ben fejleszti front-end fejlesztői készségeit
Frontendmentor.io A tényleges projektek létrehozásával a Frontendmentor.io segítséget nyújt a front-end kódolási képességeinek fejlesztésében. A kódolást azután kezdheti meg, hogy..

Mikor kell használni a Type-t az interfészhez képest a TypeScriptben?
A TypeScript a JavaScript gépelt szuperkészlete, amely statikus gépelést ad a nyelvhez. Ez megkönnyíti a robusztus és karbantartható kód írását azáltal, hogy a hibákat a fordítási időben..