本人自定义一个Action,并且该Action也是WS连接的服务器端点,这个Action需要怎么写呢?ServletActionContext.getContext()和ServletActionContext.getRequest()都是null,怎么回事呢?不在框架里使用,一切正常啊!
源码如下:
源码如下:
<constant name="struts.action.excludePattern" value="/_wsHandler"></constant> package cn.edu.cqupt.sims.web.action; import java.io.IOException; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.atomic.AtomicInteger; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import org.apache.struts2.ServletActionContext; import org.springframework.web.socket.server.standard.SpringConfigurator; import cn.edu.cqupt.sims.domain.Admin; import cn.edu.cqupt.sims.domain.Application4Leave; import cn.edu.cqupt.sims.domain.Student; @ServerEndpoint( value="/_wsHandler", configurator = SpringConfigurator.class) public class WebSocketHandler { private static final AtomicInteger conNum = new AtomicInteger(0); private static final Set<Student> connections = new CopyOnWriteArraySet<Student>(); private static final ConcurrentMap<String,String> map = new ConcurrentHashMap<String,String>(); private Session session; public WebSocketHandler() { } @OnOpen public void start(Session session) { this.session = session; System.out.println(ServletActionContext.getContext()); //null System.out.println(ServletActionContext.getRequest()); //null /* * 麻痹的,是什么原因导致ServletActionContext.getContext()为null的? * */ Map<String,Object> appSession = ServletActionContext.getContext().getSession(); Student student= (Student) appSession.get("stuloginer"); Admin admin= (Admin) appSession.get("admloginer"); if(student != null){ String username=student.getUsername(); String session_id=session.getId(); connections.add(student); map.put(username, session_id); String message = String.format("%s %s", username, "has joined !"); System.out.println(message+" session_id = "+session_id+" current online clients : "+conNum.get()); broadcast(message); } if(admin != null){ String username=admin.getUsername(); String message = String.format("%s %s", username, "has joined !"); System.out.println(message+" current online clients : "+conNum.get()); } } //此时不能用注解修饰该方法啊:@onClose,原因是参数是人为传进去的, //假如注解了该方法将会自动调用,参数就为null喽。 public void end(Student student) { /* * 其实当某一学生客户端离开系统时,就要将其从connnections中删除,但是这一点并不轻松; * 本人是这样做的?当学生离开系统时就会触发onclose()方法,于是在该方法内发送该学生的名字啊, * 服务器端incoming()接收消息并调用end() */ if(student == null){ return; } connections.remove(student); String message = String.format("%s %s", student.getUsername(), "has disconnected !"); System.out.println(message+" current online clients : "+conNum.get()); broadcast(message); } @OnMessage public void incoming(String message) { //message:您有新消息 if(message.equals("您有新消息")){ // 对谁审批就将消息发送给谁 Application4Leave r4l = (Application4Leave)ServletActionContext.getRequest().getSession().getAttribute("ws_send_to"); String nickName = r4l.getUsername(); System.out.println(message); broadcast2SB(nickName,message); } if(! message.equals("您有新消息")) Iterator<Student> it=connections.iterator(); while(it.hasNext()){ Student student=it.next(); if(student.getUsername().equals(message)){ System.out.println(message); end(student); } } } } @OnError public void onError(Throwable t) throws Throwable { System.out.println("Chat Error: \n" + t.getCause()); } // 向全部客户端推动消息 private void broadcast(String msg) { for (Student client : connections) { try { synchronized (client) { System.out.println(this.session.isOpen()); //true or false this.session.getBasicRemote().sendText(msg); } } catch (IOException e) { System.out.println("Chat Error: Failed to send message to client: \n"+e.getMessage()); connections.remove(client); try { this.session.close(); } catch (IOException e1) { e.printStackTrace(); } String message = String.format("%s %s", client.getUsername(), "has been disconnected."); broadcast(message); } } } // 精确地向某一客户端发送消息 // 首先要知道该客户端的登录名,我们根据登录名来精确定位发送······ public void broadcast2SB(String nickName,String msg){ for(Student client : connections){ synchronized(client){ if(client.getUsername().equals(nickName)){ try{ this.session.getBasicRemote().sendText(msg); }catch(IOException e2){ e2.printStackTrace(); } } } } } public String execute(){ return "none"; } }
解决方案
40
你没用到 ServletRequestAware ?
http://stackoverflow.com/questions/7460294/struts2-request-as-null
http://m.oschina.net/blog/107895
http://stackoverflow.com/questions/7460294/struts2-request-as-null
http://m.oschina.net/blog/107895