i'm using restful web service. In that i have a method, by using this method i send notification and mails. My method is working fine, only problem is that notification pops up 2,3 seconds before you get success response after calling this method.
#Override
#Transactional
public MedikmResponse createNPostCcbrQuestion(CreateNPostCcbrQuestionRequest createNPostCcbrQuestionRequest, HttpServletRequest request) {
logger.info("#########################Post Ccbr Question#############################");
MedikmResponse medikmResponse=new MedikmResponse();
try {
String token = request.getHeader("authToken");
User user = userDao.findUserByAuthToken(token);
if (user != null) {
/**
* Question Creation
*/
CcbrQuestion ccbrQuestion=new CcbrQuestion();
ccbrQuestion.setQuestiomtext(createNPostCcbrQuestionRequest.getCcbrQuestionText());
Integer questionId=ccbrQuestionDao.saveCcbrQuestion(ccbrQuestion);
ccbrQuestion.setQuestionId(questionId);
/* ***
* Question post
*/
TbDiscussionForumQuestion tbDiscussionForumQuestion=new TbDiscussionForumQuestion();
tbDiscussionForumQuestion.setCCBRQuestionId(ccbrQuestion);
tbDiscussionForumQuestion.setTBDiscussionId(new TbDiscussionForum(createNPostCcbrQuestionRequest.getTbdiscussionId()));
tbDiscussionForumQuestion.setPhysicianId(new Physician(user.getPhysicianId().getPhysicianId()));
tbDiscussionForumQuestion.setQuestion(createNPostCcbrQuestionRequest.getCcbrQuestionText());
tbDiscussionForumQuestion.setQuestionDate(new Date());
//tbDiscussionForumQuestionDao.saveTbDiscussionForumQuestion(tbDiscussionForumQuestion);
TbDiscussionForum discussionForum=tbDiscussionForumDao.findTbDiscussionForumbyTbId(createNPostCcbrQuestionRequest.getTbdiscussionId());
discussionForum.getTbDiscussionForumQuestionCollection().add(tbDiscussionForumQuestion);
tbDiscussionForumDao.updateTbDiscussionForum(discussionForum);
String[] deviceIdList=getParticpentDeviceIdList(discussionForum.getCaseId().getCaseId(), user);
medikmResponse.setAuthenticationKey(user.getAuthToken());
notificationSender.sendPostedCcbrQuestionToVMDCParticipant(discussionForum.getCaseId(), user.getPhysicianId(), createNPostCcbrQuestionRequest.getCcbrQuestionText());//sending mail
if(deviceIdList.length!=0){
notificationService.sendNotificationToIOS(deviceIdList,discussionForum.getCaseId().getCaseId(),createNPostCcbrQuestionRequest.getTbdiscussionId(),"Question");
}
medikmResponse.setResponseCode(MedikmConstants.SUCCESS_CODE);
medikmResponse.setResponseMessage(MedikmConstants.SUCCESS_MESSAGE);
}else{
medikmResponse.setResponseCode(MedikmConstants.FAILURE_CODE);
medikmResponse.setResponseMessage(MedikmConstants.USER_DOES_NOT_EXIST);
logger.info("############ USER_DOES_NOT_EXIST #############"+ MedikmConstants.USER_DOES_NOT_EXIST);
}
return medikmResponse;
}catch(Exception ex){
ex.printStackTrace();
return null;
}
}
for this i add #Async annotation in the sendNotificationToIOS method and it works for me after adding this annotation need to add in your xml
Related
I am currently working in Enterprise Java and I'm a newbie. I am trying to create a method which should delete a selected item from a data table. My project contains Graphical User Interface elements from "http://www.primefaces.org/showcase/".
The deletion is made through a web-service.
This is the method I created so far:
public boolean delete(String articleId) {
Client client = ClientBuilder.newClient();
WebTarget target
= client.target(DELETE_URL);//this is a String
//TODO call ws method delete
try{
target.request()....;
} catch(Exception ex) {
LOGGER.error("Delete Article Error ", ex);
}
return true;
}
Could you tell me how can I handle the deletion in an appropiate way?
All the best!
In your case the following should do the trick.
target.request().delete(Response.class)
I met an error when hardcode try to logout with shiro.
user do login and logout not through web login/logout url, but backend link.
when login, it works.
Subject currentUser = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(request.getParameter("username"), request.getParameter("password"));
token.setRememberMe(true);
try {
currentUser.login(token);
} catch (AuthenticationException e) {
e.printStackTrace();
}
but when i try to logout, with error:
public void userLogout(String sessionId){
SecurityManager securityManager = SecurityUtils.getSecurityManager();
Subject.Builder builder = new Subject.Builder(securityManager);
builder.sessionId(sessionId);
Subject subject = builder.buildSubject();
if (null != subject) {
try {
subject.logout();
} catch (SessionException e) {
// TODO: handle exception
}
}
}
but met error [org.apache.shiro.session.UnknownSessionException: There is no session with id , then how to manually colse a shiro session?
You shouldn't try to recreate the session and then operate it, you should get the session via the security manager, using the thread the user was logged into, like so:
SecurityUtils.getSubject().logout();
If you somehow want to call logout from a different thread, you can use the SessionDAO interface, but you need to do extra configuration to have shiro use a SessionDAO as described here:
http://shiro.apache.org/session-management.html#SessionManagement-SessionStorage
When you have configured it correctly you can do stuff like:
DefaultSecurityManager securityManager = (DefaultSecurityManager) SecurityUtils.getSecurityManager();
DefaultSessionManager sessionManager = (DefaultSessionManager) securityManager.getSessionManager();
Collection<Session> activeSessions = sessionManager.getSessionDAO().getActiveSessions();
for (Session session: activeSessions){
if (sessionId.equals(session.getId()){
session.stop();
}
}
Hi I have been unable to solve the following problem in Wicket 6.*:
In our webapp we are using wicket-auth-roles to manage authentication/authorization. When session expires, user should be redirected to a page set by getApplicationSettings().setPageExpiredErrorPage(SomePage.class) on his next action. However, if the user tries to access a page which doesn't allow guests, he is redirected to a login page skipping the PageExpiredPage altogether.
My question is - how can I display "Session has expired." message to the user?
Among other things, I have tried session.info("message") during onInvalidate phase of session's lifecycle, however the feedback message is then rendered on the first page after login (not on the login page).
Thank you for your anwsers.
You could use a RequestCycleListener to record when a PageExpiredException is thrown.
public class ExceptionMapperListener extends AbstractRequestCycleListener {
#Override
public IRequestHandler onException(RequestCycle cycle, Exception ex) {
if (ex instanceof PageExpiredException) {
// Record in session or request cycle
// OR
// Create a RenderPageRequestHandler yourself and add a page parameter
// See DefaultExceptionMapper#internalMap(Exception)
}
return null;
}
}
// In Application#init():
getRequestCycleListeners().add(new ExceptionMapperListener());
ORINAL ANSWER
(kept because it could still help...)
I haven't tried it myself since I don't use wicket-auth-roles, but try overriding the method AuthenticatedWebApplication#restartResponseAtSignInPage() with something like this:
if (isSessionExpired()) {
PageParameters params = new PageParameters();
params.add("showSessionExpired", true);
throw new RestartResponseAtInterceptPageException(getSignInPageClass(), params);
} else {
throw new RestartResponseAtInterceptPageException(getSignInPageClass());
}
And then in the SignInPageClass, display the desired message if the showSessionExpired page parameter is present.
I'm not sure how you implement isSessionExpired(), but you seem to have that part already covered.
OR
Depending on how you implemented isSessionExpired(), maybe you could do the following in your SignInPageClass:
if (sessionExpired()) {
session.info("message")
}
After bernie put me on the right path, I eventually figured out a solution to the problem:
First it is required to override RequestCycleListener:
public class SessionExpiredListener extends AbstractRequestCycleListener {
public void onRequestHandlerResolved(RequestCycle cycle, IRequestHandler handler) {
if (handler instanceof IPageRequestHandler) {
IPageRequestHandler pageHandler = (IPageRequestHandler) handler;
HttpServletRequest request = (HttpServletRequest) cycle.getRequest().getContainerRequest();
//check whether the requested session has expired
boolean expired = request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid();
//check whether the requested page can be instantiated with the current session
boolean authorized = Session.get().getAuthorizationStrategy().isInstantiationAuthorized(pageHandler.getPageClass());
if (expired && !authorized) {
throw new PageExpiredException("Session has expired!");
}
}
super.onRequestHandlerResolved(cycle, handler);
}
}
Check for authorized prevents the session-expired message from displaying on log-out or when accessing unprotected pages.
Finally, you must register your listener and PageRequestHandlerTracker in your WebApplication:
getRequestCycleListeners().add(new SessionExpiredListener());
getRequestCycleListeners().add(new PageRequestHandlerTracker());
In my WebApi code, I raise a HttpResponseException which short-circuits the request pipeline and generates a valid Http response. However, I'm trying to integrate webApi with elmah logging, yet the HttpResponseExeptions aren't showing up.
I have the web.config set-up for elmah and have the following code:
In Global.asx.cs:
static void ConfigureWebApi(HttpConfiguration config)
{
config.Filters.Add(new ServiceLayerExceptionFilter());
config.Filters.Add(new ElmahHandledErrorLoggerFilter());
config.DependencyResolver = new WebApiDependencyResolver(ObjectFactory.Container);
}
Filter:
public class ElmahHandledErrorLoggerFilter : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
base.OnException(actionExecutedContext);
ErrorSignal.FromCurrentContext().Raise(actionExecutedContext.Exception);
}
}
Code where exception is raised:
public Task<FileUpModel> UploadFile()
{
if (Request.Content.IsMimeMultipartContent())
{
var provider = new TolMobileFormDataStreamProvider("C:\images\");
var task = Request.Content.ReadAsMultipartAsync(provider).ContinueWith(
t =>
{
if (t.IsFaulted || t.IsCanceled)
throw new HttpResponseException(HttpStatusCode.InternalServerError);
var fileInfo = provider.FileData.FirstOrDefault();
if (fileInfo == null)
// the exception here isn't logged by Elmah?!
throw new HttpResponseException(HttpStatusCode.InternalServerError);
var uploadModel = new FileUpModel { success = true };
return uploadModel;
});
return task;
}
else
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted"));
}
}
Can anyone who has implemented this before let me know what I'm doing wrong?
As mentioned above, the Elmah filter does not catch and log anything when you raise a HttpResponseException. More specifically, if the following syntax is used:
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, "It was a bad request");
or
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "HttpResponseException - This request is not properly formatted"));
I wanted to trap and log an error in both cases. The way to do it is to use an "ActionFilterAttribute", override "OnActionExecuted", and check actionExecutedContext.Response.IsSuccessStatusCode.
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
// when actionExecutedContext.Response is null, the error will be caught and logged by the Elmah filter
if ((actionExecutedContext.Response != null) && !actionExecutedContext.Response.IsSuccessStatusCode)
{
try
{
var messages = (System.Web.Http.HttpError)((System.Net.Http.ObjectContent<System.Web.Http.HttpError>)actionExecutedContext.Response.Content).Value;
StringBuilder stringBuilder = new StringBuilder();
foreach (var keyValuePair in messages) {
stringBuilder.AppendLine("Message: Key - " + keyValuePair.Key + ", Value - " + keyValuePair.Value);
}
Elmah.ErrorSignal.FromCurrentContext().Raise(new Exception("Web API Failed Status Code returned - " + stringBuilder.ToString()));
}
catch (Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(new Exception("Error in OnActionExecuted - " + ex.ToString()));
}
}
}
On a side note, I also overwrote "OnActionExecuting" to validate the model state. This allowed me to remove all of the checks within my actions.
public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
{
if (actionContext.ModelState != null && !actionContext.ModelState.IsValid)
{
StringBuilder stringBuilder = new StringBuilder();
foreach (var obj in actionContext.ModelState.Values)
{
foreach (var error in obj.Errors)
{
if(!string.IsNullOrEmpty(error.ErrorMessage)) {
stringBuilder.AppendLine("Error: " + error.ErrorMessage);
}
}
}
Elmah.ErrorSignal.FromCurrentContext().Raise(new Exception("Invalid Model State -- " + stringBuilder.ToString()));
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);
}
}
Of course, you will need to add the filter using "config.Filters.Add".
Web API special cases HttpResponseException thrown in action and converts into HttpResponseMessage and hence you are not seeing your exception filter getting invoked.
This is not true in the case of throwing HttpResponseException from filters. However, ideally one need not throw HttpResponseException from filters as you could short-circuit a request by setting the Response property on the supplied input context.
You need to turn on Elmah for HttpFilters in order to get this to work as you expect for WebApi.
Use Elmah.Contrib.WebApi available as a NuGet Package, it will wire include a class that you can then wire up following the instructions on the Elmah.Contrib.WebApi project site.
If you want to do this yourself, Capturing Unhandled Exceptions in ASP.NET Web API's with ELMAH walks you through what the Elmah.Contrib.WebApi is doing for you.
Additionally, I had to change the way that the error response is thrown for it to be picked by Elmah to:
throw new HttpException((int)HttpStatusCode.NotAcceptable, "This request is not properly formatted");
I would also recommend the use of the Elmah.MVC NuGet Package.
I try to get my code working with catching certain errors. I store the token for a user after he or she grants permission to my app (this is a WP7 app). When I try to post on the wall by using the stored token it works. When I remove the permissions on facebook it throws an OAuthException. I can't catch it it seems. My app just crashes. This is the code I used:
private object PostToFacebook()
{
_fbApp = new FacebookClient(_appsettings.faceBookToken);
FacebookAsyncCallback callback = new FacebookAsyncCallback(this.postResult);
var parameters = new Dictionary<string, object>();
parameters.Add("message", "message on wall");
try
{
_fbApp.PostAsync("me/feed", parameters, callback);
}
catch (Exception ex)
{
}
return null;
}
private void postResult(FacebookAsyncResult asyncResult)
{
if (asyncResult.Error == null)
{
status = "succes";
}
else
{
status = "error" + asyncResult.Error.Message;
}
}
The try catch doesn't catch anything and the generic exception handler in my app.xaml.cs either.
Any ideas how to catch this error so I can ask the user to authenticate again?
Put your try..catch in the callback.
You can also catch exceptions globally by handling the UnhandledException event on the App object.