私はこれをまっすぐにするといいのですが:
Tomcat 7でモバイル用に最適化されたJSF 2.0ページを作成しようとしています。したがって、私はMojarra 2.1.6とPrimeFaces (Core 3.1.1 と Mobile 0.9.1) を使用しています。
私のシナリオ:
- ユーザーが簡略化された URL にアクセスします。例: www.someurl.eu/view.xhtml/12345678
- ServletFilter は URL を www.someurl.eu/view.xhtml?id=12345678 に書き換えます
- Url パラメーターが ManagedBean に提供される
- 必要なデータが評価され、view.xhtml に公開されます
- 私のview.xhtmlには、ダウンロード用のボタンが用意されています
私の問題:
ボタンをクリックすると、ManagedBean が @RequestScoped に設定されている場合、サーバーは NPE を表示します。ボタンをクリックすると、新しいリクエストが発行され、URL パラメータが失われ、ダウンロード ファイルが利用できなくなると思います。私が正しいかどうかはわかりませんが、そうであれば、これをエレガントに解決する方法がわかりません。
私のマネージドBean:
@ManagedBean
@RequestScoped
public class ViewBean {
// Elements
...
private StreamedContent file;
...
// Getter and Setter
...
public StreamedContent getFile() {
invalidateSession();
return file;
}
public void setFile(StreamedContent file) {
this.file = file;
}
...
// Init
@PostConstruct
public void init() {
//read URL-Parameter
urlSdbac = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id");
// validate
if(urlSdbac == null || urlSdbac.equals("") || urlSdbac.length() != 8) {
urlSdbac = "invalid";
}
// get Data
else {
SdbCustomerData cd = getFileMetadata(urlSdbac);
if(cd == null) {
this.name = "invalid code";
this.language = "no language options found";
}
else {
...
// prepare File for Download
this.file = new Helper().getWebDavFile(cd.getCid(), cd.getName());
}
}
}
私のview.xhtml:
<h:form>
<pm:page title="Download">
<pm:view>
<pm:content>
...
<p:commandButton value="Download" ajax="false">
<p:fileDownload value="#{viewBean.file}" />
</p:commandButton>
</pm:content>
</pm:view>
</pm:page>
</h:form>
最後になりましたが、私のフィルター:
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String url = request.getRequestURI();
Pattern sdbac = Pattern.compile("[A-Za-z0-9]{8}");
Matcher fit = null;
// check Page
if(url.contains("view.xhtml/") && (!url.contains("?id=") && !url.endsWith("view.xhtml")) ) {
String code = url.substring(url.indexOf("view.xhtml/")+11, url.length());
// validate Param?
fit = sdbac.matcher(code);
if(fit.matches()) {
// redirect
response.sendRedirect("/getSDS/view.xhtml?id=" + code);
}
else {
// redirect
response.sendRedirect("/getSDS/view.xhtml?id=invalid");
}
}
else {
chain.doFilter(req,res);
}
}
私のフィルターは任意の URL にマップされます<url-pattern>/*</url-pattern>
また、ManagedBean を@SessionScopedに設定しようとしました。その場合、ダウンロードは正常に機能しますが、セッション スコープの ManagedBean 内の永続データのために、ユーザーは URL を変更できません。
たぶん、私は盲目すぎて明白な解決策を見ることができません。
どんな助けでも大歓迎です!前もって感謝します!
PS例外
java.lang.NullPointerException
org.primefaces.component.filedownload.FileDownloadActionListener.processAction(FileDownloadActionListener.java:58)
javax.faces.event.ActionEvent.processListener(ActionEvent.java:88)
javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:769)
javax.faces.component.UICommand.broadcast(UICommand.java:300)
javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)
javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259)
com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
eu.qualisys.getsds.filter.SDBACParamFilter.doFilter(SDBACParamFilter.java:53)