在 Grails 3.0.9 中向 src/groovy 注入服务
Inject services to src/groovy in Grails 3.0.9
我正在尝试创建端点文件。所以我创建了一个名为 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
中从服务调用方法到文件吗?
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"
}
}
所以问题来了。您编写的代码对于注入服务是正确的:
try {
def ctx = Holders.applicationContext
chatService = ctx.chatService
} catch (Exception e) {
println "e = "+e
}
但是 chatService
没有在您的 class 中的任何地方定义。因此,即使您的 handleOpen
方法被调用,也必须抛出 MissingPropertyException
但由于您已经处理了顶层 Exception
class ( 永远不应该鼓励) handleOpen
方法中的异常被抑制了。
现在,稍后在您的 handleMessage
方法中,同样的问题再次发生 chatService
未定义,因此您得到了您在问题中发布的异常。
所以,您现在知道答案了 :-) 只需在 ServerEndPointDemo
class.
中定义 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
}
我正在尝试创建端点文件。所以我创建了一个名为 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
中从服务调用方法到文件吗?
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"
}
}
所以问题来了。您编写的代码对于注入服务是正确的:
try {
def ctx = Holders.applicationContext
chatService = ctx.chatService
} catch (Exception e) {
println "e = "+e
}
但是 chatService
没有在您的 class 中的任何地方定义。因此,即使您的 handleOpen
方法被调用,也必须抛出 MissingPropertyException
但由于您已经处理了顶层 Exception
class ( 永远不应该鼓励) handleOpen
方法中的异常被抑制了。
现在,稍后在您的 handleMessage
方法中,同样的问题再次发生 chatService
未定义,因此您得到了您在问题中发布的异常。
所以,您现在知道答案了 :-) 只需在 ServerEndPointDemo
class.
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
}