2011-08-15 18 views
15

Tôi gặp vấn đề với Phiên Grails. Tôi đã suy nghĩ về việc có một lớp dịch vụ để xử lý phiên của tôi. Vì vậy, tôi đã tạo một lớp có tên là "SessionService" (dưới grails-app/services/grails /).Grails nhận Phiên và Quản lý trong lớp Dịch vụ

class SessionService { 
    static transactional = true 
    GrailsWebRequest request = RequestContextHolder.currentRequestAttributes() 
    GrailsHttpSession session = request.session 

    def setTestvar(String value) { 
     if (session != null) 
      session.setAttribute("sTeststring", value) 
    } 

    def getTestvar() { 
     if (session != null) 
      session.getAttribute("sTeststring") 
    } 
} 

Vấn đề là bây giờ, mà tôi nhận được một Nullpointer-Ngoại lệ:. "Phương pháp ném ngoại lệ 'java.lang.NullPointerException' Không thể đánh giá org.codehaus.groovy.grails.web.servlet.mvc.GrailsHttpSession .ToString() ".

Cách sử dụng Lớp dịch vụ của tôi, ví dụ: trong Bộ điều khiển:

class SampleController { 

    SessionService sessionService 

    def selectAnything = { 

     sessionService.setTestvar("test-value") 
     render(view: "testview") 
    } 
} 

Tôi đang làm gì sai ở đây? Có đúng không? Hay tôi phải đặt "session = request.session" trong mọi phương thức?

Hy vọng nhận trợ giúp từ bạn.

Cảm ơn bạn rất nhiều trước.

Chúc mừng,

Marco

Trả lời

31

Bạn phải làm một cái gì đó giống như

def session = RequestContextHolder.currentRequestAttributes().getSession() 

trong mọi phương pháp của dịch vụ. Nhưng nó không rõ ràng với tôi, tại sao bạn cần một dịch vụ như vậy. Bạn allways có thể truy cập phiên làm việc trong điều khiển của bạn như thế này ...

session.someAttribute = "someValue" 

Christian

+1

Xin chào Christian, cảm ơn. Nhưng không có phương thức "getSession()" trên currentRequestAttributes. Thực hiện "Thao tác phiên (thiết lập/nhận)" trực tiếp có thể dễ xảy ra lỗi, tôi muốn tránh việc đặt tên biến phiên và xử lý ở một nơi ;-) – grailsInvas0r

+0

Làm cách nào bạn kiểm tra xem getSession() có sẵn không? Tôi đã thử mã trong bảng điều khiển grails và nó hoạt động. – user852518

+1

Ồ tôi phải xin lỗi, nó hoạt động. NHƯNG IntelliJ của tôi nhấn mạnh rằng phương pháp này không tồn tại: -O Cũng trong mọi tài liệu, nó không có sẵn. Chỉ các kết quả google OLD mới hiển thị giải pháp này. Tôi không chắc liệu điều này có hiệu quả trong tương lai không ?! Tôi ngạc nhiên: -O Giải pháp của tôi bây giờ là: ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes(); trả về servletRequestAttributes.getRequest(). GetSession (true); – grailsInvas0r

17

Dưới đây là một số mẫu mã nơi tôi kéo dữ liệu phiên và dữ liệu yêu cầu từ một dịch vụ mà không đi qua các yêu cầu hoặc phiên các đối tượng như một tham số cho dịch vụ.

package beecomplete 

import org.codehaus.groovy.grails.web.util.WebUtils 

class HelperService { 

    public User getCurrentUser() { 
     def webUtils = WebUtils.retrieveGrailsWebRequest() 
     return User.findById(webUtils.getSession().userid) 
    } 

    public Object getModelAttribute(String key) { 

     def webUtils = WebUtils.retrieveGrailsWebRequest() 
     return webUtils.getCurrentRequest().getAttribute(key) 
    } 
} 
+2

'WebUtils.retrieveGrailsWebRequest(). session' là một giải pháp tuyệt vời thanh lịch. – tzrlk

+1

Cảm ơn, hoạt động hoàn hảo. –

+0

Tuyệt vời! Làm cách nào để bạn khám phá lớp WebUtils? – Mauro

9

Đối với phiên bản mới (> 2.2) của Grails:

import org.codehaus.groovy.grails.web.util.WebUtils 

.... 
HttpServletRequest request = WebUtils.retrieveGrailsWebRequest().currentRequest 
HttpSession session = request.session 
0

Trong các phiên bản sau (thử nghiệm trong Grails 2.5.0) bạn chỉ có thể làm getSession (true) trực tiếp từ một dịch vụ:

def myServiceMethod() { 
    def session = getSession(true) 
    ... 
}