如何让JSF 2.0将JS包含为'application/javascript'而不是'text/javascript'

Urs*_*pke 6 javascript jsf-2 mime-types

在我们的JSF 2.0应用程序中,我们通过包含几个javascript文件<h:outputscript>.

<h:outputScript library="javascript" name="DoStuff.js"/>
Run Code Online (Sandbox Code Playgroud)

生成的html将它们称为"text/javascript".

<script type="text/javascript" src="/mycontext/javax.faces.resource/DoStuff.js.jsf?ln=javascript"></script>
Run Code Online (Sandbox Code Playgroud)

根据这个问题,"text/javascript"已经过时了,而且,htmlunit相当冗长地抱怨这种类型.当然,一切正常,我可以关闭htmlunit的日志记录,但我宁愿让JSF生成正确的类型.

有没有办法覆盖所选的类型<h:outputscript>

Bal*_*usC 6

这是在默认渲染器中硬编码的<h:outputScript>.假设你正在使用Mojarra,那就是com.sun.faces.renderkit.html_basic.ScriptRenderer.根据源,该type属性已在startElement方法中设置.你可以覆盖它:

public class ExtendedScriptRenderer extends ScriptRenderer {

    @Override
    protected void startElement(ResponseWriter writer, UIComponent component) throws IOException {
        writer.startElement("script", component);
        writer.writeAttribute("type", "application/javascript", "type");
    }

}
Run Code Online (Sandbox Code Playgroud)

或者,如果要为最终用户提供指定type属性本身的可能性,并application/javascript在未指定时默认为:

public class ExtendedScriptRenderer extends ScriptRenderer {

    @Override
    protected void startElement(ResponseWriter writer, UIComponent component) throws IOException {
        writer.startElement("script", component);
        String type = (String) component.getAttributes().get("type");
        if (type == null) type = "application/javascript";
        writer.writeAttribute("type", type, "type");
    }

}
Run Code Online (Sandbox Code Playgroud)

要使其运行,请按以下方式注册faces-config.xml:

<render-kit>
    <renderer>
        <component-family>javax.faces.Output</component-family>
        <renderer-type>javax.faces.resource.Script</renderer-type>
        <renderer-class>com.example.ExtendedScriptRenderer</renderer-class>
    </renderer>
</render-kit>
Run Code Online (Sandbox Code Playgroud)

顺便说一句,还有一个很好的@FacesRenderer注释应该如下工作

@FacesRenderer(componentFamily="javax.faces.Output", rendererType="javax.faces.resource.Script")
public class ExtendedScriptRenderer extends ScriptRenderer {

    // ...
}
Run Code Online (Sandbox Code Playgroud)

但是,当它已经被标准渲染器(ScriptRenderer!)定义时,自定义渲染器将无法通过a覆盖它@FacesRenderer.另见问题1748.