Skip to main content

Welcome to Geoff Hayward's Weblog

Commenting on Java, JavaFX, Java EE, Joomla, and IoT.

It took me a while to get to the bottom of why CDI seemed to be dropping @ViewScoped and @SessionScoped beans. @RequestScope was not behaving properly ether.

It took a lot of digging in the application's codebase and a lot of watching the Debugger before narrowing down the course. Anyway here is the culprit; can you spot the bug?

<h:link outcome="#{navbar.logout()}" >Logout</h:link>

That is from an extract of a composite component that is used on every page of the application. Hence, CDI seemed to be dropping scope.

@Named(value = "navbar")
@ApplicationScoped
public class Navbar implements Serializable {
	
    @Inject
    private HttpServletRequest request;

    public String logout() {
        request.getSession(false).invalidate();
        return "/index?faces-redirect=true";
    }

}

For completeness, the extracts CDI backing bean.

I hope you enjoyed this issue more than I did.



Read

Here is how you can create a WebSockets base path for your JavaScript with JSF. This WebSocket base path points back to your deployed application's WAR address.

<script type="text/javascript">
	var base = "#{request.scheme.endsWith("s") ? "wss" : "ws" }://#{request.serverName}:#{request.serverPort}#{request.contextPath}";
</script>

I hope this helps.



Read

I have been experimenting with the Twitter Bower package manager as part of the tech stack to be used with a Java EE JSF project.

This post is a note on how I set up the Web Application project to use the Bower package manager.

I began by setting up a new Mavan Web Application. I used the NetBeans 'New Project' wizard. Once the new Web Application project was created I added JavaServer Faces to the project via NetBeans' Properties > Framework menu.

Next I added a .bowerrc file to the root of the webapp as:

{
  "directory": "resources/components"
}

This .bowerrc file changes the default location that Bower will store the components it downloads. This change made Bower fit with a Mavan Web Application folder structure. Next I added a bower.json file to the root of the webapp.

{
  "name": "bower-setup-test",
  "authors": [
    "Geoffrey Hayward"
  ],
  "private": true
}

The bower.json file keeps a record of each dependency and its version that is added to the project. See the bower.json spec for details.

Then from the root of the webapp I ran the command: bower install bootstrap --save. The --save saved the dependency to bower.json file.

Why Bower? Good question. To reduce the size of the tracked GIT repository and to make the web component libraries explicit. Each time a file is forked from the dependency, such as a bootstrap LESS variables file, you add it to the bower.json ignore property. Likewise you then begin tracking the forked file in GIT. Everything that is managed by Bower (that is not forked) is in (or should be in) the .gitignore file.

My Thoughts: Post Experiment

My thoughts to using Bower with a Java EE JSF project are Bower adds complexity to a Java EE JSF project that may not bring any value. But, with that said Bower certainly would come in handy for a front-end framework heavy project; particularly when some control over what should and should not be edited is needed. In other words I am undecided for now, but have no plans to start using Bower just yet in this context.



Read

Sending a 404 "page not found" response with JSF is easily achieved. In the example below a 404 "page not found" is sent back to the requester if a search on a primary key does not yield a result.

 public Post findPost(Long id) throws IOException {
        Post post =em.find(Post.class, id);
        if (post == null) {
            FacesContext.getCurrentInstance().getExternalContext().responseSendError(HttpServletResponse.SC_NOT_FOUND, "Page not found");
            FacesContext.getCurrentInstance().responseComplete();
        }
        return post;
    }

As can be seen from the example: to send a 404 "page not found" response with JSF you need to get the external context via the 'FacesContext' object. Then using the external context, of the JSF, set the response code. In this case the response code is an error. Finally, It's important to complete the response to halt server side processing.



Read

JSF's h:outputStylesheet and h:outputScript elements have an odd way of ordering linked resources. For example if you do not set the target element of an h:outputScript to body the JavaScript is output before the CSS. This is irrespective of the order given in a template.

I needed to put an <!--[if lte IE 7]> [...] <![endif]--> element into a template. OmniFaces' o:conditionalComment is a great element for this; but the <!--[if lte IE 7]> [...] <![endif]--> condition was being output before the main CSS.

To fix this resource loading problem use a plain old HTML link elements instead of JSF h:outputStylesheet elements. Use this element with the HTML link elements having #{resource['libs:reset.css']} as there href.

<link rel="stylesheet" href="#{resource['libs:reset.css']}" />
<link rel="stylesheet" href="#{resource['css:login.css']}" />
<o:conditionalComment if="lte IE 7" >
     <link rel="stylesheet" href="#{resource['css:login-ie7.css']}" />
</o:conditionalComment>

Will then output:

<link rel="stylesheet" href="/javax.faces.resource/reset.css?ln=libs" />
<link rel="stylesheet" href="/javax.faces.resource/login.css?ln=css" />
<!--[if lte IE 7]>
     <link rel="stylesheet" href="/javax.faces.resource/login-ie7.css?ln=css" />
<![endif]-->

Which is the desired resource ordering.


Tags: JSFOmniFaces

Read

Mailing List

Responsive Media

With the ResponsiveMedia plugin for Joomla it is easy to add 3rd party content from YouTube, Vimeo, and Instagram right in to any Joomla! article.

ResponsiveMedia