如何使用JSF和导航规则创建带参数的GET请求? [英] How to create a GET request with parameters, using JSF and navigation-rules?

查看:140
本文介绍了如何使用JSF和导航规则创建带参数的GET请求?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法使用h:outputLink,其他JSF标记或代码创建一个带有请求参数的非面部请求(HTTP GET)的html链接?



例如,我有以下导航规则

 < navigation-rule> 
< navigation-case>
< from-outcome> showMessage< / from-outcome>
< to-view-id> /showMessage.jsf< / to-view-id>
< redirect />
< / navigation-case>
< / navigation-rule>

在我的页面中,我想输出以下html代码:

 < a href =/ showMessage.jsf?msg = 23>点击查看消息< / a> 

我可以在页面中编写html代码,但我想按顺序使用导航规则将所有网址都定义在一个可配置文件中。

解决方案

这是一个有趣的想法。我很想知道它在实践中是如何实现的。



获取导航规则



导航由 NavigationHandler 。掌握NavigationHandler并不困难,但API不会公开它使用的规则。



正如我所看到的,你可以:


  1. 在初始化时解析faces-config.xml并将规则存储在应用程序上下文中( easy

  2. 实现您自己的NavigationHandler,忽略faces-config.xml中的规则或使用您自己的规则文件对其进行补充,并以某种方式公开其规则集(可行,但需要一些工作

  3. 嘲笑你自己的 FacesContext 并将其传递给现有的导航处理程序(很难让两个FacesContext对象在同一个线程中共存并且效率极低

现在,您还有另一个问题。你想在哪里保留映射来查看视图?在豆类中对它们进行硬编码?



使用导航规则



关闭我可以想到两种方法可以从后端构造包含参数的URL。两者都涉及定义某种bean。

 < managed-bean> 
< managed-bean-name> navBean< / managed-bean-name>
< managed-bean-class> foo.NavBean< / managed-bean-class>
< managed-bean-scope> application< / managed-bean-scope>
< / managed-bean>

资料来源:

  package foo; 

import java.io.IOException;
import java.io.Serializable;
import java.net.URLEncoder;

import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;

公共类NavBean实现Serializable {

private String getView(){
String viewId =/showMessage.faces; //或者查看某处
返回viewId;
}

/ **
*页面的常规链接
* /
public String getUrlLink(){
FacesContext context = FacesContext。 getCurrentInstance();
ExternalContext extContext = context.getExternalContext();
String viewId = getView();
String navUrl = context.getExternalContext()。encodeActionURL(
extContext.getRequestContextPath()+ viewId);
返回navUrl;
}

/ **
*只是一些价值
* /
public String getValue(){
return+ System。的currentTimeMillis();
}

/ **
*由行动调用
* /
public String invokeRedirect(){
FacesContext context = FacesContext.getCurrentInstance ();
ExternalContext extContext = context.getExternalContext();
String viewId = getView();
try {
String charEncoding = extContext.getRequestCharacterEncoding();
String name = URLEncoder.encode(foo,charEncoding);
字符串值= URLEncoder.encode(getValue(),charEncoding);
viewId = extContext.getRequestContextPath()+ viewId +'?'+ name
+=+ value;
String urlLink = context.getExternalContext()。encodeActionURL(
viewId);
extContext.redirect(urlLink);
} catch(IOException e){
extContext.log(getClass()。getName()+。invokeRedirect,e);
}
返回null;
}

}

GET



对于GET请求,您可以使用UIParameters设置值并让渲染器构建参数列表。

 < h:outputLink value =#{navBean.urlLink}> 
< f:param name =foovalue =#{navBean.value}/>
< h:outputText value =get/>
< / h:outputLink>

POST



如果要在POST操作期间将URL设置为视图,可以使用操作中的重定向(由按钮或commandLink调用)来执行此操作。

 < h:commandLink id =myCommandLinkaction =#{navBean.invokeRedirect}> 
< h:outputText value =post/>
< / h:commandLink>

注释



<请注意 ExternalContext.encodeActionURL 用于对字符串进行编码。这是生成可跨上下文(portlet等)移植的代码的好习惯。如果您正在编码图像或下载文件的链接,则可以使用 encodeResourceURL


Is there a way to create an html link using h:outputLink, other JSF tag or code to create a non faces request (HTTP GET) with request parameters?

For example I have the following navigation-rule

<navigation-rule>
    <navigation-case>
        <from-outcome>showMessage</from-outcome>
        <to-view-id>/showMessage.jsf</to-view-id>
        <redirect/>
    </navigation-case>
</navigation-rule>

In my page I would like to output the following html code:

<a href="/showMessage.jsf?msg=23">click to see the message</a>

I could just write the html code in the page, but I want to use the navigation rule in order to have all the urls defined in a single configurable file.

解决方案

This is an interesting idea. I'd be curious to know how it pans out in practice.

Getting the navigation rules

Navigation is handled by the NavigationHandler. Getting hold of the NavigationHandler isn't difficult, but the API does not expose the rules it uses.

As I see it, you can:

  1. parse faces-config.xml on initialization and store the rules in the application context (easy)
  2. implement your own NavigationHandler that ignores the rules in faces-config.xml or supplements them with your own rules file and exposes its ruleset somehow (workable, but takes a bit of work)
  3. mock your own FacesContext and pass it to the existing navigation handler (really difficult to make two FacesContext object coexist in same thread and extremely inefficient)

Now, you have another problem too. Where are you going to keep the mappings to look up the views? Hard-code them in the beans?

Using the navigation rules

Off hand, I can think of two ways you could construct parameter-containing URLs from the back-end. Both involve defining a bean of some kind.

<managed-bean>
    <managed-bean-name>navBean</managed-bean-name>
    <managed-bean-class>foo.NavBean</managed-bean-class>
    <managed-bean-scope>application</managed-bean-scope>
</managed-bean>

Source:

package foo;

import java.io.IOException;
import java.io.Serializable;
import java.net.URLEncoder;

import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;

public class NavBean implements Serializable {

    private String getView() {
        String viewId = "/showMessage.faces"; // or look this up somewhere
        return viewId;
    }

    /**
     * Regular link to page
     */
    public String getUrlLink() {
        FacesContext context = FacesContext.getCurrentInstance();
        ExternalContext extContext = context.getExternalContext();
        String viewId = getView();
        String navUrl = context.getExternalContext().encodeActionURL(
                extContext.getRequestContextPath() + viewId);
        return navUrl;
    }

    /**
     * Just some value
     */
    public String getValue() {
        return "" + System.currentTimeMillis();
    }

    /**
     * Invoked by action
     */
    public String invokeRedirect() {
        FacesContext context = FacesContext.getCurrentInstance();
        ExternalContext extContext = context.getExternalContext();
        String viewId = getView();
        try {
            String charEncoding = extContext.getRequestCharacterEncoding();
            String name = URLEncoder.encode("foo", charEncoding);
            String value = URLEncoder.encode(getValue(), charEncoding);
            viewId = extContext.getRequestContextPath() + viewId + '?' + name
                    + "=" + value;
            String urlLink = context.getExternalContext().encodeActionURL(
                    viewId);
            extContext.redirect(urlLink);
        } catch (IOException e) {
            extContext.log(getClass().getName() + ".invokeRedirect", e);
        }
        return null;
    }

}

GET

For a GET request, you can use the UIParameters to set the values and let the renderer build the parameter list.

<h:outputLink value="#{navBean.urlLink}">
    <f:param name="foo" value="#{navBean.value}" />
    <h:outputText value="get" />
</h:outputLink>

POST

If you want to set the URL to a view during a POST action, you can do it using a redirect in an action (invoked by a button or commandLink).

<h:commandLink id="myCommandLink" action="#{navBean.invokeRedirect}">
    <h:outputText value="post" />
</h:commandLink>

Notes

Note that ExternalContext.encodeActionURL is used to encode the string. This is good practice for producing code that is portable across contexts (portlets, etcetera). You would use encodeResourceURL if you were encoding a link to an image or download file.

这篇关于如何使用JSF和导航规则创建带参数的GET请求?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆