【问题标题】:Inject services to src/groovy in Grails 3.0.9在 Grails 3.0.9 中向 src/groovy 注入服务
【发布时间】:2016-02-22 16:26:48
【问题描述】:

我正在尝试创建一个 EndPoint 文件。所以我创建了一个名为ServerEndPointDemo.groovy的文件

package com.akiong

import grails.util.Environment
import grails.util.Holders

import javax.servlet.ServletContext
import javax.servlet.ServletContextEvent
import javax.servlet.ServletContextListener
import javax.servlet.annotation.WebListener
import javax.websocket.EndpointConfig
import javax.websocket.OnClose
import javax.websocket.OnError
import javax.websocket.OnMessage
import javax.websocket.OnOpen
import javax.websocket.Session
import javax.websocket.server.PathParam
import javax.websocket.server.ServerContainer
import javax.websocket.server.ServerEndpoint
import javax.websocket.EncodeException

import javax.servlet.annotation.WebListener
import java.util.concurrent.CopyOnWriteArraySet

@WebListener
@ServerEndpoint(value="/chat/test/{username}")

public class ServerEndPointDemo implements ServletContextListener {
    private static HashMap<String, String> usersMap = new HashMap<String, String>();
    private static final Set<ServerEndPointDemo> connections = new CopyOnWriteArraySet<>();
    private String username
    private Session session

    @OnOpen
    public void  handleOpen(Session session,@PathParam("username") String user){
        System.out.println("-------------------------------------");

        System.out.println(session.getId() + " has opened a connection");
        println "user = "+user

        connections.add(this);
        this.username   = user
        this.session    = session

        addUserToMap(username,session.getId())

        try{
            def ctx = Holders.applicationContext
            chatService = ctx.chatService
        }
        catch (Exception e){
            println "e = "+e
        }

    }

    @OnClose
    public void  handleClose(Session session){  
        System.out.println("Session " +session.getId()+" has ended");  
    }

    @OnMessage
    public String handleMessage(String message,Session session){
        chatService.saveSessionAdminJava(session.getId())    
    }

    @OnError
    public void  handleError(Throwable t){
        println "error ~"
    }  

    private void sendMessageToAll(String message){
        println "session.size() = "+sessions.size()
        for(Session s : sessions){
            try {
                s.getBasicRemote().sendText(message);
                println "sent to session = "+s.getId()
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}
`

我尝试使用此代码从服务调用方法:

try {
    def ctx = Holders.applicationContext
    chatService = ctx.chatService
} catch (Exception e) {
    println "e = " + e
}

这是我的服务:

package com.akiong.services

import com.akiong.maintenance.Chat

class ChatService {

    def serviceMethod() {

    }

    def saveSessionAdminJava(def sessionJava) {
        println "jaln!!!"
        def chatInstance = Chat.findByIsAdmin("1")
        chatInstance.sessionJava = sessionJava
        chatInstance.save(failOnError: true)
    }
}

但是在我尝试运行这段代码之后,我收到了这个错误:

Error : groovy.lang.MissingPropertyException: No such property: chatService for
class: com.akiong.ServerEndPointDemo

有人知道如何在src/groovy 中从服务调用方法到文件吗?

【问题讨论】:

  • 现有的插件会让你感到困惑吗?因为 wschat 正在做所有这些,而不是在主类中定义类,而是在 ChatUtils.groovy 中初始化,然后在 WsChatEndPoint 中注入。原因是 EndPoint + 其他 4 个其他端点都扩展了 ChatUtils 类实际上节省了我一遍又一遍地声明相同内容的时间

标签: grails groovy grails-3.0.9


【解决方案1】:

所以这就是问题所在。您编写的代码对于注入服务是正确的:

try {
    def ctx = Holders.applicationContext
    chatService = ctx.chatService
} catch (Exception e) {
    println "e = "+e
}

但是chatService 没有在你的类中的任何地方定义。因此,即使您的handleOpen 方法被调用,也必须抛出MissingPropertyException,但是由于您已经处理了顶级Exception 类(永远不应该鼓励)您的@987654326 中的异常@ 方法被抑制了。

现在,稍后在您的 handleMessage 方法中,同样的问题再次发生,chatService 未定义,因此您收到了您在问题中发布的异常。

所以,您现在知道答案了 :-) 只需在您的 ServerEndPointDemo 类中定义 chatService

更新:

public class ServerEndPointDemo implements ServletContextListener {
    private static HashMap<String, String> usersMap = new HashMap<String, String>();
    private static final Set<ServerEndPointDemo> connections = new CopyOnWriteArraySet<>();
    private String username
    private Session session

    def chartService    // Initialize here
    // rest of your code
}

【讨论】:

  • 不,这是错误的。您是在 try-catch 内部定义的,因此它的范围将仅限于那里。我已经更新了答案。
【解决方案2】:
import org.apache.commons.logging.LogFactory;
import org.codehaus.groovy.grails.commons.ApplicationHolder as AH

class MyClass{
    private static final log = LogFactory.getLog(this)
    def ctx = AH.application.mainContext
    def authService=ctx.authService

    def method(){
        log.debug "into MyClass method"
    }
}

【讨论】:

  • ` org.codehaus.groovy.grails.commons.ApplicationHolder @ line 20, column 1. import org.codehaus.groovy.grails.commons.ApplicationHolder as AH ^ C:\Users\User\Documents \309\bola309\src\main\groovy\com\akiong\ServerEndPointDem o.groovy:34:无法解析类 org.codehaus.groovy.grails.commons.ApplicationHolder @ 第 34 行,第 15 列。def ctx = AH。 application.mainContext ^ 2 个错误`
猜你喜欢
  • 2012-05-25
  • 2016-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多