SSH 非web请求是获取不到request对象,加监听器还是不行,求各路大神救救我

Old-Summer 2015-07-28 05:46:06


目前在做微信公众号,需要从系统开启后每隔两小时从腾讯服务器获取一次access_token。所以我就想着在spring容器加载完成后,调用接口请求access_token,然后把它存到request的application里区,方便全局获取统一的token。

但是尝试了好多次,都显示request对象获取不到,说是因为不是web请求没有request对象。之后我根据提示信息,加了一个RequestContextListener监听器。但是还是不起作用。

各路大神一起有没有碰到过这个问题,求指点一下。刚开始整ssh,很多地方不是太明白。犯了什么菜鸟错误还望指出。


web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" metadata-complete="true" version="3.1">
<display-name>rzf</display-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<listener>
<listener-class>com.zhejianglehua.rzf.action.util.GetAccessTokenAction</listener-class>
</listener>
<listener>
<listener-class>com.zhejianglehua.rzf.action.util.AAA</listener-class>
</listener>
<filter>
<filter-name>EcodingFilter</filter-name>
<filter-class>com.zhejianglehua.rzf.filter.EcodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>EcodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/applicationContext.xml</param-value>
</context-param>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>


调用接口的监听器
package com.zhejianglehua.rzf.action.util;

import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpServletRequest;

import org.apache.http.ParseException;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.components.If;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Controller;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.zhejianglehua.rzf.entity.weixin.po.AccessToken;
import com.zhejianglehua.rzf.service.util.WeixinUtilService;

@Namespace("/weixin")
@Controller
public class GetAccessTokenAction implements ApplicationListener<ContextRefreshedEvent> {


private HttpServletRequest request;
private Timer timer =null;

@Autowired
private WeixinUtilService weixinUtilService;

@Autowired
public void setRequest(HttpServletRequest request) {
this.request = request;
}







@Override
public void onApplicationEvent(ContextRefreshedEvent event) {

if(event.getApplicationContext().getParent() == null){
System.out.println("启动定时获取Access Token任务...");

weixinUtilService.fuck();

timer = new Timer(true);

timer.schedule(new TimerTask() {

@Override
public void run() {
try {
AccessToken token = weixinUtilService.getAccessToken();
request.getServletContext().setAttribute("token", token);
} catch (ParseException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, 10000, 5000);// 延迟0s后执行,每55分钟执行一次
}
}
}



报错
信息: Server startup in 7467 ms
Exception in thread "Timer-0" java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131)
at org.springframework.web.context.support.WebApplicationContextUtils.currentRequestAttributes(WebApplicationContextUtils.java:275)
at org.springframework.web.context.support.WebApplicationContextUtils.access$400(WebApplicationContextUtils.java:64)
at org.springframework.web.context.support.WebApplicationContextUtils$RequestObjectFactory.getObject(WebApplicationContextUtils.java:291)
at org.springframework.web.context.support.WebApplicationContextUtils$RequestObjectFactory.getObject(WebApplicationContextUtils.java:286)
at org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler.invoke(AutowireUtils.java:307)
at com.sun.proxy.$Proxy14.getServletContext(Unknown Source)
at com.zhejianglehua.rzf.service.util.WeixinUtilService.getAccessToken(WeixinUtilService.java:227)
at com.zhejianglehua.rzf.action.util.GetAccessTokenAction$1.run(GetAccessTokenAction.java:64)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)



...全文
290 点赞 收藏 13
写回复
13 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
gukuitian 2015-07-29
    at com.zhejianglehua.rzf.service.util.WeixinUtilService.getAccessToken(WeixinUtilService.java:227) 看这行
回复
迷林 2015-07-29
你监听的是servlet的请求 但是逻辑上是能够取到request对象的 你看看是不是你监听器写的有问题 加载的东西不对
回复
小-文 2015-07-29
我不是来解决你这个问题的,但是我觉得还是再用的时候去判断一下是否过期比较好,我之前做微信就是这样的
回复
Old-Summer 2015-07-29
引用 11 楼 gukuitian 的回复:
定时器也没必要,去掉做过微信公众号开发,它的token是有有效时间的,比如我写个类,

public class WeiXinConstant {
	/**
	 * 2个小时之内的值是固定的,不可直接访问,要用方法来获取。
	 */
	private  static String token;
	private static long time;
	public static String getAccessToken(){
		 if(token==null||time<new Date().getTime()){
			 //如果过期了则获取一个新的token
			 token=getToken();
			 time=new Date().getTime()+有效期;
		 }
		 return token; 
	}
}
好主意 ,我试试 ,先谢了
回复
gukuitian 2015-07-29
定时器也没必要,去掉做过微信公众号开发,它的token是有有效时间的,比如我写个类,

public class WeiXinConstant {
	/**
	 * 2个小时之内的值是固定的,不可直接访问,要用方法来获取。
	 */
	private  static String token;
	private static long time;
	public static String getAccessToken(){
		 if(token==null||time<new Date().getTime()){
			 //如果过期了则获取一个新的token
			 token=getToken();
			 time=new Date().getTime()+有效期;
		 }
		 return token; 
	}
}
回复
gukuitian 2015-07-29
你的control是单例的吧? 单例的不能这么注入. 实际我觉得, 你这东西根本没必要扔到request里,直接静态变量就完了.比如 WeiXinConstant.token
回复
迷林 2015-07-29
引用 8 楼 shengwugang 的回复:
[quote=引用 5 楼 wi496481 的回复:] 你监听的是servlet的请求 但是逻辑上是能够取到request对象的 你看看是不是你监听器写的有问题 加载的东西不对
这是web.xml里的三条监听器,顺序有关系么???
 <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
  </listener>
  <listener>
    <listener-class>com.zhejianglehua.rzf.action.util.GetAccessTokenAction</listener-class>
  </listener>
监听器上面也贴出来了,我找不出什么原因[/quote] 线程中的异常“定时器0”java.lang.IllegalStateException:没有线程绑定请求中找到:你是指要求外部属性的实际的网络请求,或处理原接收线程之外的要求?如果你实际上是一个Web请求内运行,仍然收到此消息,您的代码可能运行的DispatcherServlet / DispatcherPortlet时外:在这种情况下,使用RequestContextListener或RequestContextFilter拦截当前请求 这是错误消息,看着这上面改吧 ,希望能帮到你
回复
Old-Summer 2015-07-29
引用 5 楼 wi496481 的回复:
你监听的是servlet的请求 但是逻辑上是能够取到request对象的 你看看是不是你监听器写的有问题 加载的东西不对
这是web.xml里的三条监听器,顺序有关系么???
 <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
  </listener>
  <listener>
    <listener-class>com.zhejianglehua.rzf.action.util.GetAccessTokenAction</listener-class>
  </listener>
监听器上面也贴出来了,我找不出什么原因
回复
Old-Summer 2015-07-29
引用 6 楼 gukuitian 的回复:
    at com.zhejianglehua.rzf.service.util.WeixinUtilService.getAccessToken(WeixinUtilService.java:227) 看这行
抱歉,WeixinUtilService 里原来也加了一句request.getServletContext().setAttribute("token", token);所以报错指向了那里 删除之后

	@Override
	public void onApplicationEvent(ContextRefreshedEvent event) {
		
		if(event.getApplicationContext().getParent() == null){
			System.out.println("启动定时获取Access Token任务...");

			timer = new Timer(true);
			
			timer.schedule(new TimerTask() {
				
				@Override
				public void run() {
					try {
						AccessToken token = weixinUtilService.getAccessToken();
						request.getServletContext().setAttribute("token", token);
					} catch (ParseException | IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}, 10000, 5000);// 延迟0s后执行,每55分钟执行一次
		}
	}
报错如下:
Exception in thread "Timer-0" java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
	at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131)
	at org.springframework.web.context.support.WebApplicationContextUtils.currentRequestAttributes(WebApplicationContextUtils.java:275)
	at org.springframework.web.context.support.WebApplicationContextUtils.access$400(WebApplicationContextUtils.java:64)
	at org.springframework.web.context.support.WebApplicationContextUtils$RequestObjectFactory.getObject(WebApplicationContextUtils.java:291)
	at org.springframework.web.context.support.WebApplicationContextUtils$RequestObjectFactory.getObject(WebApplicationContextUtils.java:286)
	at org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler.invoke(AutowireUtils.java:307)
	at com.sun.proxy.$Proxy14.getServletContext(Unknown Source)
	at com.zhejianglehua.rzf.action.util.GetAccessTokenAction$1.run(GetAccessTokenAction.java:63)
	at java.util.TimerThread.mainLoop(Timer.java:555)
	at java.util.TimerThread.run(Timer.java:505)
回复
Old-Summer 2015-07-28
快来人啊。。。
回复
Old-Summer 2015-07-28
up up up
回复
Old-Summer 2015-07-28
求顶。。。。。
回复
相关推荐
发帖
Web 开发
创建于2007-09-28

8.0w+

社区成员

Java Web 开发
申请成为版主
帖子事件
创建了帖子
2015-07-28 05:46
社区公告
暂无公告