Sfoglia il codice sorgente

modify search result page

Shinsuke Sugaya 9 anni fa
parent
commit
2799bf6975

+ 2 - 1
src/main/java/org/codelibs/fess/app/web/cache/CacheAction.java

@@ -20,6 +20,7 @@ import java.util.Map;
 
 import org.codelibs.fess.Constants;
 import org.codelibs.fess.app.web.base.FessSearchAction;
+import org.codelibs.fess.util.DocumentUtil;
 import org.elasticsearch.index.query.QueryBuilders;
 import org.elasticsearch.index.query.TermQueryBuilder;
 import org.lastaflute.web.Execute;
@@ -73,7 +74,7 @@ public class CacheAction extends FessSearchAction {
             }, () -> asHtml(path_ErrorJsp));
         }
 
-        return asStream((String) doc.get(fieldHelper.docIdField)).contentType("text/html; charset=UTF-8").data(
+        return asStream(DocumentUtil.getValue(doc, fieldHelper.docIdField, String.class)).contentType("text/html; charset=UTF-8").data(
                 content.getBytes(Constants.CHARSET_UTF_8));
     }
 

+ 13 - 14
src/main/java/org/codelibs/fess/app/web/go/GoAction.java

@@ -33,10 +33,12 @@ import org.codelibs.fess.es.exentity.ClickLog;
 import org.codelibs.fess.helper.SearchLogHelper;
 import org.codelibs.fess.helper.ViewHelper;
 import org.codelibs.fess.util.ComponentUtil;
+import org.codelibs.fess.util.DocumentUtil;
 import org.codelibs.robot.util.CharUtil;
 import org.elasticsearch.index.query.QueryBuilders;
 import org.elasticsearch.index.query.TermQueryBuilder;
 import org.lastaflute.web.Execute;
+import org.lastaflute.web.response.ActionResponse;
 import org.lastaflute.web.response.HtmlResponse;
 import org.lastaflute.web.util.LaResponseUtil;
 import org.slf4j.Logger;
@@ -61,7 +63,7 @@ public class GoAction extends FessSearchAction {
     //                                                                      Search Execute
     //                                                                      ==============
     @Execute
-    public HtmlResponse index(final GoForm form) throws IOException {
+    public ActionResponse index(final GoForm form) throws IOException {
         searchAvailable();
 
         Map<String, Object> doc = null;
@@ -80,13 +82,12 @@ public class GoAction extends FessSearchAction {
                 messages.addErrorsDocidNotFound(GLOBAL, form.docId);
             }, () -> asHtml(path_ErrorJsp));
         }
-        final Object urlObj = doc.get(fieldHelper.urlField);
-        if (urlObj == null) {
+        final String url = DocumentUtil.getValue(doc, fieldHelper.urlField, String.class);
+        if (url == null) {
             throwValidationError(messages -> {
                 messages.addErrorsDocumentNotFound(GLOBAL, form.docId);
             }, () -> asHtml(path_ErrorJsp));
         }
-        final String url = urlObj.toString();
 
         if (Constants.TRUE.equals(crawlerProperties.getProperty(Constants.SEARCH_LOG_PROPERTY, Constants.TRUE))) {
             final String userSessionId = userInfoHelper.getUserCode();
@@ -100,9 +101,9 @@ public class GoAction extends FessSearchAction {
                 clickLog.setUserSessionId(userSessionId);
                 clickLog.setDocId(form.docId);
                 long clickCount = 0;
-                final Object count = doc.get(fieldHelper.clickCountField);
-                if (count instanceof Long) {
-                    clickCount = ((Long) count).longValue();
+                final Integer count = DocumentUtil.getValue(doc, fieldHelper.clickCountField, Integer.class);
+                if (count != null) {
+                    clickCount = count.longValue();
                 }
                 clickLog.setClickCount(clickCount);
                 searchLogHelper.addClickLog(clickLog);
@@ -133,13 +134,13 @@ public class GoAction extends FessSearchAction {
             if (Constants.TRUE.equals(crawlerProperties.getProperty(Constants.SEARCH_FILE_PROXY_PROPERTY, Constants.TRUE))) {
                 final ViewHelper viewHelper = ComponentUtil.getViewHelper();
                 try {
-                    viewHelper.writeContent(doc);
-                    return null;
+                    return viewHelper.asContentResponse(doc);
                 } catch (final Exception e) {
                     logger.error("Failed to load: " + doc, e);
                     throwValidationError(messages -> {
                         messages.addErrorsNotLoadFromServer(GLOBAL, url);
                     }, () -> asHtml(path_ErrorJsp));
+                    return null; // workaround
                 }
             } else if (Constants.TRUE.equals(crawlerProperties.getProperty(Constants.SEARCH_DESKTOP_PROPERTY, Constants.FALSE))) {
                 final String path = url.replaceFirst("file:/+", "//");
@@ -159,15 +160,13 @@ public class GoAction extends FessSearchAction {
                     }, () -> asHtml(path_ErrorJsp));
                 }
 
-                LaResponseUtil.getResponse().setStatus(HttpServletResponse.SC_NO_CONTENT);
-                return null;
+                return HtmlResponse.asEmptyBody().httpStatus(HttpServletResponse.SC_NO_CONTENT);
             } else {
-                LaResponseUtil.getResponse().sendRedirect(url + hash);
+                return newHtmlResponseAsRediect(url + hash);
             }
         } else {
-            LaResponseUtil.getResponse().sendRedirect(url + hash);
+            return newHtmlResponseAsRediect(url + hash);
         }
-        return null;
     }
 
     protected boolean isFileSystemPath(final String url) {

+ 2 - 1
src/main/java/org/codelibs/fess/app/web/screenshot/ScreenshotAction.java

@@ -30,6 +30,7 @@ import org.codelibs.core.io.CopyUtil;
 import org.codelibs.core.io.OutputStreamUtil;
 import org.codelibs.core.lang.StringUtil;
 import org.codelibs.fess.app.web.base.FessSearchAction;
+import org.codelibs.fess.util.DocumentUtil;
 import org.elasticsearch.index.query.QueryBuilders;
 import org.elasticsearch.index.query.TermQueryBuilder;
 import org.lastaflute.web.Execute;
@@ -70,7 +71,7 @@ public class ScreenshotAction extends FessSearchAction {
                 queryRequestBuilder.addFields(queryHelper.getResponseFields());
                 return true;
             }).get();
-            final String url = doc == null ? null : (String) doc.get(fieldHelper.urlField);
+            final String url = DocumentUtil.getValue(doc, fieldHelper.urlField, String.class);
             if (StringUtil.isBlank(form.queryId) || StringUtil.isBlank(url) || screenShotManager == null) {
                 // 404
                 response.sendError(HttpServletResponse.SC_NOT_FOUND);

+ 21 - 2
src/main/java/org/codelibs/fess/client/FessEsClient.java

@@ -11,6 +11,7 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Optional;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
@@ -131,6 +132,7 @@ import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.transport.InetSocketTransportAddress;
 import org.elasticsearch.common.transport.TransportAddress;
 import org.elasticsearch.common.unit.TimeValue;
+import org.elasticsearch.index.get.GetField;
 import org.elasticsearch.index.query.BoolFilterBuilder;
 import org.elasticsearch.index.query.FilterBuilders;
 import org.elasticsearch.index.query.QueryBuilder;
@@ -138,6 +140,7 @@ import org.elasticsearch.index.query.QueryBuilders;
 import org.elasticsearch.indices.IndexAlreadyExistsException;
 import org.elasticsearch.indices.IndexMissingException;
 import org.elasticsearch.search.SearchHit;
+import org.elasticsearch.search.SearchHitField;
 import org.elasticsearch.search.aggregations.AggregationBuilders;
 import org.elasticsearch.search.aggregations.bucket.filter.FilterAggregationBuilder;
 import org.elasticsearch.search.aggregations.bucket.terms.TermsBuilder;
@@ -501,7 +504,15 @@ public class FessEsClient implements Client {
     public Optional<Map<String, Object>> getDocument(final String index, final String type,
             final SearchCondition<SearchRequestBuilder> condition) {
         return getDocument(index, type, condition, (response, hit) -> {
-            return hit.getSource();
+            Map<String, Object> source = hit.getSource();
+            if (source != null) {
+                return source;
+            }
+            Map<String, SearchHitField> fields = hit.getFields();
+            if (fields != null) {
+                return fields.entrySet().stream().collect(Collectors.toMap(e -> e.getKey(), e -> (Object) e.getValue().getValues()));
+            }
+            return null;
         });
     }
 
@@ -521,7 +532,15 @@ public class FessEsClient implements Client {
     public Optional<Map<String, Object>> getDocument(final String index, final String type, final String id,
             final SearchCondition<GetRequestBuilder> condition) {
         return getDocument(index, type, id, condition, (response, result) -> {
-            return response.getSource();
+            Map<String, Object> source = response.getSource();
+            if (source != null) {
+                return source;
+            }
+            Map<String, GetField> fields = response.getFields();
+            if (fields != null) {
+                return fields.entrySet().stream().collect(Collectors.toMap(e -> e.getKey(), e -> (Object) e.getValue().getValues()));
+            }
+            return null;
         });
     }
 

+ 38 - 43
src/main/java/org/codelibs/fess/helper/ViewHelper.java

@@ -17,11 +17,9 @@
 package org.codelibs.fess.helper;
 
 import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.OutputStream;
 import java.io.Serializable;
 import java.io.UnsupportedEncodingException;
 import java.net.URLDecoder;
@@ -39,12 +37,9 @@ import java.util.regex.Pattern;
 import javax.annotation.PostConstruct;
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 
-import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.codelibs.core.CoreLibConstants;
-import org.codelibs.core.io.CopyUtil;
 import org.codelibs.core.lang.StringUtil;
 import org.codelibs.core.misc.Base64Util;
 import org.codelibs.core.misc.DynamicProperties;
@@ -59,6 +54,7 @@ import org.codelibs.fess.es.exentity.CrawlingConfig;
 import org.codelibs.fess.es.exentity.CrawlingConfig.ConfigType;
 import org.codelibs.fess.helper.UserAgentHelper.UserAgentType;
 import org.codelibs.fess.util.ComponentUtil;
+import org.codelibs.fess.util.DocumentUtil;
 import org.codelibs.fess.util.ResourceUtil;
 import org.codelibs.robot.builder.RequestDataBuilder;
 import org.codelibs.robot.client.S2RobotClient;
@@ -67,6 +63,7 @@ import org.codelibs.robot.entity.ResponseData;
 import org.codelibs.robot.util.CharUtil;
 import org.lastaflute.di.core.SingletonLaContainer;
 import org.lastaflute.taglib.function.LaFunctions;
+import org.lastaflute.web.response.StreamResponse;
 import org.lastaflute.web.util.LaRequestUtil;
 import org.lastaflute.web.util.LaResponseUtil;
 import org.lastaflute.web.util.LaServletContextUtil;
@@ -398,18 +395,20 @@ public class ViewHelper implements Serializable {
         if (locale == null) {
             locale = Locale.ENGLISH;
         }
-        String url = (String) doc.get("urlLink");
+        String url = DocumentUtil.getValue(doc, "urlLink", String.class);
         if (url == null) {
             url = ComponentUtil.getMessageManager().getMessage(locale, "labels.search_unknown");
         }
-        Object created = doc.get(fieldHelper.createdField);
-        if (created instanceof Date) {
+        String createdStr;
+        Long created = DocumentUtil.getValue(doc, fieldHelper.createdField, Long.class);
+        if (created != null) {
             final SimpleDateFormat sdf = new SimpleDateFormat(CoreLibConstants.DATE_FORMAT_ISO_8601_EXTEND);
-            created = sdf.format((Date) created);
+            createdStr = sdf.format(new Date(created.longValue()));
         } else {
-            created = ComponentUtil.getMessageManager().getMessage(locale, "labels.search_unknown");
+            createdStr = ComponentUtil.getMessageManager().getMessage(locale, "labels.search_unknown");
         }
-        doc.put("cacheMsg", ComponentUtil.getMessageManager().getMessage(locale, "labels.search_cache_msg", new Object[] { url, created }));
+        doc.put("cacheMsg",
+                ComponentUtil.getMessageManager().getMessage(locale, "labels.search_cache_msg", new Object[] { url, createdStr }));
 
         doc.put("queries", queries);
 
@@ -476,7 +475,7 @@ public class ViewHelper implements Serializable {
         return null;
     }
 
-    public void writeContent(final Map<String, Object> doc) {
+    public StreamResponse asContentResponse(final Map<String, Object> doc) {
         if (logger.isDebugEnabled()) {
             logger.debug("writing the content of: " + doc);
         }
@@ -516,37 +515,32 @@ public class ViewHelper implements Serializable {
             throw new FessSystemException("No S2RobotClient: " + configIdObj + ", url: " + url);
         }
         final ResponseData responseData = client.execute(RequestDataBuilder.newRequestData().get().url(url).build());
-        final HttpServletResponse response = LaResponseUtil.getResponse();
+        StreamResponse response = new StreamResponse(StringUtil.EMPTY);
         writeFileName(response, responseData);
         writeContentType(response, responseData);
         writeNoCache(response, responseData);
-        InputStream is = null;
-        OutputStream os = null;
-        try {
-            is = new BufferedInputStream(responseData.getResponseBody());
-            os = new BufferedOutputStream(response.getOutputStream());
-            CopyUtil.copy(is, os);
-            os.flush();
-        } catch (final IOException e) {
-            if (!"ClientAbortException".equals(e.getClass().getSimpleName())) {
-                throw new FessSystemException("Failed to write a content. configId: " + configIdObj + ", url: " + url, e);
+        response.stream(out -> {
+            try (InputStream is = new BufferedInputStream(responseData.getResponseBody())) {
+                out.write(is);
+            } catch (final IOException e) {
+                if (!"ClientAbortException".equals(e.getClass().getSimpleName())) {
+                    throw new FessSystemException("Failed to write a content. configId: " + configIdObj + ", url: " + url, e);
+                }
             }
-        } finally {
-            IOUtils.closeQuietly(is);
-            IOUtils.closeQuietly(os);
-        }
-        if (logger.isDebugEnabled()) {
-            logger.debug("Finished to write " + url);
-        }
+            if (logger.isDebugEnabled()) {
+                logger.debug("Finished to write " + url);
+            }
+        });
+        return response;
     }
 
-    protected void writeNoCache(final HttpServletResponse response, final ResponseData responseData) {
-        response.setHeader("Pragma", "no-cache");
-        response.setHeader("Cache-Control", "no-cache");
-        response.setHeader("Expires", "Thu, 01 Dec 1994 16:00:00 GMT");
+    protected void writeNoCache(final StreamResponse response, final ResponseData responseData) {
+        response.header("Pragma", "no-cache");
+        response.header("Cache-Control", "no-cache");
+        response.header("Expires", "Thu, 01 Dec 1994 16:00:00 GMT");
     }
 
-    protected void writeFileName(final HttpServletResponse response, final ResponseData responseData) {
+    protected void writeFileName(final StreamResponse response, final ResponseData responseData) {
         final UserAgentHelper userAgentHelper = ComponentUtil.getUserAgentHelper();
         final UserAgentType userAgentType = userAgentHelper.getUserAgentType();
         String charset = responseData.getCharSet();
@@ -569,19 +563,19 @@ public class ViewHelper implements Serializable {
 
             switch (userAgentType) {
             case IE:
-                response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(name, Constants.UTF_8) + "\"");
+                response.header("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(name, Constants.UTF_8) + "\"");
                 break;
             case OPERA:
-                response.setHeader("Content-Disposition", "attachment; filename*=utf-8'ja'" + URLEncoder.encode(name, Constants.UTF_8));
+                response.header("Content-Disposition", "attachment; filename*=utf-8'ja'" + URLEncoder.encode(name, Constants.UTF_8));
                 break;
             case SAFARI:
-                response.setHeader("Content-Disposition", "attachment; filename=\"" + name + "\"");
+                response.header("Content-Disposition", "attachment; filename=\"" + name + "\"");
                 break;
             case CHROME:
             case FIREFOX:
             case OTHER:
             default:
-                response.setHeader("Content-Disposition",
+                response.header("Content-Disposition",
                         "attachment; filename=\"=?utf-8?B?" + Base64Util.encode(name.getBytes(Constants.UTF_8)) + "?=\"");
                 break;
             }
@@ -590,22 +584,23 @@ public class ViewHelper implements Serializable {
         }
     }
 
-    protected void writeContentType(final HttpServletResponse response, final ResponseData responseData) {
+    protected void writeContentType(final StreamResponse response, final ResponseData responseData) {
         final String mimeType = responseData.getMimeType();
         if (logger.isDebugEnabled()) {
             logger.debug("mimeType: " + mimeType);
         }
         if (mimeType == null) {
+            response.contentTypeOctetStream();
             return;
         }
         if (mimeType.startsWith("text/")) {
-            final String charset = response.getCharacterEncoding();
+            final String charset = LaResponseUtil.getResponse().getCharacterEncoding();
             if (charset != null) {
-                response.setContentType(mimeType + "; charset=" + charset);
+                response.contentType(mimeType + "; charset=" + charset);
                 return;
             }
         }
-        response.setContentType(mimeType);
+        response.contentType(mimeType);
     }
 
     public boolean isUseSession() {

+ 3 - 2
src/main/java/org/codelibs/fess/screenshot/ScreenShotManager.java

@@ -36,6 +36,7 @@ import org.codelibs.fess.Constants;
 import org.codelibs.fess.FessSystemException;
 import org.codelibs.fess.helper.FieldHelper;
 import org.codelibs.fess.util.ComponentUtil;
+import org.codelibs.fess.util.DocumentUtil;
 import org.lastaflute.web.util.LaRequestUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -112,7 +113,7 @@ public class ScreenShotManager {
         final FieldHelper fieldHelper = ComponentUtil.getFieldHelper();
         for (final ScreenShotGenerator generator : generatorList) {
             if (generator.isTarget(docMap)) {
-                final String url = (String) docMap.get(fieldHelper.urlField);
+                final String url = DocumentUtil.getValue(docMap, fieldHelper.urlField, String.class);
                 final String path = getImageFilename(docMap);
                 if (!screenShotTaskQueue.offer(new ScreenShotTask(url, new File(baseDir, path), generator))) {
                     logger.warn("Failed to offer a screenshot task: " + url + " -> " + path);
@@ -125,7 +126,7 @@ public class ScreenShotManager {
     protected String getImageFilename(final Map<String, Object> docMap) {
         final StringBuilder buf = new StringBuilder(50);
         final FieldHelper fieldHelper = ComponentUtil.getFieldHelper();
-        final String docid = (String) docMap.get(fieldHelper.docIdField);
+        final String docid = DocumentUtil.getValue(docMap, fieldHelper.docIdField, String.class);
         for (int i = 0; i < docid.length(); i++) {
             if (i > 0 && i % splitSize == 0) {
                 buf.append('/');

+ 35 - 0
src/main/java/org/codelibs/fess/util/DocumentUtil.java

@@ -0,0 +1,35 @@
+package org.codelibs.fess.util;
+
+import java.util.List;
+import java.util.Map;
+
+public final class DocumentUtil {
+
+    private DocumentUtil() {
+    }
+
+    public static <T> T getValue(Map<String, Object> doc, String key, Class<T> clazz) {
+        if (doc == null || key == null) {
+            return null;
+        }
+
+        Object value = doc.get(key);
+        if (value == null) {
+            return null;
+        }
+
+        if (value instanceof List) {
+            if (clazz.isAssignableFrom(List.class)) {
+                return (T) value;
+            }
+
+            if (((List<?>) value).isEmpty()) {
+                return null;
+            }
+
+            return (T) ((List) value).get(0);
+        }
+
+        return (T) value;
+    }
+}

+ 12 - 12
src/main/webapp/WEB-INF/view/searchResults.jsp

@@ -29,15 +29,15 @@
 			<c:forEach var="doc" varStatus="s" items="${documentItems}">
 				<li id="result${s.index}">
 					<h3 class="title ellipsis">
-						<a class="link" href="${doc.urlLink}" data-uri="${doc.urlLink}" data-id="${doc.docId}">${f:h(doc.contentTitle)}</a>
+						<a class="link" href="${doc.urlLink}" data-uri="${doc.urlLink}" data-id="${doc.doc_id}">${f:h(doc.contentTitle)}</a>
 					</h3>
 					<div class="body">
 						<div class="description">${doc.contentDescription}</div>
 						<div class="site ellipsis">
 							<cite>${f:h(doc.sitePath)}</cite>
 							<c:if test="${doc.hasCache_s_s=='true'}">
-								<a href="cache?docId=${doc.docId}${appendHighlightQueries}" class="cache"><la:message
-										key="labels.search_result_cache" /></a>
+								<la:link href="/cache/?docId=${doc.doc_id}${appendHighlightQueries}" class="cache"><la:message
+										key="labels.search_result_cache" /></la:link>
 							</c:if>
 						</div>
 						<div class="more visible-phone">
@@ -47,27 +47,27 @@
 							<c:if test="${doc.created!=null && doc.created!=''}">
 								<c:set var="hasInfo" value="true"/>
 								<la:message key="labels.search_result_created" />
-								<fmt:formatDate value="${fe:parseDate(doc.created)}" type="BOTH" />
+								<fmt:formatDate value="${fe:date(doc.created)}" type="BOTH" />
 							</c:if>
-							<c:if test="${doc.lastModified!=null && doc.lastModified!=''}">
+							<c:if test="${doc.last_modified!=null && doc.last_modified!=''}">
 								<c:if test="${hasInfo}"><span class="br-phone"></span><span class="hidden-phone">-</span></c:if><c:set var="hasInfo" value="true"/>
-								<la:message key="labels.search_result_lastModified" />
-								<fmt:formatDate value="${fe:parseDate(doc.lastModified)}" type="BOTH" />
+								<la:message key="labels.search_result_last_modified" />
+								<fmt:formatDate value="${fe:date(doc.last_modified)}" type="BOTH" />
 							</c:if>
-							<c:if test="${doc.contentLength!=null && doc.contentLength!=''}">
+							<c:if test="${doc.content_length!=null && doc.content_length!=''}">
 								<c:if test="${hasInfo}"><span class="br-phone"></span><span class="hidden-phone">-</span></c:if><c:set var="hasInfo" value="true"/>
 								<la:message key="labels.search_result_size"
-									arg0="${f:h(doc.contentLength)}" />
+									arg0="${f:h(doc.content_length)}" />
 							</c:if>
 							<c:if test="${searchLogSupport}">
 								<c:if test="${hasInfo}"><span class="br-phone"></span><span class="hidden-phone">-</span></c:if><c:set var="hasInfo" value="true"/>
 								<la:message key="labels.search_click_count"
-									arg0="${f:h(doc.clickCount_l_x_dv)}" />
+									arg0="${f:h(doc.click_count)}" />
 							</c:if>
 							<c:if test="${favoriteSupport}">
 								<c:if test="${hasInfo}"><span class="br-phone"></span><span class="hidden-phone">-</span></c:if><c:set var="hasInfo" value="true"/>
-								<a href="#${doc.docId}" class="favorite"><la:message
-										key="labels.search_result_favorite" /> (${f:h(doc.favoriteCount_l_x_dv)})</a>
+								<a href="#${doc.doc_id}" class="favorite"><la:message
+										key="labels.search_result_favorite" /> (${f:h(doc.favorite_count)})</a>
 								<span class="favorited"><la:message
 										key="labels.search_result_favorited"/> <span class="favorited-count">(${f:h(doc.favoriteCount_l_x_dv)})</span></span>
 							</c:if>

+ 4 - 2
src/main/webapp/js/search.js

@@ -27,7 +27,8 @@ $(function(){
 			rt = $('#rt').val(),
 			url = $(this).attr('href'),
 			buf = [];
-		buf.push('go?rt=');
+		buf.push(contextPath);
+		buf.push('/go/?rt=');
 		buf.push(rt);
 		buf.push('&docId=');
 		buf.push(docId);
@@ -50,7 +51,8 @@ $(function(){
 				url = $(this).attr('href'),
 				queryId = $queryId.val(),
 				buf = [];
-			buf.push('go?rt=');
+		    buf.push(contextPath);
+			buf.push('/go/?rt=');
 			buf.push(rt);
 			buf.push('&docId=');
 			buf.push(docId);