I am having trouble using JSF just wanted to run it by so if there is anything obvious someone can spot. I have a managed bean which is giving me trouble. In my faces-config.xml I have:
<managed-bean>
<description>Info Bean</description>
<managed-bean-name>InfoBean</managed-bean-name>
<managed-bean-class>bean.InfoBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
In my JSF I have the following:
<h:outputText value="#{InfoBean.deviceModel}" rendered="true"></h:outputText>
I have a POJO for InfoBean as follows:
public class InfoBean {
String deviceModel;
String userEmail;
String active;
public InfoBean() {
// TODO Auto-generated constructor stub
}
public String getDeviceModel() {
return deviceModel;
}
public void setDeviceModel(String deviceModel) {
this.deviceModel = deviceModel;
}
public String getUserEmail() {
return userEmail;
}
public void setUserEmail(String userEmail) {
this.userEmail = userEmail;
}
public String getActive() {
return active;
}
public void setActive(String active) {
this.active = active;
}
}
There is a no arg constructor in POJO too, but for some reason the deviceModel value does not get displayed to the screen and I cannot figure out why! Any help much appreciated. I have a handler which is also in the faces-config as a separate managed bean, when the user clicks a button, control goes to handler class which calls a service that populates fields in the POJO InfoBean, so as I can see it should appear but it does not!
Any help much appreciated.
I have sorted out the issue and the solution is that since I had a model like this: JSP button is clicked->call goes to Handler->handler calls method in service->Service populates the managed bean InfoBean and returns it to handler
The managed bean even though declared in the config file with scope as session was NOT actually part of the session. In my handler after returning the InfoBean I added:
HttpSession session = (HttpSession)FacesContext.getCurrentInstance().getExternalContext().getSession(false);
session.setAttribute("InfoBean", InfoBean);
This placed it in the session and immediately and values started appearing! :-))
I have read several articles about this and never seen this mentioned, so I am wondering how it is done otherwise. One other suggestion I got was make InfoBean a private instance of the Handler with getters and setters, this way it will get created with the handler and will also be olk. I have not tried this approach though. Thanks to all who helped.
How your deviceModel property of the bean is populated?
Are you sure that it is not null? You can eventually check that by putting a log in the getter method:
public String getDeviceModel() {
System.out.println("Getter called: " + deviceModel + ".");
return deviceModel;
}
Eventually, you can modify the scope of the bean to set it as session.
Your post shows it being defined in request scope not session scope. If you change it to session, you won't need put it in using setAttribute(). Or maybe I'm missing something.
Despite changign the scope to session, it was not working, the above code where I add it to the HttpSession is necessary in order for this to work, or so I have found.
Thanks.
Related
I have followed this steps to setup JSB. In my bounded-class, I need to return the source of an API request (I cannot, therefore, use GetPageSourceAsync because no JS context is ever created). So, I use the trick of copying and immediately pasting the page content to a string variable (see result). This code is not working, I get the following exception:
The ChromiumWebBrowser instance creates the underlying Chromium Embedded Framework (CEF) browser instance in an async fashion. The undelying CefBrowser instance is not yet initialized. Use the IsBrowserInitializedChanged event and check the IsBrowserInitialized property to determine when the browser has been initialized.
which is happening on bro.SelectAll();:
public class boundClass
{
ChromiumWebBrowser bro;
public boundClass()
{
bro = new ChromiumWebBrowser("https://google.com");
}
public string getAuthSource(string url)
{
string source = String.Empty;
bro.Load(url);
while (bro.IsLoading)
{
}
bro.SelectAll();
bro.Copy();
string result = Clipboard.GetText();
Clipboard.Clear();
return result;
}
}
What's the problem? The ChromiumWebBrowser seems well-initialized to me...
When using spring-data-rest there is a post processing of Resource classes returned from Controllers (e.g. RepositoryRestControllers). The proper ResourceProcessor is called in the post processing.
The class responsible for this is ResourceProcessorHandlerMethodReturnValueHandler which is part of spring-hateoas.
I now have a project that only uses spring-hateoas and I wonder how to configure ResourceProcessorHandlerMethodReturnValueHandler in such a scenario. It looks like the auto configuration part of it still resides in spring-data-rest.
Any hints on how to enable ResourceProcessorHandlerMethodReturnValueHandler in a spring-hateoas context?
I've been looking at this recently too, and documentation on how to achieve this is non-existent. If you create a bean of type ResourceProcessorInvokingHandlerAdapter, you seem to lose the the auto-configured RequestMappingHandlerAdapter and all its features. As such, I wanted to avoid using this bean or losing the WebMvcAutoConfiguration, since all I really wanted was the ResourceProcessorHandlerMethodReturnValueHandler.
You can't just add a ResourceProcessorHandlerMethodReturnValueHandler via WebMvcConfigurer.addReturnValueHandlers, because what we need to do is actually override the entire list, as is what happens in ResourceProcessorInvokingHandlerAdapter.afterPropertiesSet:
#Override
public void afterPropertiesSet() {
super.afterPropertiesSet();
// Retrieve actual handlers to use as delegate
HandlerMethodReturnValueHandlerComposite oldHandlers = getReturnValueHandlersComposite();
// Set up ResourceProcessingHandlerMethodResolver to delegate to originally configured ones
List<HandlerMethodReturnValueHandler> newHandlers = new ArrayList<HandlerMethodReturnValueHandler>();
newHandlers.add(new ResourceProcessorHandlerMethodReturnValueHandler(oldHandlers, invoker));
// Configure the new handler to be used
this.setReturnValueHandlers(newHandlers);
}
So, without a better solution available, I added a BeanPostProcessor to handle setting the List of handlers on an existing RequestMappingHandlerAdapter:
#Component
#RequiredArgsConstructor
#ConditionalOnBean(ResourceProcessor.class)
public class ResourceProcessorHandlerMethodReturnValueHandlerConfigurer implements BeanPostProcessor {
private final Collection<ResourceProcessor<?>> resourceProcessors;
#Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
if (bean instanceof RequestMappingHandlerAdapter) {
RequestMappingHandlerAdapter requestMappingHandlerAdapter = (RequestMappingHandlerAdapter) bean;
List<HandlerMethodReturnValueHandler> handlers =
requestMappingHandlerAdapter.getReturnValueHandlers();
HandlerMethodReturnValueHandlerComposite delegate =
handlers instanceof HandlerMethodReturnValueHandlerComposite ?
(HandlerMethodReturnValueHandlerComposite) handlers :
new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
requestMappingHandlerAdapter.setReturnValueHandlers(Arrays.asList(
new ResourceProcessorHandlerMethodReturnValueHandler(delegate,
new ResourceProcessorInvoker(resourceProcessors))));
return requestMappingHandlerAdapter;
}
else return bean;
}
}
This has seemed to work so far...
can someone please explain me the code written below
public IList<GetProductPrice> CurrentPage
{
get { return ViewState["CurrentPage"] as List<GetProductPrice>; }
set { ViewState["CurrentPage"] = value; }
}
It is called a Property. They generate a getter and setter functions when compiled:
List<GetProductPrice> GetCurrentPage(){
return ViewState["CurrentPage"] as List<GetProductPrice>;
}
void SetCurrentPage(List<GetProductPrice> value) {
ViewState["CurrentPage"] = value;
}
//i think its actual get_.. but it doesn't matter for the example
So its generates ease of use getter setters. which you can just call by using:
var test = CurrentPage; //compiled to var test = GetCurrenctPage();
CurrentPage = test; //compiled to SetCurrentPage(test);
If you leave the getter and setter empty like this:
public int CurrentPage
{
get;
set;
}
it will also generate a backing field on the class where it stores the data:
private int _currentPage;
public GetCurrentPage(){ return _currentPage }
public SetCurrentPage(int value) { _currentPage = value }
Why do we do this?
Using getters and setters is a very old best practise from java (where ide's would have an option to generate them). But this would lead to a lot of boilerplate code!
In C# they try to counter this by adding these properties. But why do we need getters and setters? For example if you want to be notified when a value changes (to mark the classes it self as dirty). I think entity framework uses it to track if a model is changed otherwise it wont do a db update call. There are also other usefull tools that inject code in properties on compile time. to add extra functionality.
How not to use it:
using properties to return HttpContext.Current Is a dangerous one because you secretly depend on the HttpContext so try not to do this at any time!
Generally its also bad practise to use it when the code inside the get or set is very heavy (very instensive). Its bad practise because someone else using the code might think he is just setting a property/field while actually some very heavy code is executed. its best practice to make a special function for this instead and private the getter/setter:
public int Property {get; private set; }
public SetProperty(int value){
//intensive code here:
Property = value;
}
This property is letting the consumer of the property to use it like Local collection without referring the ViewState in the code. It will make the code simple and easy to use.
get { return ViewState["CurrentPage"] as List<GetProductPrice>; }
Here the ViewState object ViewState["CurrentPage"] is converted to list of GetProductPrice
set { ViewState["CurrentPage"] = value; }
Here the List is assigned to ViewState["CurrentPage"]
This code will only work in a controller, where ViewState is a property. This CurrentPage property provides a statically-typed way to access a certain ViewState item through that property.
So instead of sprinkling ViewState["CurrentPage"] as List<GetProductPrice> all over your controller code where you want to access the "current page", you can now simply use the CurrentPage property.
Of course "current page" is a term made up by the developer who chose to name things like this, I don't see how a List<GetProductPrice> has a relation to the "current page".
I was wondering if it's possible to use an extension method with asp.net webforms and nvelocity. I would like to set some defaults if the string value is null or empty.
Example of .vm file:
Example of my email body...
Billable Status: $billableStatus.Evaluate()
rest of my email body...
Attempted extension method:
public static class Helper
{
public static string Evaluate(this string value)
{
if (String.IsNullOrEmpty(value))
return "Not Provided";
else
return value;
}
}
Or is there an alternative to what I'm tryting to accomplish?
I don't think NVelocity can resolve extension methods with C#/VB.NET syntax sugar. What I do is register an instance of a helper in the velocity context:
var context = VelocityContext();
context.Put("helper", new Helper());
context.Put("billableStatus", "something");
...
and then in your template:
$helper.Evaluate($billableStatus)
You have to make your helper non-static for this to work, of course.
I came across something similar in past and I was looking for something more sophisticated and with more control. I found that NVelocity does provide a way to intercept the method and property calls but for that you will have to implement certain things. In order to make your custom interceptor you will need to implement NVelocity.IDuck. For example
public class MyClass : NVelocity.IDuck
{
public object GetInvoke(string propName)
{
....
}
public object Invoke(string method, params object[] args)
{
....
}
public void SetInvoke(string propName, object value)
{
....
}
}
Now any instance of MyClass will intercept and pass the method and property calls to our these three function implementation and give us a chance to resolve and return the output. You may notice from these three function signatures that in order to implement them we may need some reflection where we can locate respective methods on available extension types and execute them. If needed you can read following blog post for more details about going this way. NVelocity and extension methods
Let's say I have the following interceptor in a SEAM app:
public class MyInterceptor {
#In
private Monitor myMonitor;
#AroundInvoke
public Object aroundInvoke(InvocationContext ctx) throws Exception {
try {
myMonitor.a();
return ctx.proceed();
}
finally {
myMonitor.b();
}
}
}
myMonitor.a() works (so Monitor is correctly injected), myMonitor.b() fails because Monitor is already null. Seam Doc says: "Injected values are disinjected (i.e., set to null) immediately after method completion and outjection."
Is that what is happening? Can I do something to tell SEAM to "not yet" "disinject" the component? I can of course also do something like XContext.get(..), but I'm wondering whether this is a bug or a mistake from my side. thanks!
Try this one instead
Object response = null;
try {
myMonitor.a();
response = ctx.proceed();
} finally {
myMonitor.b();
}
return response;
regards,
Avoid using injection.
Try working around this problem. I see you have some sort of monitoring going on. Look at this interceptor that captures the amount of time a method is executed in Seam components. Try modifying your code to match that.
It works great!
Here is the link
Seam is working as advertised.
You could just ignore the disinjection:
public class MyInterceptor {
private Monitor myMonitor;
#In
private void setMonitor(Monitor aMonitor) {
if (aMonitor != null) {
myMonitor = aMonitor;
}
}
#AroundInvoke
public Object aroundInvoke(InvocationContext ctx) throws Exception {
try {
myMonitor.a();
return ctx.proceed();
}
finally {
myMonitor.b();
myMonitor = null; //perform disinjection yourself
}
}
}
The caveat here is that Seam is disinjecting the reference for a reason. Seam wants to control the lifecycle and identity of "myMonitor" and by keeping a reference to it, you are not abiding by your contract with Seam. This could lead to unexpected behavior.
For instance, if myMonitor were for some reason in the Stateless scope, Seam might destroy it before ctx.proceed() returns, leaving you with a reference to a broken proxy. Best advice is to know the scope and lifecycle of what you are retaining since you are "living on the edge."