aspose file tools*
The moose likes JSF and the fly likes image rendering issue with h:commandButton Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of The Java EE 7 Tutorial Volume 1 or Volume 2 this week in the Java EE forum
or jQuery UI in Action in the JavaScript forum!
JavaRanch » Java Forums » Java » JSF
Bookmark "image rendering issue with h:commandButton" Watch "image rendering issue with h:commandButton" New topic
Author

image rendering issue with h:commandButton

Elie Steckruebe
Greenhorn

Joined: Feb 08, 2012
Posts: 26

Hello folks,

First off, I don't know a lot about web design or even the design of these pages in particular. I outsourced the design part, got html files, and am now implementing functionality using JSF 2.0. I don't actually even know what makes the button look like it's supposed to in the first place.

I have code that looks like this:



which outputs something that looks like this:


That is obviously not what it should look like. The button is being rendered as a broken image. But it works perfectly.

If I take away the name attribute of the commandButton and have code that looks like this:




Then I get something that looks like this:



This is what it should look like, but... when I press the button it causes this error:

java.io.FileNotFoundException: /OHP-Site/faces/index.xhtml Not Found in ExternalContext as a Resource

any ideas?
prasad kakani
Ranch Hand

Joined: Jul 15, 2008
Posts: 59
Hi Elie,

here there is no attribute like class for all (h: ) tags. i think if they are style sheet classes then you need to refer it as styleClass which is one of the attribute of all jsf2.0 components.

remove the class="submit" and try to run in debug mode.

Thanks
prasad


Elie Steckruebe
Greenhorn

Joined: Feb 08, 2012
Posts: 26

Thanks for the reply.

I have tried taking out the Class attribute and it doesn't do anything. I changed it to styleClass and still no effect at all. The only thing that makes any difference is removing the name attribute (which makes it not work as stated before)
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16019
    
  20

1. Writing your own login code is suicide and I don't care how many J2EE books use a "login page" as an example. I've never run into a user-written security system that couldn't be hacked, usually fairly quickly, and I've been doing J2EE since before they invented JSPs. Use a pre-debugged professionally-designed security framework such as the one that comes standard with J2EE and integrates directly into web.xml.

2. "class" is a reserved word in Java, so in order to reduce conflicts, JSF uses "styleClass" instead.

3. In JSF you don't write Controllers. The Controllers are the FacesServlet and logic in the JSF UIComponents. Backing beans are not Controllers, they are Models.

4. My bleary eyes cannot spot an image tag in your sample View Definition, but apparently you didn't include everything. You should be able to use your browser's source examination features to get the actual URL being requested. If we have that plus the source of the image tag (or CSS), we should be able to un-break it.

5. That last message would see to say that your WAR doesn't contain an OHP-Site/faces/index.xhtml resource. Although come to think of it, that resource path looks a lot like a JSF URL that wasn't configured to route to the FacesServlet. Meaning that your web.xml definitions are not set up properly.

Customer surveys are for companies who didn't pay proper attention to begin with.
Elie Steckruebe
Greenhorn

Joined: Feb 08, 2012
Posts: 26

Thanks Tim, especially for touching on some other issues as well.

Regarding the issue at hand, I posted all jsf code on that page. The other code on that page is inconsequential html code. I have no idea where that image is supposed to be. I have looked in the css file, but can't find anything...

Here is the source for that button when the name attribute is present (and therefore works but does not render properly):



Here is the source when the name attribute is not present (and therefore renders properly but does not work):



index.xhtml is the name of the page on which this is all happening and I can get to it fine by going to http://localhost:8080/OHP-Site/faces/index.xhtml, not to mention the error only happens when that button is pressed and doesn't have a name attribute. So there is likely nothing wrong with web.xml.

and for your viewing pleasure, here's the entire css file:

Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16019
    
  20

I never liked the "/faces/" URL convention. Aside from making the URL path longer, it makes it too easy for people to confuse URLs and resource paths. I prefer URLs in the form of "http://localhost:8080/OHP-Site/index.jsf".

When you get stuff on a web page that isn't in the View Definition, such as H1-style captions and images, I have to conclude that one of 3 things is happening:

1. You aren't retrieving from the server you think you are or you're not accessing the webapp you think you are.

2. You are retrieving from the right server, but you're retrieving stale data. Which is why when I use Tomcat, I make a point of cleaning out the temp, work and log directories when re-deploying.

3. You are getting you view definition from an intermediary that is decorating it. Most commonly that would be because there was some sort of "tiling" mechanism at work, but custom login processors often muck around with user requests, which means that anything could be happening.

Elie Steckruebe
Greenhorn

Joined: Feb 08, 2012
Posts: 26

I am certain that 1 and 2 are not issues here. When I make changes to the code and restart the server, that changes are immediately visible, including the name/no name change. Therefore, I am clearly connecting to that server and getting the latest data.

As far as an intermediary, I'm not sure what you mean. My "custom login processor" is one line that returns the String "success" so that the navigation rule in faces-config.xml will send the user off to another page. It doesn't even check what was entered in those fields.

Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16019
    
  20

OK. Next question is what does the "success" navigation rule look like. Because if the login screen isn't coming through an interception and it contains text and image items that aren't in the login View Definition, there's almost got to be something tiling it.
Elie Steckruebe
Greenhorn

Joined: Feb 08, 2012
Posts: 26



Once again, it all works as long as there is a name attribute in that button. If there was a problem with the navigation rule itself, I wouldn't imagine it would ever work at all. By the way, it has nothing to do with the wild card. I just changed it to that.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16019
    
  20

You can omit the "from-view" ID if you want a universal match. No need for a wildcard.

Next question. Is user.xhtml the actual file you posted or is it another resource that doing something like a ui:include?
Elie Steckruebe
Greenhorn

Joined: Feb 08, 2012
Posts: 26

ah ok thanks for the navigation rule tip

user.xhtml is just another page in the WebContent folder
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16019
    
  20

OK, but how does index.html (or whatever page your login form is on) get pulled in?
Elie Steckruebe
Greenhorn

Joined: Feb 08, 2012
Posts: 26

Sorry, I don't understand your question. There are two pages in WebContent: index.xhtml and user.xhtml. If I navigate to index.xhtml (http://localhost:8080/OHP-Site/faces/index.xhtml) and press the login button, I'm taken to user.xhtml ( http://localhost:8080/OHP-Site/faces/user.xhtml)
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16019
    
  20

OK. Then I am going to understand that to mean that the page with the login form that you posted is index.html. Technically, that's the page whose resource path is /index.html and I won't worry about its URL just yet.

The problem I'm having is that the sample View Definition you gave not only seems to lack a graphics tag - whether raw HTML or JSF - but also doesn't match your sample screen in that the sample screen has a boldface large-print page title on it that isn't accounted for on your View Definition.

JSF doesn't just make stuff like that up, so where does it come from?
Elie Steckruebe
Greenhorn

Joined: Feb 08, 2012
Posts: 26

I'm not sure what a graphics tag is so please tell me what to look for and I'll see if I can find it.

Right above that form there is:



Didn't think that was important so didn't post that part.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16019
    
  20

At think at this stage, it's all important, since there are some other critical constructs that I've been assuming were there and maybe they aren't.

The JSF equivalent of the HTML <IMG> tag is <h:graphicImage> BTW.

Elie Steckruebe
Greenhorn

Joined: Feb 08, 2012
Posts: 26

right. There is nothing like that. If you look at the css file I posted starting at line 199, I think you may find where the graphics are coming from. I know very little about css but it looks to me like that's defining images to use for buttons.
Elie Steckruebe
Greenhorn

Joined: Feb 08, 2012
Posts: 26

I think the problem is clearly that JSF is rendering it as type="image" when it should be rendering it as type="submit" and just let the css do its job.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16019
    
  20

I can work my way towards that, but if you don't have the proper JSF view tags wrapping the h:form, the page will generally neither render nor respond properly, which is why I wanted to see the entire thing and not just the form.

Unless I'm being blind (again ), there is no "name=" attribute for the JSF commandLink tag. However, I do recommend putting 'id=" attributes on your form and input control elements. Otherwise JSF will generate internal automatic IDs that are hard to use for debugging.
Elie Steckruebe
Greenhorn

Joined: Feb 08, 2012
Posts: 26

Here's the whole thing. I have to get some sleep. maybe the answer will come to me in a dream :-)



template:

Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16019
    
  20

Thanks. You don't have f:view tags, although for JSF2 they are no longer mandatory.

I do recommend using explicit id attributes, since like I said, you get more meaningful debug messages.

The broken image is probably because your relative URL was relative to the JSF "/faces/" URL, and CSS shouldn't be going through that. Another reason why I prefer the ".jsf" URL format convention over the "/faces/" convention.

I think that the navigation action is probably the usual confusion between URL paths and resource paths, but we'll look at that tomorrow.
Elie Steckruebe
Greenhorn

Joined: Feb 08, 2012
Posts: 26

So I changed the mapping to *.jsf

Now instead of getting the error when I press the button with no name attribute, the entire form just disappears.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16019
    
  20

Just to be clear, your navigation rule should look something like this:


Assuming that it does and that your debugger indicates that the JSF Action method named "login" is being successfully invoked, then a blank page would indicate that there is something wrong with the user.xhtml View Definition file. Unlike Struts which can be annoyingly fond of displaying blank pages when there is failure in the form-processing code, JSF normally only presents blank pages when the page definitions themselves are at fault, so replacing this file with a simpler definition usually verifies that you're navigating to the right place. Once you're satisfied with that, you should be able to build up the page a piece at a time.
Elie Steckruebe
Greenhorn

Joined: Feb 08, 2012
Posts: 26

Are you sure about that first part? I don't think that's the case. Eclipse's built in faces-config editor does not do it that way, and it's hard to believe they would make such an egregious error. I changed it anyway and it made it do all kinds of weird things like ignore the template when redirected. I changed it back to .xhtml in the navigation rule.

Just to be clear, user.xhtml displays fine when I navigate to http://localhost:8080/OHP-Site/user.jsf
It also displays fine when redirected there by that form (when the name attribute is present making the form work at all)

It seems to me then unlikely that the definition of user.xhtml is at fault. It's more likely a problem that occurs in the postback before it even tries to redirect?

I'd also like to reiterate that it works fine (but renders wrong) if there is a name attribute in the tag. There is a clue there that seems to be getting ignored. And yes I realize there is no name attribute in commandButton which makes this even more mysterious.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16019
    
  20

I'm afraid that the Eclipse faces-config editor isn't very impressive. That particular example was snipped from a very old and very functional project. On the whole, in fact, Eclipse support for JSF is less than exciting. I tend to ignore most of what it does provide, although they've apparently finally got a semi-decent approximation to WYSIWYG view definition editing working in Eclipse Indigo. And it actually seems to be working. Even simple XML editing was a problem for longer than I want to recall.

A navigation rule consists of one or more source patterns and a destination URL or "view-id", which is relative to the webapp context root. You can make a rule global by supplying just a target name (for example, "Home"), or you can narrow its scope to a given source view(s) and/or a given action method. Prior to JSF2, I usually defined rules for my actions linked to results of "success", "failure", and occasionally specific types of success or failure, and so my preferred approach was to scope by action method name, since success on one action might not lead to the same destination as success on a different action.

Normally, a code Exception will dump a stacktrace. not a blank page. A botched navigation (misspelled target view id, bad name, usw. would cause the index.jsf to redisplay, since the default is not to navigate. Only a navigation to a page which doesn't render should give a blank page.

Of course, a blank page isn't always really blank, so it's always wise to use the browser's View Page Source function in case there are clues there. I like to put comments in my view templates so that I'll know if the proper view was being processed.

Views that include other views are a specific case where you can be presented with a blank page if the included view has a problem rendering and that particular situation can be a to debug.
Elie Steckruebe
Greenhorn

Joined: Feb 08, 2012
Posts: 26

In any case, it seems to work fine in general when I leave it as .xhtml, and not work fine if I change it to .jsf so I'll just keep it. I have actually used the *.jsf mapping on the other test projects I made while learning jsf 2.0 and never changed the navigation rules to say .jsf instead of .xhtml and never had an issue.

but I did discover it is not ever invoking the login() method when the name attribute is not present, which is the issue at hand. hmm...
Elie Steckruebe
Greenhorn

Joined: Feb 08, 2012
Posts: 26

I found the entire problem.

It was this bit of javascript code in an included script file:



This worked fine when the pages were just html, but something about how jsf rendered it, made this screw everything up. I can't even find where that form() function is and have no idea what it does because everything seems to be working fine by just removing those lines.

By the way, do you have any good places to get started with that J2EE security framework you talked about? The next thing I need to do is actually implement a real login.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16019
    
  20

Ouch! Nothing worse than finding that everything you thought was OK has been silently sabotaged.

J2EE container-managed security is covered in just about any decent introductory text on J2EE. Unfortunately, they usually then go and confuse the issue by showing a sample app with a user-written login process.

Since even user-designed security systems usually have enough wit to use SSL, there's usually a section on setting up transport security in web.xml. A properly thorough text will then cover URL patterns and roles.

The J2EE standard security system is primarily wrapped around the webapp rather than coded into it. That means that less coding is required and many exploits will be turned away by the server without every being able to interact with application code at all, thereby ensuring that application bugs cannot be exploited.

The heart of this architecture is based on secured URL patterns and security roles, both of which you define and associate in web.xml. If an incoming URL request matches one of the defined patterns, then the server checks to see if the user is logged in. If the user is not logged in, the server intercepts the request, sidelines it, presents the login page defined in web.xml (this must be a straight HTML or JSP form, JSF doesn't work here), then (assuming the user logged in) resumes the sidelined request as though nothing had happened. If the request requires a role that the user doesn't possess, the server rejects the request, instead.

You can also augment this system in application code where needed using the HttpServletRequest method isUserInRole() to query for authorization. I do this, for example, when a URL can handle multiple roles, but only some roles are allowed to update data. Also available on the HttpServletRequest are the userName and userPrincipal properties. userPrincipal isn't much use directly, but it holds the userName, as supplied to the login service. The userName method is a shortcut way to retrieve this.

The actual configuration of userids, passwords and roles is done external to the web application, typically using a plug-in security services provider called a Realm. Most common J2EE servers come with support for many different types of Realms. For example, among those available for the Tomcat server are the MemoryRealm, which is a crude service that uses an XML user/role configuration file and is good for testing, the JDBCRealm, which authorizes and authenticates using a database, and the LDAPRealm, which uses an LDAP server such as Microsoft's Active Directory. The webapp neither knows nor cares which Realm is in use, so it's easy to swap Realms for testing.

Because JSF abstracts the underlying server and transport mechanisms. if you need any of the properties and functions available from the HttpServletRequest, you have to dig through JSF's FacesConfig to get it. Rather than splatter a lot of JSF-specific code all over my webapps, I prefer to isolate this functionality into a security manager object, which can be at session or application scope, depending on whether I want my security manager to hold additional security information of its own or simply statically access the HttpServletRequest security features. So I can say "if ( userSecurity.inRole(UserSecurity.ROLE_AUDITOR)) ...".

One thing to be aware of in JSF, however. The container-managed security system secures URLs, not resources. That's an important thing to know, since in JSF, the URL paths don't always track the resource paths. To ensure that there are no security holes introduced on this account, use the "<redirect/>" navigation element to force the URL to match the resource path.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: image rendering issue with h:commandButton