struts 2 type=「redirect」ソースコード解析
まずいくつかの名詞を説明します.
request.getRequestDispatcher()はリクエスト転送であり、前後のページでrequestを共有する.
response.sendRedirect()は再配向であり、前後のページはrequestではありません.
RequestDispatcher.forward()はサーバ側で実行されます.
HttpServletResponse.sendRedirect()は、クライアントブラウザにコマンドを送信ことで完了する.
だから...forward()はブラウザにとって「透明」です.
HttpServeretResponse.sendRedirect()はそうではありません.
このように言うだけでは、きっと理解しにくいに違いない.一例を見てください.
情景:qq登录の上で、あなたは直接メールボックスをクリックして、彼は直接メールボックスに登录します.
要求パスの場合:http://localhost:8080/test/web/skiplogin.action?url=/mail/productManage.action&sessionid=1000111&&phoneId=100000
Actionではurl,sessionid,phoneIdを解析しurlにジャンプします.
ブラウザのアドレスバーのパスは変わりません.
responseを使用する場合.sendRedirect(basePath+finalLocation);
ブラウザのパスは次のようになります.http://localhost:8080/test/mail/productManage.action.
struts 2 resultがタイプtype=「redirect」を返すと、ソースコードを表示すると、実際には再ジャンプが行われます.
私のactionに書かれているコード:
request.getRequestDispatcher()はリクエスト転送であり、前後のページでrequestを共有する.
response.sendRedirect()は再配向であり、前後のページはrequestではありません.
RequestDispatcher.forward()はサーバ側で実行されます.
HttpServletResponse.sendRedirect()は、クライアントブラウザにコマンドを送信ことで完了する.
だから...forward()はブラウザにとって「透明」です.
HttpServeretResponse.sendRedirect()はそうではありません.
このように言うだけでは、きっと理解しにくいに違いない.一例を見てください.
情景:qq登录の上で、あなたは直接メールボックスをクリックして、彼は直接メールボックスに登录します.
要求パスの場合:http://localhost:8080/test/web/skiplogin.action?url=/mail/productManage.action&sessionid=1000111&&phoneId=100000
Actionではurl,sessionid,phoneIdを解析しurlにジャンプします.
RequestDispatcher dispatcher = request.getRequestDispatcher(url_pa);
// dispatcher.forward(request, response);
// , ,
ブラウザのアドレスバーのパスは変わりません.
responseを使用する場合.sendRedirect(basePath+finalLocation);
ブラウザのパスは次のようになります.http://localhost:8080/test/mail/productManage.action.
struts 2 resultがタイプtype=「redirect」を返すと、ソースコードを表示すると、実際には再ジャンプが行われます.
* $Id: ServletRedirectResult.java 1188965 2011-10-25 23:19:48Z mcucchiara $
package org.apache.struts2.dispatcher;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.config.entities.ResultConfig;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;
import com.opensymphony.xwork2.util.reflection.ReflectionException;
import com.opensymphony.xwork2.util.reflection.ReflectionExceptionHandler;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.dispatcher.mapper.ActionMapper;
import org.apache.struts2.dispatcher.mapper.ActionMapping;
import org.apache.struts2.views.util.UrlHelper;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import static javax.servlet.http.HttpServletResponse.SC_FOUND;
/**
* <!-- START SNIPPET: description -->
*
* Calls the {@link HttpServletResponse#sendRedirect(String) sendRedirect}
* method to the location specified. The response is told to redirect the
* browser to the specified location (a new request from the client). The
* consequence of doing this means that the action (action instance, action
* errors, field errors, etc) that was just executed is lost and no longer
* available. This is because actions are built on a single-thread model. The
* only way to pass data is through the session or with web parameters
* (url?name=value) which can be OGNL expressions.
*
* <!-- END SNIPPET: description -->
* <p/>
* <b>This result type takes the following parameters:</b>
*
* <!-- START SNIPPET: params -->
*
* <ul>
*
* <li><b>location (default)</b> - the location to go to after execution.</li>
*
* <li><b>parse</b> - true by default. If set to false, the location param will
* not be parsed for Ognl expressions.</li>
*
* <li><b>anchor</b> - Optional. Also known as "fragment" or colloquially as
* "hash". You can specify an anchor for a result.</li>
* </ul>
*
* <p>
* This result follows the same rules from {@link StrutsResultSupport}.
* </p>
*
* <!-- END SNIPPET: params -->
*
* <b>Example:</b>
*
* <pre>
* <!-- START SNIPPET: example -->
* <!--
* The redirect URL generated will be:
* /foo.jsp#FRAGMENT
* -->
* <result name="success" type="redirect">
* <param name="location">foo.jsp</param>
* <param name="parse">false</param>
* <param name="anchor">FRAGMENT</param>
* </result>
* <!-- END SNIPPET: example -->
* </pre>
*
*/
public class ServletRedirectResult extends StrutsResultSupport implements ReflectionExceptionHandler {
private static final long serialVersionUID = 6316947346435301270L;
private static final Logger LOG = LoggerFactory.getLogger(ServletRedirectResult.class);
protected boolean prependServletContext = true;
protected ActionMapper actionMapper;
protected int statusCode = SC_FOUND;
protected boolean suppressEmptyParameters = false;
protected Map<String, String> requestParameters = new LinkedHashMap<String, String>();
protected String anchor;
public ServletRedirectResult() {
super();
}
public ServletRedirectResult(String location) {
this(location, null);
}
public ServletRedirectResult(String location, String anchor) {
super(location);
this.anchor = anchor;
}
@Inject
public void setActionMapper(ActionMapper mapper)
{
this.actionMapper = mapper;
}
public void setStatusCode(int code)
{
this.statusCode = code;
}
/**
* Set the optional anchor value.
*
* @param anchor
*/
public void setAnchor(String anchor)
{
this.anchor = anchor;
}
/**
* Sets whether or not to prepend the servlet context path to the redirected
* URL.
*
* @param prependServletContext
* <tt>true</tt> to prepend the location with the servlet context
* path, <tt>false</tt> otherwise.
*/
public void setPrependServletContext(boolean prependServletContext)
{
this.prependServletContext = prependServletContext;
}
public void execute(ActionInvocation invocation) throws Exception
{
if (anchor != null)
{
anchor = conditionalParse(anchor, invocation);
}
super.execute(invocation);
}
/**
* Redirects to the location specified by calling
* {@link HttpServletResponse#sendRedirect(String)}.
*
* @param finalLocation
* the location to redirect to.
* @param invocation
* an encapsulation of the action execution state.
* @throws Exception
* if an error occurs when redirecting.
*/
protected void doExecute(String finalLocation, ActionInvocation invocation) throws Exception
{
ActionContext ctx = invocation.getInvocationContext();
HttpServletRequest request = (HttpServletRequest) ctx.get(ServletActionContext.HTTP_REQUEST);
HttpServletResponse response = (HttpServletResponse) ctx.get(ServletActionContext.HTTP_RESPONSE);
if (isPathUrl(finalLocation))
{
if (!finalLocation.startsWith("/"))
{
ActionMapping mapping = actionMapper.getMapping(request, Dispatcher.getInstance().getConfigurationManager());
String namespace = null;
if (mapping != null)
{
namespace = mapping.getNamespace();
}
if ((namespace != null) && (namespace.length() > 0) && (!"/".equals(namespace)))
{
finalLocation = namespace + "/" + finalLocation;
}
else
{
finalLocation = "/" + finalLocation;
}
}
// if the URL's are relative to the servlet context, append the servlet context path
if (prependServletContext && (request.getContextPath() != null) && (request.getContextPath().length() > 0))
{
finalLocation = request.getContextPath() + finalLocation;
}
ResultConfig resultConfig = invocation.getProxy().getConfig().getResults().get(invocation.getResultCode());
if (resultConfig != null)
{
Map<String, String> resultConfigParams = resultConfig.getParams();
for (Map.Entry<String, String> e : resultConfigParams.entrySet())
{
if (!getProhibitedResultParams().contains(e.getKey()))
{
String potentialValue = e.getValue() == null ? "" : conditionalParse(e.getValue(), invocation);
if (!suppressEmptyParameters || ((potentialValue != null) && (potentialValue.length() > 0)))
{
requestParameters.put(e.getKey(), potentialValue);
}
}
}
}
StringBuilder tmpLocation = new StringBuilder(finalLocation);
UrlHelper.buildParametersString(requestParameters, tmpLocation, "&");
// add the anchor
if (anchor != null)
{
tmpLocation.append('#').append(anchor);
}
finalLocation = response.encodeRedirectURL(tmpLocation.toString());
}
if (LOG.isDebugEnabled())
{
LOG.debug("Redirecting to finalLocation " + finalLocation);
}
sendRedirect(response, finalLocation);//////
}
protected List<String> getProhibitedResultParams()
{
return Arrays.asList(DEFAULT_PARAM, "namespace", "method", "encode", "parse", "location", "prependServletContext", "suppressEmptyParameters", "anchor");
}
/**
* Sends the redirection. Can be overridden to customize how the redirect is
* handled (i.e. to use a different status code)
*
* @param response
* The response
* @param finalLocation
* The location URI
* @throws IOException
*/
protected void sendRedirect(HttpServletResponse response, String finalLocation) throws IOException
{
if (SC_FOUND == statusCode)
{
response.sendRedirect(finalLocation);//
}
else
{
response.setStatus(statusCode);
response.setHeader("Location", finalLocation);
response.getWriter().write(finalLocation);
response.getWriter().close();
}
}
private static boolean isPathUrl(String url)
{
// filter out "http:", "https:", "mailto:", "file:", "ftp:"
// since the only valid places for : in URL's is before the path specification
// either before the port, or after the protocol
return (url.indexOf(':') == -1);
}
/**
* Sets the suppressEmptyParameters option
*
* @param suppressEmptyParameters
* The new value for this option
*/
public void setSuppressEmptyParameters(boolean suppressEmptyParameters)
{
this.suppressEmptyParameters = suppressEmptyParameters;
}
/**
* Adds a request parameter to be added to the redirect url
*
* @param key
* The parameter name
* @param value
* The parameter value
*/
public ServletRedirectResult addParameter(String key, Object value)
{
requestParameters.put(key, String.valueOf(value));
return this;
}
public void handle(ReflectionException ex)
{
// Only log as debug as they are probably parameters to be appended to the url
LOG.debug(ex.getMessage(), ex);
}
}
私のactionに書かれているコード:
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@SuppressWarnings("serial")
public class SkipLoginAction extends Action {
@Inject
private PhoneService phoneService;
/**
* @return
* @throws ActionException
*/
public void index() throws ActionException {
try {
HttpServletRequest request =getRequest();
HttpServletResponse response = getResponse();
AuthBean authBean = null;
// RequestDispatcher dispatcher = request.getRequestDispatcher(url_pa);
// dispatcher.forward(request, response);
// , ,
//
String sessionid = request.getParameter("sessionid");
String finalLocation = request.getParameter("url");
String phoneId = request.getParameter("phoneId");
String contextpath = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + contextpath;
if(!StringUtils.isBlank(finalLocation) && !StringUtils.isBlank(sessionid) ){
if(!finalLocation.startsWith("/")){
finalLocation = "/" + finalLocation;
}
HttpSession session = request.getSession();
authBean = getAuthBean();
if(authBean!=null){
if(phoneId.equals(authBean.getPhoneId())){
response.sendRedirect(basePath+finalLocation);
return;
}
}
//// user sessionid
Phone phone = phoneService.findPhoneByPhoneId(phoneId);
if(phone!=null){
if( sessionid.equals(phone.getSessionid())){
//
authBean = null;
authBean = new AuthBean();
。。。。
response.sendRedirect(basePath+finalLocation);
return;
}
}
}
//
finalLocation = "/web/login.index";
response.sendRedirect(basePath+finalLocation);
} catch (Exception e) {
throw new ActionException(" ");
}
}
}