NIHVIVO-2701 Specify status code 303 when redirecting to RDF in IndividualController. Some incidental refactoring to allow for status codes in TemplateResponseValues objects.

This commit is contained in:
ryounes 2011-06-17 14:33:46 +00:00
parent d7f7155f1b
commit 996cb3be85
6 changed files with 68 additions and 28 deletions

View file

@ -185,15 +185,23 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
// Tell the template and any directives it uses that we're processing a page template.
templateDataModel.put("templateType", PAGE_TEMPLATE_TYPE);
writePage(templateDataModel, config, vreq, response);
writePage(templateDataModel, config, vreq, response, values.getStatusCode());
}
protected void doRedirect(HttpServletRequest request, HttpServletResponse response, ResponseValues values)
throws ServletException, IOException {
String redirectUrl = values.getRedirectUrl();
setResponseStatus(response, values.getStatusCode());
response.sendRedirect(redirectUrl);
}
private void setResponseStatus(HttpServletResponse response, int statusCode) {
if (statusCode > 0) {
response.setStatus(statusCode);
}
}
protected void doForward(HttpServletRequest request, HttpServletResponse response, ResponseValues values)
throws ServletException, IOException {
String forwardUrl = values.getForwardUrl();
@ -369,11 +377,6 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
// This value is used only in stylesheets.ftl and already contains the context path.
map.put("stylesheetPath", UrlBuilder.getUrl(themeDir + "/css"));
// String bannerImage = portal.getBannerImage();
// if ( ! StringUtils.isEmpty(bannerImage)) {
// map.put("bannerImage", UrlBuilder.getUrl(themeDir + "site_icons/" + bannerImage));
// }
String flashMessage = DisplayMessage.getMessageAndClear(vreq);
if (! flashMessage.isEmpty()) {
map.put("flash", flashMessage);
@ -452,18 +455,24 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
}
protected void writePage(Map<String, Object> root, Configuration config,
HttpServletRequest request, HttpServletResponse response) throws TemplateProcessingException {
writeTemplate(getPageTemplateName(), root, config, request, response);
HttpServletRequest request, HttpServletResponse response, int statusCode) throws TemplateProcessingException {
writeTemplate(getPageTemplateName(), root, config, request, response, statusCode);
}
protected void writeTemplate(String templateName, Map<String, Object> map, Configuration config,
HttpServletRequest request, HttpServletResponse response) throws TemplateProcessingException {
StringWriter sw = processTemplate(templateName, map, config, request);
write(sw, response);
writeTemplate(templateName, map, config, request, response, 0);
}
protected void write(StringWriter sw, HttpServletResponse response) {
protected void writeTemplate(String templateName, Map<String, Object> map, Configuration config,
HttpServletRequest request, HttpServletResponse response, int statusCode) throws TemplateProcessingException {
StringWriter sw = processTemplate(templateName, map, config, request);
write(sw, response, statusCode);
}
protected void write(StringWriter sw, HttpServletResponse response, int statusCode) {
try {
setResponseStatus(response, statusCode);
PrintWriter out = response.getWriter();
out.print(sw);
} catch (IOException e) {

View file

@ -100,7 +100,7 @@ public class IndividualController extends FreemarkerHttpServlet {
// Check to see if the request is for a non-information resource, redirect if it is.
String redirectURL = checkForRedirect ( url, vreq );
if( redirectURL != null ){
return new RedirectResponseValues(redirectURL);
return new RedirectResponseValues(redirectURL, HttpServletResponse.SC_SEE_OTHER);
}
Individual individual = null;
@ -464,11 +464,18 @@ public class IndividualController extends FreemarkerHttpServlet {
return null;
}
private static Pattern URI_PATTERN = Pattern.compile("^/individual/([^/]*)$");
//Redirect if the request is for http://hostname/individual/localname
// if accept is nothing or text/html redirect to ???
// if accept is some RDF thing redirect to the URL for RDF
/*
* Following recipe 3 from "Best Practice Recipes for Publishing RDF Vocabularies."
* See http://www.w3.org/TR/swbp-vocab-pub/#recipe3.
* The basic idea is that a URI like http://vivo.cornell.edu/individual/n1234
* identifies a real world individual. HTTP cannot send that as the response
* to a GET request because it can only send bytes and not things. The server
* sends a 303, to mean "you asked for something I cannot send you, but I can
* send you this other stream of bytes about that thing."
* In the case of a request like http://vivo.cornell.edu/individual/n1234/n1234.rdf,
* the request is for a set of bytes rather than an individual, so no 303 is needed.
*/
private static Pattern URI_PATTERN = Pattern.compile("^/individual/([^/]*)$");
private String checkForRedirect(String url, VitroRequest vreq) {
Matcher m = URI_PATTERN.matcher(url);
if( m.matches() && m.groupCount() == 1 ){
@ -506,7 +513,11 @@ public class IndividualController extends FreemarkerHttpServlet {
protected ContentType checkForLinkedDataRequest(String url, VitroRequest vreq ) {
try {
Matcher m;
// Check for url param specifying format
/*
* Check for url param specifying format.
* Example: http://vivo.cornell.edu/individual/n23?format=rdfxml
* This request will trigger a redirect with a 303.
*/
String formatParam = (String) vreq.getParameter("format");
if (formatParam != null) {
m = RDFXML_FORMAT.matcher(formatParam);
@ -523,7 +534,11 @@ public class IndividualController extends FreemarkerHttpServlet {
}
}
//check the accept header
/*
* Check the accept header. This request will trigger a
* redirect with a 303, because the request is for an individual
* but the server can only provide a set of bytes.
*/
String acceptHeader = vreq.getHeader("accept");
if (acceptHeader != null) {
String ctStr = ContentType.getBestContentType(
@ -538,10 +553,12 @@ public class IndividualController extends FreemarkerHttpServlet {
}
/*
* check for parts of URL that indicate request for RDF
http://vivo.cornell.edu/individual/n23/n23.rdf
http://vivo.cornell.edu/individual/n23/n23.n3
http://vivo.cornell.edu/individual/n23/n23.ttl
* Check for parts of URL that indicate request for RDF
* http://vivo.cornell.edu/individual/n23/n23.rdf
* http://vivo.cornell.edu/individual/n23/n23.n3
* http://vivo.cornell.edu/individual/n23/n23.ttl
* This request will not trigger a redirect and 303, because
* the request is for a set of bytes rather than an individual.
*/
m = RDF_REQUEST.matcher(url);
if( m.matches() ) {
@ -556,7 +573,6 @@ public class IndividualController extends FreemarkerHttpServlet {
return ContentType.TURTLE;
}
} catch (Throwable th) {
log.error("problem while checking accept header " , th);
}

View file

@ -23,6 +23,11 @@ public abstract class BaseResponseValues implements ResponseValues {
this.contentType = contentType;
}
BaseResponseValues(ContentType contentType, int statusCode) {
this.contentType = contentType;
this.statusCode = statusCode;
}
@Override
public int getStatusCode() {
return statusCode;
@ -38,6 +43,7 @@ public abstract class BaseResponseValues implements ResponseValues {
return contentType;
}
@Override
public void setContentType(ContentType contentType) {
this.contentType = contentType;
}

View file

@ -14,6 +14,11 @@ public class RdfResponseValues extends BaseResponseValues {
this.model = model;
}
public RdfResponseValues(ContentType contentType, Model model, int statusCode) {
super(contentType, statusCode);
this.model = model;
}
@Override
public Model getModel() {
return model;

View file

@ -28,6 +28,8 @@ public interface ResponseValues {
public ContentType getContentType();
public void setContentType(ContentType contentType);
public Model getModel();
}

View file

@ -49,7 +49,9 @@ public class TemplateResponseValues extends BaseResponseValues {
}
public static TemplateResponseValues getTemplateResponseValuesFromException(ExceptionResponseValues responseValues) {
return new TemplateResponseValues(responseValues.getTemplateName(), responseValues.getMap());
return new TemplateResponseValues(responseValues.getTemplateName(),
responseValues.getMap(),
responseValues.getStatusCode());
}
}