JSF 1.2 - How to pass huge data between JSF applications - jsf-1.2

I have two JSF 1.2 applications running in the same weblogic server: App1.war & App2.war I have a requirement to call a jsf page in App2 from App1 page say, page3.xhtml. After entering the values in all the pages of App2 the control should come back to App1 page3.xhtml and I should be able to use the data entered in App2 pages.
I am able to call App2 jsf page from App1 using ExternalContext.redirect() method. But the problem that I am having is I am not able to access the managed session bean from other application? Since the data is huge I cannot also pass it as a GET request. I can only create a xml data with all the page values and try to transfer using HTTPSession but that is not working. Below is the code that I am using in App1
FacesContext facesContext = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession) facesContext.getExternalContext().getSession(false);
session.setAttribute("xml", xml);
ExternalContext externalContext = facesContext .getExternalContext();
externalContext.redirect(url);
And in App2
HttpSession session = request.getSession(false);
session.getAttribute("xml"); ----> Returns null
How to pass huge data between JSF applications?

Related

ServletUriComponentsBuilder.fromRequest return http scheme instead of https

I have a web application composed by frontend code that invokes the same api implemented by two backend modules. This api returns a url in a JSON object. The backend modules are both written with spring mvc but in different versions.
The url-building is the same and it is something like this:
#GetMapping(path = "/app1/menu", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public JsonObject getMenu(HttpServletRequest req) throws IOException {
JsonObject menu = new JsonObject();
menu.addProperty("href", ServletUriComponentsBuilder.fromRequest(req)
.replacePath(req.getContextPath())
.path("/index.html")
.toUriString());
return menu;
}
As you can see this code simply adds a constant to the incoming request and returns it.
The first app uses spring mvc 4 (4.3.5.RELEASE precisely).
The second module uses the 5.1.4.RELEASE version.
When all these apps are deployed on a load balanced server (2 tomcat instance with a load balancer upfront) and https the problem shows up.
Say that the request url is, for app1, something like this:
https://example.com/context/app1/menu
The app1 returns correctly
https://example.com/context/index.html
For the app2 the request issued by the frontend is
https://example.com/context/app2/menu
And the answer is
http://example.com/context/another_index.html
So it looses the https scheme
It seems that the ServletUriComponentsBuilder.fromRequest has changed behaviour?
I have taken a (quick I admit) look at the commits in the git repo but haven't
found anything ....

ASP.NET MVC Temp Data and RedirectToAction in web form

In ASP.NET MVC from one controller in one area I am using:
TempData["Model"] = model;
then RedirectToAction to pass the model to another controller in another area. In the controller action method I immediately pull the data back out of the model.
I am concerned that if I deploy to a web farm then TempData's use of session state will cause issues but am not sure if I can get away with it in this case because I immediately pull the model out of TempData again in the action method I pass to?
You are right to be concerned, a RedirectToAction sends the client a 302 message containing a url of the redirected resource. This is then the clients responsibilty to create a new request to the redirected resource. There is no guarantee this resource will be served by the original server. The fact that the request is pulled immediately from TempData makes no difference to this approach, at some point it is going to error.
You need to have some means of managing sessions. You could configure HTTP session affinity so that requests served from a server will always return to the originating server.
You could use cookies for session state or implement a session state provider.
This blog post is also a good start on the overview of the options.
If you are using InProc session state you might run into problems because in the redirect you could be sent to another server where the same session will not be available.
Two possible options are to either implement a cookie based TempData provider or switch to another session-state mode. Note that cookie based TempData is completely visible to users, though there are implementations where you encrypt the data.
Try with cooke based instead of session tempdata
See below link
http://volaresystems.com/Blog/post/2011/06/30/Sessionless-MVC-without-losing-TempData
Avoid the use of TempData all together. If you are sending your model in the redirection then use something like
RedirectToAction("MyAction", new {model = myModel});
public actionresult MyAction(model model)
{
/// Mode Code
return View(MyView, model);
}
Assuming that you controller action will take the model as parameter.

Web API 'in memory' requests throw exception

Ok, my situation is much more complicated but there is an easy way to reproduce. Starting with a fresh new ASP.NET MVC 4 Web Application project and selecting Web API as a template I just add a second mvc action to the HomeController where I need to call Web API internally.
public async Task<string> TestAPI()
{
HttpServer server = new HttpServer(GlobalConfiguration.Configuration);
using (HttpMessageInvoker messageInvoker = new HttpMessageInvoker(server, false))
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost:58233/api/values");
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = messageInvoker.SendAsync(request, new CancellationToken()).Result;
return await response.Content.ReadAsStringAsync();
}
//server.Dispose(); - if I do that on the second request I get a "Cannot access a disposed object." exception
}
that thing works only on the first request. On subsequent requests it throws with
The 'DelegatingHandler' list is invalid because the property
'InnerHandler' of 'RequestMessageHandlerTracer' is not null. Parameter
name: handlers
I really need to use the GlobalConfiguration.Configuration here since my system is very modular/plugin based, which makes it really hard to reconstruct that configuration within the action method(or anywhere else).
I would suggest trying to re-use the HttpServer instance on secondary requests. Creating and configuring a new server on every request is not an expected usage and you are likely hitting some edge case. Either setup a DI mechanism and inject into your controller a singleton of the HttpServer, or try accessing it from some static property.
I also would suggest using new HttpClient(httpServer) instead of HttpMessageInvoker.
The same issue can occur in Web API, if you have multiple HttpServers using the same configuration object, and the configuration contains a non-empty list of delegating handlers.
The error occurs because MVC/Web API builds a pipeline of handlers on first request, containing all the delegating handlers (eg RequestMessageHandlerTracer if request tracing is enabled) linked to each other, followed by the MVC server handler.
If you have multiple HttpServers using the same configuration object, and the config object contains delegating handlers, the first HttpServer will be successfully connected into a pipeline; but the second one won't, because the delegating handlers are already connected - instead it will throw this exception on first request/initialization.
More detail on the Web API case here (which is conceptually identical, but uses different classes and would have a slightly different fix):
webapi batching and delegating handlers
In my opinion, the MVC configuration classes should be pure config, and not contain actual delegating handlers. Instead, the configuration classes should create new delegating handlers upon initialization. Then this bug wouldn't exist.

Where to hook up authentication in Grizzly?

I'm using a Grizzly HttpServer which has two HttpHandler instances registered:
under /api/* there is an Jersey REST - style application offering the API of the product, and
under /* there is an StaticHttpHandler which serves static HTML / JavaScript content (which, among other things, talks to the API under /api/
For authentication I'm currently securing only the API using a Jersey ContainerRequestFilter implementing HTTP Basic Auth, which looks quite similar to what is presented in another SO question.
But as requirements changed, now I'd like to require authentication for all requests hitting the server. So I'd like to move the authentication one level up, from Jersey to Grizzly. Unfortunately, I'm completely lost figuring out where I can hook up a "request filter" (or whatever it is called) in Grizzly. Can someone point me to the relevant API to accomplish this?
The easiest solution would leverage the Grizzly embedded Servlet support.
This of course would mean you'd need to do a little work to migrate your current HttpHandler logic over to Servlets - but that really shouldn't be too difficult as the HttpHandler API is very similar.
I'll give some high level points on doing this.
HttpServer server = HttpServlet.createSimpleServer(<docroot>, <host>, <port>);
// use "" for <context path> if you want the context path to be /
WebappContext ctx = new WebappContext(<logical name>, <context path>);
// do some Jersey initialization here
// Register the Servlets that were converted from HttpHandlers
ServletRegistration s1 = ctx.addServlet(<servlet name>, <Servlet instance or class name>);
s1.addMapping(<url pattern for s1>);
// Repeat for other Servlets ...
// Now for the authentication Filter ...
FilterRegistration reg = ctx.addFilter(<filter name>, <filter instance or class name>);
// Apply this filter to all requests
reg.addMapping(null, "/*");
// do any other additional initialization work ...
// "Deploy" ctx to the server.
ctx.deploy(server);
// start the server and test ...
NOTE: The dynamic registration of Servlets and Filters is based off the Servlet 3.0 API, so if you want information on how to deal with Servlet listeners, init parameters, etc., I would recommend reviewing the Servlet 3.0 javadocs.
NOTE2: The Grizzly Servlet implementation is not 100% compatible with the Servlet specification. It doesn't support standard Servlet annotations, or deployment of traditional Servlet web application archive deployment.
Lastly, there are examples of using the embedded Servlet API here
The "hookup" part can be done using a HttpServerProbe (tested with Grizzly 2.3.5):
srv.getServerConfiguration().getMonitoringConfig().getWebServerConfig()
.addProbes(new HttpServerProbe.Adapter() {
#Override
public void onRequestReceiveEvent(HttpServerFilter filter,
Connection connection, Request request) {
...
}
#Override
public void onRequestCompleteEvent(HttpServerFilter filter,
Connection connection, Response response) {
}
});
For the "linking" to the ContainerRequestFilter you might want to have a look at my question:
UnsupportedOperationException getUserPrincipal

Can I get information about the IIS7 virtual directory from Application_Start?

I have 3 IIS7 virtual directories which point to the same physical directory. Each one has a unique host headers bound to it and each one runs in its own app pool. Ultimately, 3 instances of the same ASP.NET application.
In the Application_Start event handler of global.asax I would like to identify which instance of the application is running (to conditionally execute some code). Since the Request object is not available, I cannot interrogate the current URL so I would like to interrogate the binding information of the current virtual directory?
Since the host header binding is unique for each site, it would allow me to identify which application instance is starting up. Does anyone know how to do this or have a better suggestion?
When a request is made, and just prior to the HttpApplication instance being created, ASP.NET initializes core objects such as HttpContext, HttpRequest and HttpResponse which means they will exist when you get to the Application_Start event in Global.asax. Thus, in Application_Start, you can get the requesting url like so:
var url = this.Context.Request.Url;

Resources