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

@ -184,16 +184,24 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
templateDataModel.put("body", bodyString); templateDataModel.put("body", bodyString);
// Tell the template and any directives it uses that we're processing a page template. // Tell the template and any directives it uses that we're processing a page template.
templateDataModel.put("templateType", PAGE_TEMPLATE_TYPE); 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) protected void doRedirect(HttpServletRequest request, HttpServletResponse response, ResponseValues values)
throws ServletException, IOException { throws ServletException, IOException {
String redirectUrl = values.getRedirectUrl(); String redirectUrl = values.getRedirectUrl();
setResponseStatus(response, values.getStatusCode());
response.sendRedirect(redirectUrl); 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) protected void doForward(HttpServletRequest request, HttpServletResponse response, ResponseValues values)
throws ServletException, IOException { throws ServletException, IOException {
String forwardUrl = values.getForwardUrl(); 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. // This value is used only in stylesheets.ftl and already contains the context path.
map.put("stylesheetPath", UrlBuilder.getUrl(themeDir + "/css")); 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); String flashMessage = DisplayMessage.getMessageAndClear(vreq);
if (! flashMessage.isEmpty()) { if (! flashMessage.isEmpty()) {
map.put("flash", flashMessage); map.put("flash", flashMessage);
@ -452,18 +455,24 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
} }
protected void writePage(Map<String, Object> root, Configuration config, protected void writePage(Map<String, Object> root, Configuration config,
HttpServletRequest request, HttpServletResponse response) throws TemplateProcessingException { HttpServletRequest request, HttpServletResponse response, int statusCode) throws TemplateProcessingException {
writeTemplate(getPageTemplateName(), root, config, request, response); writeTemplate(getPageTemplateName(), root, config, request, response, statusCode);
} }
protected void writeTemplate(String templateName, Map<String, Object> map, Configuration config, protected void writeTemplate(String templateName, Map<String, Object> map, Configuration config,
HttpServletRequest request, HttpServletResponse response) throws TemplateProcessingException { HttpServletRequest request, HttpServletResponse response) throws TemplateProcessingException {
StringWriter sw = processTemplate(templateName, map, config, request); writeTemplate(templateName, map, config, request, response, 0);
write(sw, 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) { protected void write(StringWriter sw, HttpServletResponse response, int statusCode) {
try { try {
setResponseStatus(response, statusCode);
PrintWriter out = response.getWriter(); PrintWriter out = response.getWriter();
out.print(sw); out.print(sw);
} catch (IOException e) { } 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. // Check to see if the request is for a non-information resource, redirect if it is.
String redirectURL = checkForRedirect ( url, vreq ); String redirectURL = checkForRedirect ( url, vreq );
if( redirectURL != null ){ if( redirectURL != null ){
return new RedirectResponseValues(redirectURL); return new RedirectResponseValues(redirectURL, HttpServletResponse.SC_SEE_OTHER);
} }
Individual individual = null; Individual individual = null;
@ -463,12 +463,19 @@ public class IndividualController extends FreemarkerHttpServlet {
return null; return null;
} }
private static Pattern URI_PATTERN = Pattern.compile("^/individual/([^/]*)$"); /*
//Redirect if the request is for http://hostname/individual/localname * Following recipe 3 from "Best Practice Recipes for Publishing RDF Vocabularies."
// if accept is nothing or text/html redirect to ??? * See http://www.w3.org/TR/swbp-vocab-pub/#recipe3.
// if accept is some RDF thing redirect to the URL for RDF * 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) { private String checkForRedirect(String url, VitroRequest vreq) {
Matcher m = URI_PATTERN.matcher(url); Matcher m = URI_PATTERN.matcher(url);
if( m.matches() && m.groupCount() == 1 ){ if( m.matches() && m.groupCount() == 1 ){
@ -506,7 +513,11 @@ public class IndividualController extends FreemarkerHttpServlet {
protected ContentType checkForLinkedDataRequest(String url, VitroRequest vreq ) { protected ContentType checkForLinkedDataRequest(String url, VitroRequest vreq ) {
try { try {
Matcher m; 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"); String formatParam = (String) vreq.getParameter("format");
if (formatParam != null) { if (formatParam != null) {
m = RDFXML_FORMAT.matcher(formatParam); 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"); String acceptHeader = vreq.getHeader("accept");
if (acceptHeader != null) { if (acceptHeader != null) {
String ctStr = ContentType.getBestContentType( String ctStr = ContentType.getBestContentType(
@ -538,10 +553,12 @@ public class IndividualController extends FreemarkerHttpServlet {
} }
/* /*
* check for parts of URL that indicate request for RDF * 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.rdf
http://vivo.cornell.edu/individual/n23/n23.n3 * http://vivo.cornell.edu/individual/n23/n23.n3
http://vivo.cornell.edu/individual/n23/n23.ttl * 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); m = RDF_REQUEST.matcher(url);
if( m.matches() ) { if( m.matches() ) {
@ -555,8 +572,7 @@ public class IndividualController extends FreemarkerHttpServlet {
if( m.matches() ) { if( m.matches() ) {
return ContentType.TURTLE; return ContentType.TURTLE;
} }
} catch (Throwable th) { } catch (Throwable th) {
log.error("problem while checking accept header " , th); log.error("problem while checking accept header " , th);
} }

View file

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

View file

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

View file

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

View file

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