我有一段时间试图找出NHibernate中的会话管理问题.我假设我的很多麻烦都是由于缺乏对IoC和AOP概念的了解; 至少那是我在思考Fabio Maulo指导我的地方.
无论如何,我的问题是我有一个win表单应用程序正在进行"get"调用并将结果绑定到网格.在绑定之后,用户可以执行某种"写入"动作,并且这些动作导致在写入之后会话被关闭以尝试使用每次使用会话的概念.然后用户可以滚动网格,这导致延迟加载开始,现在会话已经关闭,我得到一个例外.
我不想让我的观点认识到我的会话,我不想在用户关闭表单时发送KillAllSessions.此外,用户可以在任何给定时间打开多个表单,从而进一步加剧与该方法相关的问题.我基本上希望所有这些都能在"幕后"工作.
所以到目前为止我的想法是拦截延迟加载调用并检查会话是否打开,如果没有重新打开它,获取信息然后重新关闭它.但是,据我所知,这并不多,这本质上就是延迟加载的工作原理.它被代理工厂(NHibernate.Bytecode.Castle)拦截,然后使用会话检索数据.所以我需要实际拦截该调用,然后在重新打开会话后将其传递给原始的预期拦截.这就是我的想法.
我的问题基本上首先是这个甚至是正确的方法吗?第二,如果它是我甚至不知道从哪里开始.我从未对方法调用进行任何拦截,我在理论上知道但在实践中却没有.我知道有些图书馆可以做Rhino Commons这样的事情,但我想利用这个机会学习并成为一名更好的程序员.我正在尝试理解AOP和Context Bound Objects,但目前我并没有理解它.你们有些人可以帮助一个人吗?
我想修改一个传出的SOAP请求.我想从信封的主体中删除2个xml节点.我设法建立一个Interceptor并将生成的消息集的String值获取到端点.
但是,以下代码似乎不起作用,因为未按预期编辑传出消息.有没有人有关于如何做到这一点的一些代码或想法?
public class MyOutInterceptor extends AbstractSoapInterceptor {
public MyOutInterceptor() {
super(Phase.SEND);
}
public void handleMessage(SoapMessage message) throws Fault {
// Get message content for dirty editing...
StringWriter writer = new StringWriter();
CachedOutputStream cos = (CachedOutputStream)message.getContent(OutputStream.class);
InputStream inputStream = cos.getInputStream();
IOUtils.copy(inputStream, writer, "UTF-8");
String content = writer.toString();
// remove the substrings from envelope...
content = content.replace("<idJustification>0</idJustification>", "");
content = content.replace("<indicRdv>false</indicRdv>", "");
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
outputStream.write(content.getBytes(Charset.forName("UTF-8")));
message.setContent(OutputStream.class, outputStream);
}
Run Code Online (Sandbox Code Playgroud) 我是AngularJS的新手,现在花了3天时间找到处理401状态的方法.我尝试过使用$ http的拦截器,使用$ resource ...但没有任何工作.我的应用程序在同一台服务器上调用JSONP调用.当发生错误时,它会被错误回调函数捕获.但状态始终为0且响应未定义.
首先,我尝试了这个拦截器
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.responseInterceptors.push(['$q', function($q) {
return function(promise) {
return promise.then(function(response) {
console.log('success in interceptor');
return response;
}, function(response) {
console.log('error in interceptor');
console.log(response);
if (response.status === 401) {
response.data = {
status: false,
description: 'Authentication required!'
};
return response;
}
return $q.reject(response);
});
}
}]);
}]);
Run Code Online (Sandbox Code Playgroud)
其次,还尝试使用$ resource的控制器
$scope.fetchData = function(fromDate, toDate){
Cancel.get({from: fromDate, to: toDate, perPage: 99999},
function(data){
$scope.cancels = $scope.filteredCancels = data.data;
$scope.search();
},
function(response) {
$scope.errorMessage = '<h4>Error : '+response.status+'</h4>';
window.location …
Run Code Online (Sandbox Code Playgroud) 我有几个控制器使用@ResponseBody注释返回相同的通用Response对象,如下所示:
@RequestMapping(value = "/status", method = RequestMethod.GET)
@Transactional(readOnly = true)
public @ResponseBody Response<StatusVM> status()
Run Code Online (Sandbox Code Playgroud)
在返回Response之后,我需要在每个控制器上执行操作.此操作将使用新数据丰富Response对象.
我不想重复代码,所以我需要单点干预.我认为我可以用拦截器做到这一点,但是,根据文档http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-handlermapping-interceptor这样做与@ResponseBody不协调:
请注意,HandlerInterceptor的postHandle方法并不总是非常适合与@ResponseBody和ResponseEntity方法一起使用.在这种情况下,HttpMessageConverter在调用postHandle之前写入并提交响应,这使得无法更改响应,例如添加标头.相反,应用程序可以实现ResponseBodyAdvice并将其声明为@ControllerAdvice bean或直接在RequestMappingHandlerAdapter上配置它.
我无法找到这个技术的例子,有人可以帮助我吗?
作为替代方案,我可以使用方面,但是我需要注释每个控制器,这是我想要避免的.
我写了一个这样的例子
简单计算器类:
public class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
}
Run Code Online (Sandbox Code Playgroud)
实现了DynamicProxy提供的"IInterceptor"
[Serializable]
public abstract class Interceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
ExecuteBefore(invocation);
invocation.Proceed();
ExecuteAfter(invocation);
}
protected abstract void ExecuteAfter(IInvocation invocation);
protected abstract void ExecuteBefore(IInvocation invocation);
}
Run Code Online (Sandbox Code Playgroud)
创建了一个Interceptor类,并继承自"Interceptor"类
public class CalculatorInterceptor : Interceptor
{
protected override void ExecuteBefore(Castle.DynamicProxy.IInvocation invocation)
{
Console.WriteLine("Start");
}
protected override void ExecuteAfter(Castle.DynamicProxy.IInvocation invocation)
{
Console.WriteLine("End");
}
}
Run Code Online (Sandbox Code Playgroud)
但是当我用它不工作!
static void Main(string[] args)
{
ProxyGenerator generator …
Run Code Online (Sandbox Code Playgroud) c# castle-dynamicproxy dynamic-proxy interceptor interception
我的Java EE 6应用程序由war文件和ejb模块组成,包含在ear文件中.我正在使用CDI for DI(即我在两个模块中都有一个beans.xml文件).我想使用war模块中的ejb模块中定义的日志拦截器.我在ejb的beans.xml中启用了拦截器:
<beans>
<interceptors>
<class>com.test.interceptor.LoggingInterceptor</class>
</interceptors>
</beans>
Run Code Online (Sandbox Code Playgroud)
这仅适用于使用ejb模块中的拦截器注释的类.战争模块中的类不被截获(尽管它们也被拦截器注释).我认为解决方案是在战争的拦截器中启用拦截器(如上所述).但是无法使用以下消息部署应用程序:
严重:加载应用程序时出现异常:WELD-001417启用拦截器类类com.test.interceptor.LoggingInterceptor既没有注释@Interceptor也没有通过可移植扩展注册
我的LoggingInterceptor看起来像这样:
@Log
@Interceptor
public class LoggingInterceptor {
private static final Logger logger = Logger.getLogger(LoggingInterceptor.class.getName());
static {
logger.setLevel(Level.ALL);
}
@AroundInvoke
public Object logMethod(InvocationContext ctx) throws Exception {
logger.log(Level.FINE, "ENTRY {0} {1}",
new Object[]{ ctx.getTarget().getClass().getName(), ctx.getMethod().getName() });
long startTime = System.nanoTime();
try {
return ctx.proceed();
} finally {
long diffTime = System.nanoTime() - startTime;
logger.log(Level.FINE, "RETURN {0} {1}",
new Object[]{ ctx.getTarget().getClass().getName(), ctx.getMethod().getName() });
logger.log(Level.FINE, "{0} took {1} ms", …
Run Code Online (Sandbox Code Playgroud) 我必须在Apache CXF客户端中设置一些http头字段:
我通过拦截器尝试过:
public class HttpHeaderInterceptor extends AbstractPhaseInterceptor<Message> {
private String userId;
private String xAuthorizeRoles;
private String host;
public HttpHeaderInterceptor() {
super(Phase.POST_PROTOCOL);
}
@Override
public void handleMessage(Message message) throws Fault {
Map<String, List> headers = (Map<String, List>) message.get(Message.PROTOCOL_HEADERS);
try {
System.out.println("HttpHeaderInterceptor Host: " + host + " UserId: " + userId + " X-AUTHORIZE-roles: " + xAuthorizeRoles);
headers.put("Host", Collections.singletonList(host));
headers.put("UserId", Collections.singletonList(userId));
headers.put("X-AUTHORIZE-roles", Collections.singletonList(xAuthorizeRoles));
} catch (Exception ce) {
throw new Fault(ce);
}
}
public void setUserId(String userId) {
this.userId = …
Run Code Online (Sandbox Code Playgroud) 我正在使用ES6类构建AngularJS应用程序,并将跟踪器转换为AMD格式的ES5.
在我的模块中,我导入拦截器类并将其注册为服务,然后使用module.config中的$ httpProvider.interceptors注册此服务:
var commonModule = angular.module(moduleName, [constants.name]);
import authenticationInterceptor from './authentication/authentication.interceptor';
commonModule.service('authenticationInterceptor', authenticationInterceptor);
commonModule.config( $httpProvider => {
$httpProvider.interceptors.push('authenticationInterceptor');
});
Run Code Online (Sandbox Code Playgroud)
我的拦截器类注入$ q和$ window服务,将它们保存在构造函数中供以后使用.我使用调试器跟踪了这一部分并正确地进行了注入:
'use strict';
/*jshint esnext: true */
var authenticationInterceptor = class AuthenticationInterceptor {
/* ngInject */
constructor($q, $window) {
this.$q = $q;
this.$window = $window;
}
responseError(rejection) {
var authToken = rejection.config.headers.Authorization;
if (rejection.status === 401 && !authToken) {
let authentication_url = rejection.data.errors[0].data.authenticationUrl;
this.$window.location.replace(authentication_url);
return this.$q.defer(rejection);
}
return this.$q.reject(rejections);
}
}
authenticationInterceptor.$inject = ['$q', …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用此拦截器进行身份验证:
public class CustomInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
// try the request
Response response = chain.proceed(request);
if (response shows expired token) {
// get a new token (I use a synchronous Retrofit call)
// create a new request and modify it accordingly using the new token
Request newRequest = request.newBuilder()...build();
// retry the request
return chain.proceed(newRequest);
}
// otherwise just pass the original response on
return response;
}
Run Code Online (Sandbox Code Playgroud)
问题是我的检查(响应显示过期令牌)与状态无关,我需要检查实际响应(正文内容).因此,在检查之后,响应被"消耗"并且任何准备身体的尝试都将失败. …
我想拦截401和其他错误,以便做出相应的反应.这是我的拦截器:
import { LoggingService } from './../logging/logging.service';
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpHandler, HttpRequest, HttpEvent, HttpResponse, HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';
@Injectable()
export class TwsHttpInterceptor implements HttpInterceptor {
constructor(private logger: LoggingService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.logger.logDebug(request);
return next.handle(request)
.do(event => {
if (event instanceof HttpResponse) {
this.logger.logDebug(event);
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
虽然这适用于200个请求,但它不会拦截错误响应
我在chrome的开发控制台中看到的只有:
zone.js:2616 GET http:// localhost:8080/backend/rest/wrongurl 404(Not Found)
或这个
zone.js:2616 GET …
interceptor ×10
angularjs ×2
c# ×2
cxf ×2
android ×1
angular ×1
apache ×1
callback ×1
cdi ×1
controller ×1
ecmascript-6 ×1
ejb-3.1 ×1
gulp-traceur ×1
header ×1
interception ×1
java ×1
java-ee ×1
json ×1
jsonp ×1
lazy-loading ×1
nhibernate ×1
okhttp ×1
response ×1
session ×1
spring-mvc ×1
traceur ×1
unauthorized ×1
web-services ×1