Reputation: 31
I have a problem with redirecting with JSF and pretty faces. I am quite new to this stuff and need some help as I cannot get redirect to work, like I want it to.
Basically I have this in my pretty config:
<url-mapping id="newProject">
<pattern value="/newProject/" />
<view-id value="/faces/project/newProject.xhtml" />
<action>#{projectController.initNewProject}</action>
</url-mapping>
<url-mapping id="project">
<pattern value="/project/" />
<view-id value="/faces/project/projectIdx.xhtml" />
</url-mapping>
The function initNewProject looks like this:
public String initNewProject() throws IOException {
project = this.createProject(123415, "1234578943148", "KB25");
System.out.println(project);
return "pretty:project";
}
where project is a field in the ProjectController:
@Named
@ConversationScoped
public class ProjectController implements Serializable {
private transient Project project;
...
The redirect works as I wish, as the URL changes from ../newProject/ to ../project/ and the contents of /faces/project/newProject.xhtml are displayed. But somewhen during the redirect the constructor of ProjektController is called and nulls the field project.
If I change
return "pretty:project";
to
return "/project/projectIdx.xhtml";
everything works fine. The contents of project are displayed on the webpage. However the URL does not change. It stays ../newProject/ and if the user presses F5 he creates a new project which is bad.
For some other reasons I cannot store the project in the session, so that is no option for me.
I dont want the redirect to recreate the controller as I want newProject.xhtml to display contents of the project, which was created during initNewProject
How can this be achieved?
Many thanks!
Michael
Upvotes: 3
Views: 3026
Reputation: 3908
Fixed the redirection by using the following syntax:
public String create(final Post post) {
postService.save(post);
return "pretty:posts";
}
Upvotes: 0
Reputation: 5668
I think the problem is caused by the tight coupling between the two mappings. Basically you are using a page action in your first mapping to initialize a bean property and then want to access this property in the page rendered by the second mapping. That's not the way RESTful URLs created with PrettyFaces work.
Instead your second mapping should be completely independent from the other. This ensures that the RESTful URL works even if it is bookmarked, copied into another browser window or whatever.
The common way to build such a RESTful URL with PrettyFaces is to use a path parameter like this:
<url-mapping id="project">
<pattern value="/project/#{projectController.projectId}/" />
<view-id value="/faces/project/projectIdx.xhtml" />
<action>#{projectController.loadProject}</action>
</url-mapping>
This way the ID of the project is injected into your controller and you can load the corresponding entity from the database in the page action method:
public void loadProject() {
this.project = projectDao.getById( projectId );
}
How to handle the "new project" use case for your example depends on your requirements regarding persistence and the overall process.
In theory the code you provided should also work. My guess is that the cid
query parameter which is required to keep the conversion scope alive gets lost for some reason. There are a few threads on the PrettyFaces forums about this issue. But AFAIK this is typically caused by bugs in older CDI implementations.
Upvotes: 0