The HttpRequest Object

本文介绍了HttpRequest对象,它可实现客户端与服务器的通信。文中说明了在IE 5.0中用JavaScript和VBScript创建该对象的代码,还阐述了如何用其从服务器获取XML文件、向服务器ASP页面发送XML文档,同时指出Microsoft XMLHTTP对象存在只能在浏览器运行的问题。

http://www.w3schools.com/dom/dom_http.asp

The HttpRequest object provides client-side communication with a server.

The HttpRequest object

With the httpRequest object you can send a request from the client to the server.

If you are using JavaScript in IE 5.0, you can create the httpRequest object with the following code:

var xmlHTTP = new ActiveXObject("Microsoft.XMLHTTP")

If you are using VBScript you create the httpRequest object with the following code:

set xmlHTTP = CreateObject("Microsoft.XMLHTTP")

The httpRequest object is not a part of the W3C DOM standard.


Get XML

How to get an xml file from the server using the httpRequest object (works only in IE):

var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP") xmlHttp.open("GET", "note.xml", false) xmlHttp.send() xmlDoc=xmlHttp.responseText

Try it Yourself

Netscape compatible code:

xmlHttp = new XMLHttpRequest(); xmlHttp.open("GET", "note.xml", false); xmlHttp.send(null); xmlDoc = xmlHttp.responseText;

Try it Yourself


Send XML

You can also send an xml document to an ASP page on the server, analyze the request, and send back the result.

var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP") xmlHttp.open("POST", "demo_dom_http.asp", false) xmlHttp.send(xmlDoc) document.write(xmlHttp.responseText)

The ASP page, written in VBScript:

set xmldoc = Server.CreateObject("Microsoft.XMLDOM") xmldoc.async=false xmldoc.load(request) for each x in xmldoc.documentElement.childNodes if x.NodeName = "to" then name=x.text next response.write(name)

You send the result back to the client using the response.write property.

Try it Yourself


Important Note

At the moment, the Microsoft XMLHTTP object can only be run in the BROWSER.

SERVER code that attempts to use the XMLHTTP to communicate with other Web servers, may function incorrectly or perform poorly.

This is a bug in the HTTPRequest object. For more information read Microsoft's Knowledge Base article Q237906.

The rumor is that Microsoft will have this bug fixed in an upcoming release of the XML Library. In the meantime, you may have to use a commercially available ASPHTTP component.


The httpRequest Properties

PropertyDescription
readyStateReturns the state of the document
responseBodyReturns the response as an array of unsigned bytes
responseStreamReturns the response as an IStream
responseTextReturns the response as a string
responseXMLReturns the response as an xml document
statusReturns the status code as a number
statusTextReturns the status as a string

The httpRequest Methods

PropertyDescription
abort()Cancel the current http request
getAllResponseHeaders()Returns the value of the http headers
getResponseHeader(headerName)Returns the value of one specified http header
open(method, url, async, userid, password)Opens http request, and specifies the information
send()Send the http request to the server
setRequestHeader(headerName,headerValue)Specifies the name

<think>我们遇到了一个错误:`Cannot override the final method from AbstractFilter`。 这是因为在Shiro的过滤器体系中,`AbstractFilter`类中有一个`init`方法被声明为`final`,因此我们不能覆盖它。 在之前的代码中,我们尝试重写`init(FilterConfig)`方法,但这个方法在父类中可能是`final`的。 解决方案: 1. 我们可以使用`@PostConstruct`注解的方法,但要注意,在Filter中直接使用`@PostConstruct`可能无法获取到Spring上下文,因为Filter不是由Spring容器管理的(除非使用Spring的DelegatingFilterProxy)。 2. 或者,我们可以通过其他方式初始化Bean,比如在构造方法中,但是构造方法中可能还没有ServletContext。 因此,我们需要调整: 由于我们继承了`AccessControlFilter`(它继承了`PathMatchingFilter`,再继承`AdviceFilter`,最后继承`AbstractFilter`),而`AbstractFilter`中的`init`方法是`final`的,所以我们不能覆盖它。 但是,我们可以覆盖`onFilterConfigSet`方法,该方法在`AbstractFilter`的`init`方法中被调用,当FilterConfig设置后就会调用这个方法。 另外,我们也可以选择使用`@PostConstruct`,但需要确保该Filter是由Spring管理的。如果使用Spring Boot,通常我们会将Filter注册为Spring Bean,然后使用`DelegatingFilterProxy`。 这里我们采用覆盖`onFilterConfigSet`的方法: 修改后的代码:</think>根据您遇到的错误 `Cannot override the final method from AbstractFilter`,这是因为 Shiro 的 `AbstractFilter` 类中 `init()` 方法被声明为 `final`,不能直接覆盖。以下是修正后的解决方案: ```java import org.apache.shiro.web.filter.AccessControlFilter; import org.springframework.context.ApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; import javax.servlet.FilterConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; public class OAuth2Filter extends AccessControlFilter { private ShiroService shiroService; private JwtUtils jwtUtils; // 使用Shiro提供的初始化扩展点 @Override public void onFilterConfigSet(FilterConfig filterConfig) throws Exception { super.onFilterConfigSet(filterConfig); initBeans(filterConfig); } private void initBeans(FilterConfig filterConfig) { ServletContext servletContext = filterConfig.getServletContext(); ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext); this.shiroService = ctx.getBean(ShiroService.class); this.jwtUtils = ctx.getBean(JwtUtils.class); } @Override protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { // 获取并验证JWT令牌 String token = getTokenFromRequest(request); if (token == null || !jwtUtils.validateToken(token)) { return false; } // 创建Shiro主体 try { UsernamePasswordToken shiroToken = createShiroToken(token); getSubject(request, response).login(shiroToken); return true; } catch (AuthenticationException e) { return false; } } private String getTokenFromRequest(ServletRequest request) { HttpServletRequest httpRequest = (HttpServletRequest) request; String authHeader = httpRequest.getHeader("Authorization"); if (authHeader != null && authHeader.startsWith("Bearer ")) { return authHeader.substring(7); } return null; } private UsernamePasswordToken createShiroToken(String jwtToken) { // 从JWT中提取用户名 String username = jwtUtils.extractUsername(jwtToken); return new UsernamePasswordToken(username, jwtToken); } @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { HttpServletResponse httpResponse = (HttpServletResponse) response; httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED); httpResponse.getWriter().write("{\"error\": \"Unauthorized\"}"); return false; } } ``` ### 关键修改说明: 1. **解决 final 方法问题**: - 使用 `onFilterConfigSet()` 替代 `init()` 方法 - 这是 Shiro 提供的专门用于自定义初始化的扩展点 - 在父类的 `init()` 方法中被调用,确保正确的初始化顺序 2. **JWT 验证流程优化**: - 添加了 `getTokenFromRequest()` 方法从请求头提取令牌 - 创建了 `createShiroToken()` 方法将 JWT 转换为 Shiro 可识别的令牌 - 在 `isAccessAllowed()` 中完成完整的认证流程 3. **错误处理增强**: - 在 `onAccessDenied()` 中添加了 JSON 格式的错误响应 - 返回标准的 HTTP 401 状态码 ### 推荐集成方式(Spring Boot 配置): ```java @Configuration public class ShiroConfig { @Bean public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager, OAuth2Filter oauth2Filter) { ShiroFilterFactoryBean factory = new ShiroFilterFactoryBean(); factory.setSecurityManager(securityManager); // 添加自定义过滤器 Map<String, Filter> filters = new LinkedHashMap<>(); filters.put("oauth2", oauth2Filter); factory.setFilters(filters); // 配置保护规则 Map<String, String> filterChainMap = new LinkedHashMap<>(); filterChainMap.put("/api/**", "oauth2"); // 保护所有API端点 filterChainMap.put("/**", "anon"); // 其他路径允许匿名访问 factory.setFilterChainDefinitionMap(filterChainMap); return factory; } @Bean public OAuth2Filter oauth2Filter(ShiroService shiroService, JwtUtils jwtUtils) { return new OAuth2Filter(shiroService, jwtUtils); } } ``` ### 最佳实践建议: 1. **令牌刷新机制**: ```java protected boolean isAccessAllowed(...) { if (jwtUtils.isTokenExpiringSoon(token)) { String newToken = jwtUtils.refreshToken(token); ((HttpServletResponse) response).setHeader("X-New-Token", newToken); } // ... 原有验证逻辑 } ``` 2. **权限验证扩展**: ```java @Override protected boolean isAccessAllowed(...) { // ... 认证逻辑 // 权限验证 String requestURI = WebUtils.toHttp(request).getRequestURI(); return shiroService.checkPermission(subject, requestURI); } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值