JavaXT
|
|
ServiceResponse Classpackage javaxt.express; import java.util.*; import java.io.IOException; import javaxt.json.*; import javaxt.http.servlet.HttpServletRequest; import javaxt.http.servlet.HttpServletResponse; //****************************************************************************** //** ServiceResponse //****************************************************************************** /** * Used to encapsulate a response to a ServiceRequest * ******************************************************************************/ public class ServiceResponse { private String contentType = "text/plain"; private String contentDisposition = null; private Long contentLength; private int status = 200; //private String statusMessage; //not generally used or required private javaxt.utils.Date date; //<--Used for eTags and 304 responses private String cacheControl; private String authMessage; private Object response; private HashMap<String, Object> properties = new HashMap<>(); public ServiceResponse(byte[] response){ this.response = response; this.contentLength = Long.valueOf(response.length); } public ServiceResponse(javaxt.io.File file){ this.contentType = file.getContentType(); this.contentLength = file.getSize(); this.response = file; } public ServiceResponse(java.io.InputStream response){ this.response = response; } public ServiceResponse(int status, String body){ this(getBytes(body)); this.status = status; } public ServiceResponse(String str){ this(200, str); } public ServiceResponse(StringBuffer str){ this(200, str.toString()); } public ServiceResponse(StringBuilder str){ this(200, str.toString()); } public ServiceResponse(JSONObject json){ this(200, json.toString()); this.contentType = "application/json"; } public ServiceResponse(JSONArray json){ this(200, json.toString()); this.contentType = "application/json"; } public ServiceResponse(javaxt.sql.Model model){ this(model.toJson()); } public ServiceResponse(int status){ this.status = status; } public ServiceResponse(Exception e){ this((Throwable) e); } public ServiceResponse(Throwable e){ this(500, (e.getMessage()==null || e.getMessage().trim().length()==0) ? "Unspecified Web Services Error" : e.getMessage()); //e.printStackTrace(); String s = e.getClass().getName(); s = s.substring(s.lastIndexOf(".")+1); String message = e.getLocalizedMessage(); StringBuilder error = new StringBuilder((message != null) ? (s + ": " + message) : s); //if (error.equalsIgnoreCase("NullPointerException")){ for (StackTraceElement x : e.getStackTrace()){ String err = x.toString(); if (err.trim().startsWith("org.eclipse.jetty")) break; error.append("\r\n"); error.append(x); } System.out.println(error); response = getBytes(error.toString()); } public void setContentType(String contentType){ this.contentType = contentType; } public String getContentType(){ return contentType; } public void setContentDisposition(String fileName){ if (fileName==null) contentDisposition = null; else contentDisposition = "attachment;filename=\"" + fileName + "\""; } public String getContentDisposition(){ return contentDisposition; } public void setDate(javaxt.utils.Date date){ this.date = date; } public javaxt.utils.Date getDate(){ if (date==null) return null; return date.clone(); } public void setContentLength(long contentLength){ this.contentLength = contentLength; } public Long getContentLength(){ return contentLength; } //e.g. "no-cache, no-transform" public void setCacheControl(String cacheControl){ this.cacheControl = cacheControl; } //e.g. "no-cache, no-transform" public String getCacheControl(){ return cacheControl; } // public void setStatus(int status){ // this.status = status; // } public int getStatus(){ return status; } // public String getStatusMessage(){ // return statusMessage; // } // // public void setStatusMessage(String msg){ // statusMessage = msg; // } // //"WWW-Authenticate", "Basic realm=\"Access Denied\"" public void setAuthMessage(String msg){ authMessage = msg; } public String getAuthMessage(){ return authMessage; } public void set(String key, Object val){ properties.put(key, val); } public Object get(String key){ return properties.get(key); } public Object getResponse() { return response; } //************************************************************************** //** send //************************************************************************** /** Used to send the response to a client by generating an * HttpServletResponse * @param response An HttpServletResponse to write to */ public void send(HttpServletResponse response) throws IOException { send(response, null); } //************************************************************************** //** send //************************************************************************** /** Used to send the response to a client by generating an * HttpServletResponse * @param response An HttpServletResponse to write to * @param req The ServiceRequest associated with this response */ public void send(HttpServletResponse response, ServiceRequest req) throws IOException { HttpServletRequest request = req==null ? null : req.getRequest(); if (status==307){ response.setStatus(307); String location = new String((byte[]) this.getResponse()); response.setHeader("Location", location); String msg = "<head>" + "<title>Document Moved</title>" + "</head>" + "<body>" + "<h1>Object Moved</h1>" + "This document may be found <a href=\"" + location + "\">here</a>" + "</body>"; response.write(msg); } else{ //Set general response headers response.setContentType(this.getContentType()); response.setStatus(status); //Set cache directives String eTag = (String) properties.get("ETag"); if (eTag!=null) response.setHeader("ETag", eTag); String lastModified = (String) properties.get("Last-Modified"); if (lastModified!=null) response.setHeader("Last-Modified", lastModified); //this.setHeader("Expires", "Sun, 30 Sep 2018 16:23:15 GMT "); if (cacheControl!=null) response.setHeader("Cache-Control", cacheControl); if (status==304) return; //Set authentication header as needed String authType = request==null ? null : request.getAuthType(); if (authMessage!=null && authType!=null){ //"WWW-Authenticate", "Basic realm=\"Access Denied\"" if (authType.equalsIgnoreCase("BASIC")){ response.setHeader("WWW-Authenticate", "Basic realm=\"" + authMessage + "\""); } } //Send body Object obj = this.getResponse(); if (obj instanceof javaxt.io.File){ javaxt.io.File file = (javaxt.io.File) obj; if (date!=null && request!=null){ javaxt.utils.URL url = new javaxt.utils.URL(request.getURL()); long currVersion = date.toLong(); long requestedVersion = 0; try{ requestedVersion = Long.parseLong(url.getParameter("v")); } catch(Exception e){} if (requestedVersion < currVersion){ url.setParameter("v", currVersion+""); response.sendRedirect(url.toString(), true); return; } else if (requestedVersion==currVersion){ response.setHeader("Cache-Control", "public, max-age=31536000, immutable"); } } //Set "Content-Disposition" header as needed String contentDisposition = this.getContentDisposition(); if (contentDisposition!=null) response.setHeader("Content-Disposition", contentDisposition); //Set fileName and contentType. Note that when a fileName is //provided, the server returns a "Content-Disposition" header //which we may be different than what the caller spefified in //this response. To avoid ambiguities, we'll rely exclusively //on whatever the user specified for the "Content-Disposition" String contentType = file.getContentType(); String fileName = null; //Send file response.write(file.toFile(), fileName, contentType, true); } else if (obj instanceof java.io.InputStream){ //Set Content-Length response header if (contentLength!=null){ response.setHeader("Content-Length", contentLength+""); } java.io.InputStream inputStream = (java.io.InputStream) obj; response.write(inputStream, true); inputStream.close(); } else{ response.write((byte[]) obj, true); } } } //************************************************************************** //** getBytes //************************************************************************** private static byte[] getBytes(String str){ try{ return str.getBytes("UTF-8"); } catch(Exception e){ return null; } } } |