Passing value from Servlet to JSF Action method in WebLogic

假如想象 提交于 2019-12-24 05:23:07

问题


I am trying to pass an Object from Servlet's doPost() to JSF's Managed bean's action method. But I am unable to do that.

I have tried to set the value from Servlet as:

request.getSession().setAttribute(key, "JYM");

And tried to retrieve it form Managed bean as:

FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(key)

It is returning null.

Also this is also returning null from Managed bean:

((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getSession().getAttribute(key);

Also from Managed bean this is returning null:

((HttpSession)FacesContext.getCurrentInstance().getExternalContext().getSession(false)).getAttribute(key)

I am passing the key as:

'${pageContext.request.contextPath}/uploadservlet;jsessionid=${pageContext.session.id}?key=<h:outputText value="#{uploadBean.key}" />'

uploadBean is the name of the Managed bean and the key is generated as:

key = UUID.randomUUID().toString();

The key remains unchanged in both of the Servlet and in managed bean. I have printed is to check.

How can I pass the Object from Servlet to Action? Any pointer would be very helpful.

Update

The Managed bean is in session scope.

Update

By using ServletContext I am able to pass the value:

Here is what I did: In Servlet:

String key = request.getParameter("key");

if (getServletContext().getAttribute(key) == null) {
    List<FileItem> fileFields = new ArrayList<FileItem>();
    fileFields.add(fileField);
    getServletContext().setAttribute(key, fileFields);
} else {
    List<FileItem> fileFields = (List<FileItem>)getServletContext().getAttribute(key);
    fileFields.add(fileField);
}

And from session scoped bean:

ServletContext servletContext = ((ServletContext)FacesContext.getCurrentInstance().getExternalContext().getContext());
List<FileItem> fileFields = (List<FileItem>)servletContext.getAttribute(key);
servletContext.setAttribute(key, null);

Now the fileFields is not null anymore. What I understand is the ServletContext behave like Application Scoped variable.

Update

HttpSessionListener's implementation:

This is the class I have written:

public class UploadListener implements HttpSessionListener {
    private HttpSession session = null;

    public void sessionCreated(HttpSessionEvent event) {
        session  = event.getSession();
        session.setMaxInactiveInterval(10);
    }

    public void sessionDestroyed(HttpSessionEvent event) {
        session  = event.getSession();
        Set<String> keys = (Set<String>) session.getAttribute("key");
        Map<String, Object> data = (Map<String, Object>) session.getServletContext().getAttribute("key");
        data.keySet().removeAll(keys);
    }
}

I am setting the value in the ServletContext as:

String key = request.getParameter("key");

List<FileItem> fileFields = (List<FileItem>)getServletContext().getAttribute(key);

if (fileFields == null) {
    fileFields = new ArrayList<FileItem>();
    getServletContext().setAttribute(key, fileFields);
}

fileFields.add(fileField);

And this is the way I am calling the Servlet: '${pageContext.request.contextPath}/uploadservlet?key=<h:outputText value="#{uploadBean.key}" />'.


回答1:


This construct will fail if the servletcontainer doesn't support identifying the HTTP session by jsessionid URL fragment. This is by default supported, but it's possible to turn off this by servletcontainer specific configuration. So far it unfortunately looks like that your Weblogic server is configured as such.

Your best bet is then to exchange the data in the application scope. The randomness of UUID is strong enough to not cause clashes. You should only need to make sure that the session-associated data is cleaned up when the session is destroyed. Otherwise the memory will leak away. For this, you can use a HttpSessionListener. Provided that you store the key in both the application scope (referencing the shared data) and in the session scope (referencing a set of all keys used so far), then the sessionDestroyed() implementation can look like this:

public void sessionDestroyed(HttpSessionEvent event) {
    Set<String> keys = (Set<String>) event.getSession().getAttribute("keys");
    Map<String, Object> data = (Map<String, Object>) event.getSession().getServletContext().getAttribute("data");
    data.keySet().removeAll(keys);
}

Update as per your update, a bit more elegant way to get/set them is:

String key = request.getParameter("key");
List<FileItem> fileFields = (List<FileItem>) getServletContext().getAttribute(key);

if (fileFields == null) {
    fileFields = new ArrayList<FileItem>();
    getServletContext().setAttribute(key, fileFields);
}

fileFields.add(fileField);

and

List<FileItem> fileFields = (List<FileItem>) FacesContext.getCurrentInstance().getExternalContext().getApplicationMap().remove(key);
// ...


来源:https://stackoverflow.com/questions/14275732/passing-value-from-servlet-to-jsf-action-method-in-weblogic

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!