NutzCN Logo
问答 Cannot call sendRedirect() after the response has been committed
发布于 2905天前 作者 qq_28b95d2d 5880 次浏览 复制 上一个帖子 下一个帖子
标签:

2016-12-01 14:33:31,242 org.nutz.mvc.impl.processor.FailProcessor.process(FailProcessor.java:28) WARN - Error@/private/index :
java.lang.IllegalStateException: Cannot call sendRedirect() after the response has been committed
at org.apache.catalina.connector.ResponseFacade.sendRedirect(ResponseFacade.java:494)
at javax.servlet.http.HttpServletResponseWrapper.sendRedirect(HttpServletResponseWrapper.java:138)
at org.nutz.mvc.view.ServerRedirectView.render(ServerRedirectView.java:35)
at cn.wizzer.common.mvc.processor.NutShiroProcessor.process(NutShiroProcessor.java:47)
at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
at org.nutz.mvc.impl.processor.ModuleProcessor.process(ModuleProcessor.java:113)
at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)

24 回复

@wendal 页面报500的错误,具体是:

HTTP Status 500 - java.lang.IllegalStateException: Cannot call sendError() after the response has been committed
type Exception report
message java.lang.IllegalStateException: Cannot call sendError() after the response has been committed
description The server encountered an internal error that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: java.lang.IllegalStateException: Cannot call sendError() after the response has been committed
	org.apache.shiro.web.servlet.AdviceFilter.cleanup(AdviceFilter.java:196)
	org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:148)
	org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
	org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
	org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
	org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
	org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
	org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)
	org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
	org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
root cause
java.lang.IllegalStateException: Cannot call sendError() after the response has been committed
	org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:478)
	javax.servlet.http.HttpServletResponseWrapper.sendError(HttpServletResponseWrapper.java:129)
	org.nutz.mvc.view.HttpStatusView.render(HttpStatusView.java:74)
	org.nutz.mvc.impl.processor.ViewProcessor.process(ViewProcessor.java:43)
	org.nutz.mvc.impl.processor.FailProcessor.process(FailProcessor.java:30)
	org.nutz.mvc.impl.NutActionChain.doChain(NutActionChain.java:45)
	org.nutz.mvc.impl.ActionInvoker.invoke(ActionInvoker.java:6

@qq_28b95d2d 做了啥

@wendal
重写了session manger ,在 protected Serializable getSessionId(ServletRequest request, ServletResponse response) 方法加了这段代码

   for (Session session : this.getSessionDAO().getActiveSessions()) {
                SimplePrincipalCollection p = (SimplePrincipalCollection) session
                        .getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
                if (p == null) {
                    try {
                        rs.sendRedirect("http://www.djinfo.com.cn:9999/");
                        return null;
                    } catch (IOException e) {
                        // e.printStackTrace();
                    }
                }

            }

@qq_28b95d2d 那得想办法终止请求,而不是继续访问

@wendal
public class SessionManager extends DefaultWebSessionManager {}

@wendal return?还是response.redirect后没把缓存flush干净

SessionManager里面做重定向, 估计shiro就没考虑过!

@wendal
可以在session manager里面调用webservice吗

@qq_28b95d2d 能

@wendal
org.apache.shiro.session.UnknownSessionException: There is no session with id [1c92e497-b096-4e53-962c-7dc36f37da37]
现在在session manager里面又报这个错

@wendal
org.apache.shiro.session.UnknownSessionException: There is no session with id [1c92e497-b096-4e53-962c-7dc36f37da37]
现在在session manager里面又报这个错

package handler;

import java.io.Serializable;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.SessionException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.servlet.Cookie;
import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.Mvcs;

import cn.wizzer.common.service.log.SysLogService;
import cn.wizzer.common.util.EncryptUtil;
import cn.wizzer.modules.sys.bean.Sys_log;
import cn.wizzer.modules.sys.bean.Sys_user;
import cn.wizzer.modules.sys.bean.Unified_portal;
import cn.wizzer.modules.sys.service.UserService;

public class SessionManager extends DefaultWebSessionManager {
    private static final Log log = Logs.get();

    @Inject
    SysLogService sysLogService;

    @Inject
    UserService userService;

    public SessionManager() {
        super();
    }

    @Override
    protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
        if (sysLogService == null) {
            sysLogService = Mvcs.ctx().getDefaultIoc()
                    .get(SysLogService.class);
        }
        if (userService == null) {
            userService = Mvcs.ctx().getDefaultIoc()
                    .get(UserService.class);
        }

        // 如果参数中包含“__sid”参数,则使用此sid会话。
        // 例如:http://localhost/project?__sid=xxx&__cookie=true
        // 其实这里还可以使用如下参数:cookie中的session名称:如:JSESSIONID=xxx,路径中的
        // ;JESSIONID=xxx,但建议还是使用 __sid参数。
        String url = ((HttpServletRequest) request).getRequestURI();
        System.out.println("request######url" + url);
        String sid = request.getParameter("jsid");
        if (StringUtils.isNotBlank(sid)) {
            // 是否将sid保存到cookie,浏览器模式下使用此参数。

            System.out.println("sidsidsidsidsidsid:" + sid);

            HttpServletRequest rq = (HttpServletRequest) request;
            HttpServletResponse rs = (HttpServletResponse) response;
            // start checkSession

            System.out.println("---rq----" + rq);

            HttpSession session = rq.getSession();

            Unified_portal unifiedPortal = (Unified_portal) session.getAttribute("unifiedPortal");

            if (unifiedPortal != null) {
                System.out.println("^^^^^^^^^^^^^^^^^^unifiedPortalunifiedPortalunifiedPortal^^^^^^^^^^^^^^");
                // 远程调用路径
                String endpoint1 = "http://www.djinfo.com.cn:9999/cxf/WSDemoService";
                String result1 = "call failed!";
                Call call1;
                try {
                    call1 = (Call) new Service().createCall();
                    call1.setTargetEndpointAddress(endpoint1);
                    // 调用的方法名
                    call1.setOperationName(new QName("http://wsTest.ws.djhome.platform.dj.com/",
                            "checkSession"));

                    // 设置参数名
                    call1.addParameter("arg0", // 参数名
                            XMLType.XSD_STRING, // 参数类型:String
                            ParameterMode.IN); // 参数模式:'IN' or 'OUT'

                    // 设置返回值类型
                    call1.setReturnType(XMLType.XSD_STRING);

                    String token = unifiedPortal.getToken();
                    String loginName = unifiedPortal.getUsername();

                    // aname,apassword, pname,ppassword,
                    String arg01 = EncryptUtil.encode(token + "&" + loginName);
                    System.out.println("AAAAAAAAAarg01" + arg01);
                    result1 = (String) call1.invoke(new Object[] { arg01 });
                    System.out.println("result1result1result1result1result1" + result1);

                    if (!result1.contains("110")) {
                        try {
                            Subject currentUser = SecurityUtils.getSubject();
                            System.out.println("CCCCCCCCCCurrentUsercurrentUsercurrentUsercurrentUsercurrentUser");
                            Sys_user user = (Sys_user) currentUser.getPrincipal();
                            Sys_log log = Sys_log.c("info", "用户退出", user.getId(),
                                    user.getUsername(), "用户:" + user.getUsername() + " 手动退出系统!",
                                    null);
                            sysLogService.async(log);
                            userService.update(Chain.make("is_online", false),
                                    Cnd.where("id", "=", user.getId()));
                            session.setAttribute("logout", "true");
                            currentUser.logout();
                            System.out.println("LLLLLLLLLLLLLLLLLLLLLLLLogoutlogoutlogoutlogoutlogoutlogout");

                        } catch (SessionException ise) {
                            log.debug(
                                    "Encountered session exception during logout.  This can generally safely be ignored.",
                                    ise);
                        } catch (Exception e) {
                            log.debug("Logout error", e);
                        }

                        rs.sendRedirect("http://www.djinfo.com.cn:9999/");
                        return null;
                    }

                } catch (Exception e) {
                    System.out.println("ExceptionExceptionExceptionExceptionExceptionEx");
                    e.printStackTrace();
                }
            }
            // end checkSession

            Cookie template = getSessionIdCookie();
            Cookie cookie = new SimpleCookie(template);
            cookie.setValue(sid);
            cookie.saveTo(rq, rs);
            // 设置当前session状态
            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,
                    ShiroHttpServletRequest.URL_SESSION_ID_SOURCE); // session来源与url
            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, sid);
            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);

            System.out.println("endddddddddddddddddddddddddddddddd");
            return sid;
        } else {
            System.out.println("endddddddddddddddddddddddddddddddd error");
            return super.getSessionId(request, response);
        }
    }

}

我的意思是你不应该在这个地方做重定向操作啊

@wendal
session.getAttribute("unifiedportal")取不到值

@wendal
他根本就没走到重定向这里,因为session.getAttribute("unifiedportal")取不到值

不觉得这切入点很不对吗?

要实现啥需求?

@wendal

1.根据url里面的参数jsid设置cookie
2.session manger每次都要调用webservice结果如果不包含“110”则重定向到9999的那个url

@wendal
大神怎么样了

在所有其他Filter之前,加个Filter来处理

然后,如果要继续下一个请求, 继承HttpServletRequestWrapper,覆盖其getHeader系列方法,即可on-fly修改原有的cookie(cookie只是header的一种)

@wendal 第二个重定向怎么解决

添加回复
请先登陆
回到顶部