List of usage examples for java.net HttpURLConnection setUseCaches
public void setUseCaches(boolean usecaches)
From source file:in.neoandroid.neoupdate.neoUpdate.java
/** * A Simpler HTTPConnection helper./* w w w .ja v a 2s .c o m*/ * Used currently. */ private static HttpURLConnection getHTTPConnection(String url) throws MalformedURLException, IOException { HttpURLConnection c; c = (HttpURLConnection) new URL(url).openConnection(); c.setUseCaches(false); c.connect(); return c; }
From source file:Main.java
@SuppressWarnings("resource") public static String post(String targetUrl, Map<String, String> params, String file, byte[] data) { Logd(TAG, "Starting post..."); String html = ""; Boolean cont = true;//from w w w. j a va2s . c om URL url = null; try { url = new URL(targetUrl); } catch (MalformedURLException e) { Log.e(TAG, "Invalid url: " + targetUrl); cont = false; throw new IllegalArgumentException("Invalid url: " + targetUrl); } if (cont) { if (!targetUrl.startsWith("https") || gVALID_SSL.equals("true")) { HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.STRICT_HOSTNAME_VERIFIER; HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier); } else { // Create a trust manager that does not validate certificate chains TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { @Override public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { // TODO Auto-generated method stub } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { // TODO Auto-generated method stub } } }; // Install the all-trusting trust manager SSLContext sc; try { sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); // Create all-trusting host name verifier HostnameVerifier allHostsValid = new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }; // Install the all-trusting host verifier HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid); } catch (NoSuchAlgorithmException e) { Logd(TAG, "Error: " + e.getLocalizedMessage()); } catch (KeyManagementException e) { Logd(TAG, "Error: " + e.getLocalizedMessage()); } } Logd(TAG, "Filename: " + file); Logd(TAG, "URL: " + targetUrl); HttpURLConnection connection = null; DataOutputStream outputStream = null; String pathToOurFile = file; String lineEnd = "\r\n"; String twoHyphens = "--"; String boundary = "*****"; int bytesRead, bytesAvailable, bufferSize; byte[] buffer; int maxBufferSize = 1 * 1024; try { connection = (HttpURLConnection) url.openConnection(); // Allow Inputs & Outputs connection.setDoInput(true); connection.setDoOutput(true); connection.setUseCaches(false); //Don't use chunked post requests (nginx doesn't support requests without a Content-Length header) //connection.setChunkedStreamingMode(1024); // Enable POST method connection.setRequestMethod("POST"); setBasicAuthentication(connection, url); connection.setRequestProperty("Connection", "Keep-Alive"); connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary); outputStream = new DataOutputStream(connection.getOutputStream()); //outputStream.writeBytes(twoHyphens + boundary + lineEnd); Iterator<Entry<String, String>> iterator = params.entrySet().iterator(); while (iterator.hasNext()) { Entry<String, String> param = iterator.next(); outputStream.writeBytes(twoHyphens + boundary + lineEnd); outputStream.writeBytes("Content-Disposition: form-data;" + "name=\"" + param.getKey() + "\"" + lineEnd + lineEnd); outputStream.write(param.getValue().getBytes("UTF-8")); outputStream.writeBytes(lineEnd); } String connstr = null; if (!file.equals("")) { FileInputStream fileInputStream = new FileInputStream(new File(pathToOurFile)); outputStream.writeBytes(twoHyphens + boundary + lineEnd); connstr = "Content-Disposition: form-data; name=\"upfile\";filename=\"" + pathToOurFile + "\"" + lineEnd; outputStream.writeBytes(connstr); outputStream.writeBytes(lineEnd); bytesAvailable = fileInputStream.available(); bufferSize = Math.min(bytesAvailable, maxBufferSize); buffer = new byte[bufferSize]; // Read file bytesRead = fileInputStream.read(buffer, 0, bufferSize); Logd(TAG, "File length: " + bytesAvailable); try { while (bytesRead > 0) { try { outputStream.write(buffer, 0, bufferSize); } catch (OutOfMemoryError e) { e.printStackTrace(); html = "Error: outofmemoryerror"; return html; } bytesAvailable = fileInputStream.available(); bufferSize = Math.min(bytesAvailable, maxBufferSize); bytesRead = fileInputStream.read(buffer, 0, bufferSize); } } catch (Exception e) { Logd(TAG, "Error: " + e.getLocalizedMessage()); html = "Error: Unknown error"; return html; } outputStream.writeBytes(lineEnd); fileInputStream.close(); } else if (data != null) { outputStream.writeBytes(twoHyphens + boundary + lineEnd); connstr = "Content-Disposition: form-data; name=\"upfile\";filename=\"tmp\"" + lineEnd; outputStream.writeBytes(connstr); outputStream.writeBytes(lineEnd); bytesAvailable = data.length; Logd(TAG, "File length: " + bytesAvailable); try { outputStream.write(data, 0, data.length); } catch (OutOfMemoryError e) { e.printStackTrace(); html = "Error: outofmemoryerror"; return html; } catch (Exception e) { Logd(TAG, "Error: " + e.getLocalizedMessage()); html = "Error: Unknown error"; return html; } outputStream.writeBytes(lineEnd); } outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd); // Responses from the server (code and message) int serverResponseCode = connection.getResponseCode(); String serverResponseMessage = connection.getResponseMessage(); Logd(TAG, "Server Response Code " + serverResponseCode); Logd(TAG, "Server Response Message: " + serverResponseMessage); if (serverResponseCode == 200) { InputStreamReader in = new InputStreamReader(connection.getInputStream()); BufferedReader br = new BufferedReader(in); String decodedString; while ((decodedString = br.readLine()) != null) { html += decodedString; } in.close(); } outputStream.flush(); outputStream.close(); outputStream = null; } catch (Exception ex) { // Exception handling html = "Error: Unknown error"; Logd(TAG, "Send file Exception: " + ex.getMessage()); } } if (html.startsWith("success:")) Logd(TAG, "Server returned: success:HIDDEN"); else Logd(TAG, "Server returned: " + html); return html; }
From source file:Main.java
public static String postMultiPart(String urlTo, String post, String filepath, String filefield) throws ParseException, IOException { HttpURLConnection connection = null; DataOutputStream outputStream = null; InputStream inputStream = null; String twoHyphens = "--"; String boundary = "*****" + Long.toString(System.currentTimeMillis()) + "*****"; String lineEnd = "\r\n"; String result = ""; int bytesRead, bytesAvailable, bufferSize; byte[] buffer; int maxBufferSize = 1 * 1024 * 1024; String[] q = filepath.split("/"); int idx = q.length - 1; try {//from ww w. jav a 2 s .co m File file = new File(filepath); FileInputStream fileInputStream = new FileInputStream(file); URL url = new URL(urlTo); connection = (HttpURLConnection) url.openConnection(); connection.setDoInput(true); connection.setDoOutput(true); connection.setUseCaches(false); connection.setRequestMethod("POST"); connection.setRequestProperty("Connection", "Keep-Alive"); connection.setRequestProperty("User-Agent", "Android Multipart HTTP Client 1.0"); connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); outputStream = new DataOutputStream(connection.getOutputStream()); outputStream.writeBytes(twoHyphens + boundary + lineEnd); outputStream.writeBytes("Content-Disposition: form-data; name=\"" + filefield + "\"; filename=\"" + q[idx] + "\"" + lineEnd); outputStream.writeBytes("Content-Type: image/jpeg" + lineEnd); outputStream.writeBytes("Content-Transfer-Encoding: binary" + lineEnd); outputStream.writeBytes(lineEnd); bytesAvailable = fileInputStream.available(); bufferSize = Math.min(bytesAvailable, maxBufferSize); buffer = new byte[bufferSize]; bytesRead = fileInputStream.read(buffer, 0, bufferSize); while (bytesRead > 0) { outputStream.write(buffer, 0, bufferSize); bytesAvailable = fileInputStream.available(); bufferSize = Math.min(bytesAvailable, maxBufferSize); bytesRead = fileInputStream.read(buffer, 0, bufferSize); } outputStream.writeBytes(lineEnd); // Upload POST Data String[] posts = post.split("&"); int max = posts.length; for (int i = 0; i < max; i++) { outputStream.writeBytes(twoHyphens + boundary + lineEnd); String[] kv = posts[i].split("="); outputStream.writeBytes("Content-Disposition: form-data; name=\"" + kv[0] + "\"" + lineEnd); outputStream.writeBytes("Content-Type: text/plain" + lineEnd); outputStream.writeBytes(lineEnd); outputStream.writeBytes(kv[1]); outputStream.writeBytes(lineEnd); } outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd); inputStream = connection.getInputStream(); result = convertStreamToString(inputStream); fileInputStream.close(); inputStream.close(); outputStream.flush(); outputStream.close(); return result; } catch (Exception e) { Log.e("MultipartRequest", "Multipart Form Upload Error"); e.printStackTrace(); return "error"; } }
From source file:de.fu_berlin.inf.dpp.netbeans.feedback.FileSubmitter.java
/** * Tries to upload the given file to the given HTTP server (via POST * method).// w w w. j ava2 s. c om * * @param file * the file to upload * @param url * the URL of the server, that is supposed to handle the file * @param monitor * a monitor to report progress to * @throws IOException * if an I/O error occurs * */ public static void uploadFile(final File file, final String url, IProgressMonitor monitor) throws IOException { final String CRLF = "\r\n"; final String doubleDash = "--"; final String boundary = generateBoundary(); HttpURLConnection connection = null; OutputStream urlConnectionOut = null; FileInputStream fileIn = null; if (monitor == null) monitor = new NullProgressMonitor(); int contentLength = (int) file.length(); if (contentLength == 0) { log.warn("file size of file " + file.getAbsolutePath() + " is 0 or the file does not exist"); return; } monitor.beginTask("Uploading file " + file.getName(), contentLength); try { URL connectionURL = new URL(url); if (!"http".equals(connectionURL.getProtocol())) throw new IOException("only HTTP protocol is supported"); connection = (HttpURLConnection) connectionURL.openConnection(); connection.setUseCaches(false); connection.setDoInput(true); connection.setDoOutput(true); connection.setRequestMethod("POST"); connection.setReadTimeout(TIMEOUT); connection.setConnectTimeout(TIMEOUT); connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); String contentDispositionLine = "Content-Disposition: form-data; name=\"" + file.getName() + "\"; filename=\"" + file.getName() + "\"" + CRLF; String contentTypeLine = "Content-Type: application/octet-stream; charset=ISO-8859-1" + CRLF; String contentTransferEncoding = "Content-Transfer-Encoding: binary" + CRLF; contentLength += 2 * boundary.length() + contentDispositionLine.length() + contentTypeLine.length() + contentTransferEncoding.length() + 4 * CRLF.length() + 3 * doubleDash.length(); connection.setFixedLengthStreamingMode(contentLength); connection.connect(); urlConnectionOut = connection.getOutputStream(); PrintWriter writer = new PrintWriter(new OutputStreamWriter(urlConnectionOut, "US-ASCII"), true); writer.append(doubleDash).append(boundary).append(CRLF); writer.append(contentDispositionLine); writer.append(contentTypeLine); writer.append(contentTransferEncoding); writer.append(CRLF); writer.flush(); fileIn = new FileInputStream(file); byte[] buffer = new byte[8192]; for (int read = 0; (read = fileIn.read(buffer)) > 0;) { if (monitor.isCanceled()) return; urlConnectionOut.write(buffer, 0, read); monitor.worked(read); } urlConnectionOut.flush(); writer.append(CRLF); writer.append(doubleDash).append(boundary).append(doubleDash).append(CRLF); writer.close(); if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) { log.debug("uploaded file " + file.getAbsolutePath() + " to " + connectionURL.getHost()); return; } throw new IOException("failed to upload file " + file.getAbsolutePath() + connectionURL.getHost() + " [" + connection.getResponseMessage() + "]"); } finally { IOUtils.closeQuietly(fileIn); IOUtils.closeQuietly(urlConnectionOut); if (connection != null) connection.disconnect(); monitor.done(); } }
From source file:xqpark.ParkApi.java
/** * API?//w w w. j a v a 2 s . c o m * @param ?url * @return APIJSON? * @throws JSONException * @throws IOException * @throws ParseException */ public static JSONObject loadJSON(String url) throws JSONException { StringBuilder json = new StringBuilder(); try { URLEncoder.encode(url, "UTF-8"); URL urlObject = new URL(url); HttpURLConnection uc = (HttpURLConnection) urlObject.openConnection(); uc.setDoOutput(true);// URL uc.setDoInput(true);// URL uc.setUseCaches(false); uc.setRequestMethod("POST"); BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream(), "utf-8")); String inputLine = null; while ((inputLine = in.readLine()) != null) { json.append(inputLine); } in.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } JSONObject responseJson = new JSONObject(json.toString()); return responseJson; }
From source file:ict.servlet.UploadToServer.java
public static int upLoad2Server(String sourceFileUri) { String upLoadServerUri = "http://vbacdu.ddns.net:8080/WBS/newjsp.jsp"; // String [] string = sourceFileUri; String fileName = sourceFileUri; int serverResponseCode = 0; HttpURLConnection conn = null; DataOutputStream dos = null;// w w w . j a v a 2 s. c o m DataInputStream inStream = null; String lineEnd = "\r\n"; String twoHyphens = "--"; String boundary = "*****"; int bytesRead, bytesAvailable, bufferSize; byte[] buffer; int maxBufferSize = 1 * 1024 * 1024; String responseFromServer = ""; File sourceFile = new File(sourceFileUri); if (!sourceFile.isFile()) { return 0; } try { // open a URL connection to the Servlet FileInputStream fileInputStream = new FileInputStream(sourceFile); URL url = new URL(upLoadServerUri); conn = (HttpURLConnection) url.openConnection(); // Open a HTTP connection to the URL conn.setDoInput(true); // Allow Inputs conn.setDoOutput(true); // Allow Outputs conn.setUseCaches(false); // Don't use a Cached Copy conn.setRequestMethod("POST"); conn.setRequestProperty("Connection", "Keep-Alive"); conn.setRequestProperty("ENCTYPE", "multipart/form-data"); conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary); conn.setRequestProperty("uploaded_file", fileName); dos = new DataOutputStream(conn.getOutputStream()); dos.writeBytes(twoHyphens + boundary + lineEnd); dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\"" + fileName + "\"" + lineEnd); dos.writeBytes(lineEnd); bytesAvailable = fileInputStream.available(); // create a buffer of maximum size bufferSize = Math.min(bytesAvailable, maxBufferSize); buffer = new byte[bufferSize]; // read file and write it into form... bytesRead = fileInputStream.read(buffer, 0, bufferSize); while (bytesRead > 0) { dos.write(buffer, 0, bufferSize); bytesAvailable = fileInputStream.available(); bufferSize = Math.min(bytesAvailable, maxBufferSize); bytesRead = fileInputStream.read(buffer, 0, bufferSize); } // send multipart form data necesssary after file data... dos.writeBytes(lineEnd); dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd); // Responses from the server (code and message) serverResponseCode = conn.getResponseCode(); String serverResponseMessage = conn.getResponseMessage(); m_log.info("Upload file to server" + "HTTP Response is : " + serverResponseMessage + ": " + serverResponseCode); // close streams m_log.info("Upload file to server" + fileName + " File is written"); fileInputStream.close(); dos.flush(); dos.close(); } catch (MalformedURLException ex) { // ex.printStackTrace(); m_log.error("Upload file to server" + "error: " + ex.getMessage(), ex); } catch (Exception e) { // e.printStackTrace(); } //this block will give the response of upload link /* try { BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line; while ((line = rd.readLine()) != null) { m_log.info("Huzza" + "RES Message: " + line); } rd.close(); } catch (IOException ioex) { m_log.error("Huzza" + "error: " + ioex.getMessage(), ioex); }*/ return serverResponseCode; // like 200 (Ok) }
From source file:org.dcm4che3.tool.stowrs.StowRS.java
private static StowRSResponse sendDicomFile(String url, File f) throws IOException { int rspCode = 0; String rspMessage = null;//w w w. j a v a 2 s . c o m URL newUrl = new URL(url); HttpURLConnection connection = (HttpURLConnection) newUrl.openConnection(); connection.setDoOutput(true); connection.setDoInput(true); connection.setInstanceFollowRedirects(false); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "multipart/related; type=application/dicom; boundary=" + MULTIPART_BOUNDARY); connection.setRequestProperty("Accept", "application/dicom+xml"); connection.setRequestProperty("charset", "utf-8"); connection.setUseCaches(false); DataOutputStream wr; wr = new DataOutputStream(connection.getOutputStream()); wr.writeBytes("\r\n--" + MULTIPART_BOUNDARY + "\r\n"); wr.writeBytes("Content-Disposition: inline; name=\"file[]\"; filename=\"" + f.getName() + "\"\r\n"); wr.writeBytes("Content-Type: application/dicom \r\n"); wr.writeBytes("\r\n"); FileInputStream fis = new FileInputStream(f); StreamUtils.copy(fis, wr); fis.close(); wr.writeBytes("\r\n--" + MULTIPART_BOUNDARY + "--\r\n"); wr.flush(); wr.close(); String response = connection.getResponseMessage(); rspCode = connection.getResponseCode(); rspMessage = connection.getResponseMessage(); LOG.info("response: " + response); Attributes responseAttrs = null; try { InputStream in; boolean isErrorCase = rspCode >= HttpURLConnection.HTTP_BAD_REQUEST; if (!isErrorCase) { in = connection.getInputStream(); } else { in = connection.getErrorStream(); } if (!isErrorCase || rspCode == HttpURLConnection.HTTP_CONFLICT) responseAttrs = SAXReader.parse(in); } catch (SAXException e) { throw new IOException(e); } catch (ParserConfigurationException e) { throw new IOException(e); } connection.disconnect(); return new StowRSResponse(rspCode, rspMessage, responseAttrs); }
From source file:org.cruxframework.crux.core.server.rest.spi.HttpUtil.java
public static String wGet(String targetURL, String urlParameters, String method, String locale) { URL url;//from ww w .j a v a 2s. c o m HttpURLConnection connection = null; try { //Create connection if (method != null && method.equals("GET") && !StringUtils.isEmpty(urlParameters)) { targetURL += "?" + urlParameters; } url = new URL(targetURL); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod(method); connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); connection.setRequestProperty("Content-Length", "" + Integer.toString(urlParameters.getBytes().length)); connection.setRequestProperty("Content-Language", locale); connection.setUseCaches(false); connection.setDoInput(true); //Send request if (method != null && method.equals("POST")) { DataOutputStream wr = new DataOutputStream(connection.getOutputStream()); connection.setDoOutput(true); wr.writeBytes(urlParameters); wr.flush(); wr.close(); } //Get Response InputStream is = connection.getInputStream(); BufferedReader rd = new BufferedReader(new InputStreamReader(is)); String line; StringBuffer response = new StringBuffer(); while ((line = rd.readLine()) != null) { response.append(line); response.append('\r'); } rd.close(); return response.toString(); } catch (Exception e) { e.printStackTrace(); return null; } finally { if (connection != null) { connection.disconnect(); } } }
From source file:com.zzl.zl_app.cache.Utility.java
public static String uploadFile(File file, String RequestURL, String fileName) { Tools.log("IO", "RequestURL:" + RequestURL); String result = null;/*from www .ja v a 2 s . c o m*/ String BOUNDARY = UUID.randomUUID().toString(); // ?? String PREFIX = "--", LINE_END = "\r\n"; String CONTENT_TYPE = "multipart/form-data"; // try { URL url = new URL(RequestURL); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setReadTimeout(Utility.SET_SOCKET_TIMEOUT); conn.setConnectTimeout(Utility.SET_CONNECTION_TIMEOUT); conn.setDoInput(true); // ?? conn.setDoOutput(true); // ?? conn.setUseCaches(false); // ?? conn.setRequestMethod("POST"); // ? conn.setRequestProperty("Charset", CHARSET); // ? conn.setRequestProperty("connection", "keep-alive"); conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary=" + BOUNDARY); if (file != null) { /** * ? */ DataOutputStream dos = new DataOutputStream(conn.getOutputStream()); StringBuffer sb = new StringBuffer(); sb.append(PREFIX); sb.append(BOUNDARY); sb.append(LINE_END); /** * ?? name???key ?key ?? * filename?????? :abc.png */ sb.append("Content-Disposition: form-data; name=\"voice\"; filename=\"" + file.getName() + "\"" + LINE_END); sb.append("Content-Type: application/octet-stream; charset=" + CHARSET + LINE_END); sb.append(LINE_END); dos.write(sb.toString().getBytes()); Tools.log("FileSize", "file:" + file.length()); InputStream is = new FileInputStream(file); byte[] bytes = new byte[1024]; int len = 0; while ((len = is.read(bytes)) != -1) { dos.write(bytes, 0, len); Tools.log("FileSize", "size:" + len); } dos.write(LINE_END.getBytes()); byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END).getBytes(); dos.write(end_data); dos.flush(); dos.close(); is.close(); /** * ??? 200=? ????? */ int res = conn.getResponseCode(); Tools.log("IO", "ResponseCode:" + res); if (res == 200) { InputStream input = conn.getInputStream(); StringBuffer sb1 = new StringBuffer(); int ss; while ((ss = input.read()) != -1) { sb1.append((char) ss); } result = sb1.toString(); } } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return result; }
From source file:org.csware.ee.utils.Tools.java
public static String GetDataByPost(String httpUrl, String parMap) { try {/*w w w.ja v a2s . c o m*/ URL url = new URL(httpUrl);// HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setDoInput(true); connection.setUseCaches(false); connection.setInstanceFollowRedirects(true); connection.setRequestMethod("POST"); // ? connection.setRequestProperty("Accept", "application/json"); // ?? connection.setRequestProperty("Content-Type", "application/json"); // ???? connection.connect(); OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), "UTF-8"); // utf-8? out.append(parMap); out.flush(); out.close(); // ?? int length = (int) connection.getContentLength();// ? InputStream is = connection.getInputStream(); if (length != -1) { byte[] data = new byte[length]; byte[] temp = new byte[1024]; int readLen = 0; int destPos = 0; while ((readLen = is.read(temp)) > 0) { System.arraycopy(temp, 0, data, destPos, readLen); destPos += readLen; } String result = new String(data, "UTF-8"); // utf-8? return result; } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); System.out.println("aa: " + e.getMessage()); } return "error"; // ? }