I'm trying to upload an image from the signup form using InscriptionForm.java to check the respectieve fields. The upload has no problem (Thanks to BalusC's tutorials), but, when I try to display the uploaded image, I can't; refering to the HTTP network monitor I got 404 error as response. Also, when I try to enter the above link into the browser's adress bar http://localhost:8080/projetForum/images/bd/Id_21082013184506.png I've got a 404 error.
InscriptionForm.java
public final class InscriptionForm {
private static final String CHAMP_EMAIL = "email";
private static final String CHAMP_PASS = "motdepasse";
private static final String CHAMP_CONF = "confirmation";
private static final String CHAMP_NOM = "nom";
private static final String CHAMP_DESC = "description";
private static final String CHAMP_LOC = "localisation";
private static final String CHAMP_SW = "siteweb";
public static final String CHAMP_IMAGE = "avatar";
public static final String CHAMP_JOURDENAISS = "jourdenaissance";
public static final String CHAMP_MOISDENAISS = "moisdenaissance";
public static final String CHAMP_ANNEEDENAISS = "anneedenaissance";
public static final String CHAMP_DATEDENAISS = "datedenaissance";
public static final int TAILLE_TAMPON = 10240; // 10 ko
public static final String CHEMIN = "E:\\Bibliothèque logicielle\\workspace\\projetForum\\WebContent\\images\\bd\\";
private String resultat;
private static Map<String, String> erreurs = new HashMap<String, String>();
public String getResultat() {
return resultat;
}
public Map<String, String> getErreurs() {
return erreurs;
}
public Utilisateur inscrireUtilisateur(HttpServletRequest request) {
String email = getValeurChamp(request, CHAMP_EMAIL);
String motDePasse = getValeurChamp(request, CHAMP_PASS);
String confirmation = getValeurChamp(request, CHAMP_CONF);
String nom = getValeurChamp(request, CHAMP_NOM);
String description = getValeurChamp(request, CHAMP_DESC);
String localisation = getValeurChamp(request, CHAMP_LOC);
String siteweb = getValeurChamp(request, CHAMP_SW);
String image = getValeurChamp(request, CHAMP_IMAGE);
String jourdenaissance = getValeurChamp(request, CHAMP_JOURDENAISS);
String moisdenaissance = getValeurChamp(request, CHAMP_MOISDENAISS);
String anneedenaissance = getValeurChamp(request, CHAMP_ANNEEDENAISS);
Integer datedenaissance = null;
try {
validationEmail(email);
} catch (Exception e) {
setErreur(CHAMP_EMAIL, e.getMessage());
}
try {
validationMotsDePasse(motDePasse, confirmation);
} catch (Exception e) {
setErreur(CHAMP_PASS, e.getMessage());
}
try {
validationNom(nom);
} catch (Exception e) {
setErreur(CHAMP_NOM, e.getMessage());
}
try {
image = validationImage(request, CHEMIN);
} catch (Exception e) {
setErreur(CHAMP_IMAGE, e.getMessage());
}
if (!jourdenaissance.equals("defaut")
&& !moisdenaissance.equals("defaut")
&& !anneedenaissance.equals("defaut")) {
try {
validationDateDeNaiss(Integer.parseInt(jourdenaissance),
Integer.parseInt(moisdenaissance),
Integer.parseInt(anneedenaissance));
} catch (Exception e) {
setErreur(CHAMP_DATEDENAISS, e.getMessage());
}
datedenaissance = Integer.parseInt((jourdenaissance + ""
+ moisdenaissance + "" + anneedenaissance));
}
if (jourdenaissance.equals("defaut")
&& moisdenaissance.equals("defaut")
&& anneedenaissance.equals("defaut")) {
} else {
setErreur(CHAMP_DATEDENAISS,
"Merci de vérifier votre date de naissance.");
}
Utilisateur utilisateur = new Utilisateur(email, motDePasse, nom,
localisation, siteweb, description, datedenaissance, image);
if (erreurs.isEmpty()) {
resultat = "Succès de l'inscription.";
createORupdate(utilisateur, request);
} else {
resultat = "Échec de l'inscription.";
}
return utilisateur;
}
private String validationImage(HttpServletRequest request, String chemin)
throws Exception {
File uploadFilePath = new File(chemin);
// Validate file.
Object fileObject = request.getAttribute("avatar");
if (fileObject == null) {
// No file uploaded.
throw new Exception("Please select file to upload.");
} else if (fileObject instanceof FileUploadException) {
// File upload is failed.
FileUploadException fileUploadException = (FileUploadException) fileObject;
throw new Exception(fileUploadException.getMessage());
}
// If there are no errors, proceed with writing file.
FileItem fileItem = (FileItem) fileObject;
// Get file name from uploaded file and trim path from it.
// Some browsers (e.g. IE, Opera) also sends the path, which is
// completely irrelevant.
String fileName = FilenameUtils.getName(fileItem.getName());
// Prepare filename prefix and suffix for an unique filename in upload
// folder.
String prefix = FilenameUtils.getBaseName(fileName) + "_";
String suffix = "." + FilenameUtils.getExtension(fileName);
File file = null;
try {
// Prepare unique local file based on file name of uploaded file.
file = File.createTempFile(prefix, suffix, uploadFilePath);
// Write uploaded file to local file.
fileItem.write(file);
} catch (Exception e) {
// Can be thrown by uniqueFile() and FileItem#write().
throw new Exception(e.getMessage());
}
return file.getName();
}
private void setErreur(String champ, String message) {
erreurs.put(champ, message);
}
private static String getValeurChamp(HttpServletRequest request,
String nomChamp) {
String valeur = request.getParameter(nomChamp);
if (valeur == null || valeur.trim().length() == 0) {
return null;
} else {
return valeur;
}
}
private static void createORupdate(Utilisateur u, HttpServletRequest request) {
Session s = HibernateUtils.getSession();
Transaction tx = s.beginTransaction();
Query q = s
.createQuery("from Utilisateur where Utilisateur_email = :email");
q.setString("email", u.getEmail());
Utilisateur userUpdt = (Utilisateur) q.uniqueResult();
if (userUpdt != null) {
userUpdt.setNom(u.getNom());
userUpdt.setEmail(u.getEmail());
userUpdt.setSiteweb(u.getSiteweb());
userUpdt.setLocalisation(u.getLocalisation());
userUpdt.setDescription(u.getDescription());
s.update(userUpdt);
} else {
SimpleDateFormat formater = new SimpleDateFormat(
"dd-MM-yyyy hh:mm:ss");
Date aujourdhui = new Date();
u.setDateInscrit(formater.format(aujourdhui));
s.persist(u);
}
tx.commit();
}
private void validationEmail(String email) throws Exception {
UtilisateurDAO<Utilisateur, String> ud = new UtilisateurDAO<Utilisateur, String>();
if (ud.findByID(email) != null)
throw new Exception("Adresse mail déjà utilisée.");
else if (email == null || ud.findByID(email) != null
|| !email.matches("([^.#]+)(\\.[^.#]+)*#([^.#]+\\.)+([^.#]+)")) {
throw new Exception("Merci de saisir une adresse mail valide.");
}
}
private void validationDateDeNaiss(Integer jj, Integer mm, Integer aaaa)
throws Exception {
switch (mm) {
case 2:
if (jj > 28 && ((aaaa / 4) % 100 == 0 && aaaa % 400 == 0))
throw new Exception(
"Merci de vérifier votre date de naissance.");
break;
case 4:
if (jj == 31)
throw new Exception(
"Merci de vérifier votre date de naissance.");
break;
case 6:
if (jj == 31)
throw new Exception(
"Merci de vérifier votre date de naissance.");
break;
case 9:
if (jj == 31)
throw new Exception(
"Merci de vérifier votre date de naissance.");
break;
case 11:
if (jj == 31)
throw new Exception(
"Merci de vérifier votre date de naissance.");
break;
}
}
private void validationMotsDePasse(String motDePasse, String confirmation)
throws Exception {
if (motDePasse != null && confirmation != null) {
if (!motDePasse.equals(confirmation)) {
throw new Exception(
"Les mots de passe entrés sont différents, merci de les saisir à nouveau.");
} else if (motDePasse.length() < 6) {
throw new Exception(
"Les mots de passe doivent contenir au moins 6 caractères.");
}
} else {
throw new Exception(
"Merci de saisir et confirmer votre mot de passe.");
}
}
private static void validationNom(String nom) throws Exception {
ConfigFDAO<ConfigF, Integer> cfd = new ConfigFDAO<ConfigF, Integer>();
UtilisateurDAO<Utilisateur, String> ud = new UtilisateurDAO<Utilisateur, String>();
if (ud.findByNom(nom) != null)
throw new Exception("Nom d'utilisateur déjà utilisée.");
else if (nom == null
|| nom.length() < cfd.findByID(0).getPseudominsize()
|| nom.length() > cfd.findByID(0).getPseudomaxsize()) {
throw new Exception("Le nom d'utilisateur doit contenir au moins "
+ cfd.findByID(0).getPseudominsize() + " et au maximum "
+ cfd.findByID(0).getPseudomaxsize() + " caractères.");
}
}
private static String getNomFichier(Part part) {
for (String cd : part.getHeader("content-disposition").split(";")) {
if (cd.trim().startsWith("filename")) {
String filename = cd.substring(cd.indexOf('=') + 1).trim()
.replace("\"", "");
return filename.substring(filename.lastIndexOf('/') + 1)
.substring(filename.lastIndexOf('\\') + 1);
}
}
return null;
}
}
MultipartFilter.java
public class MultipartFilter implements Filter {
// Init
// ---------------------------------------------------------------------------------------
private long maxFileSize;
// Actions
// ------------------------------------------------------------------------------------
/**
* Configure the 'maxFileSize' parameter.
*
* #throws ServletException
* If 'maxFileSize' parameter value is not numeric.
* #see javax.servlet.Filter#init(javax.servlet.FilterConfig)
*/
public void init(FilterConfig filterConfig) throws ServletException {
// Configure maxFileSize.
String maxFileSize = filterConfig.getInitParameter("maxFileSize");
if (maxFileSize != null) {
if (!maxFileSize.matches("^\\d+$")) {
throw new ServletException(
"MultipartFilter 'maxFileSize' is not numeric.");
}
this.maxFileSize = Long.parseLong(maxFileSize);
}
}
/**
* Check the type request and if it is a HttpServletRequest, then parse the
* request.
*
* #throws ServletException
* If parsing of the given HttpServletRequest fails.
* #see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
* javax.servlet.ServletResponse, javax.servlet.FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws ServletException, IOException {
// Check type request.
if (request instanceof HttpServletRequest) {
// Cast back to HttpServletRequest.
HttpServletRequest httpRequest = (HttpServletRequest) request;
// Parse HttpServletRequest.
HttpServletRequest parsedRequest = parseRequest(httpRequest);
// Continue with filter chain.
chain.doFilter(parsedRequest, response);
} else {
// Not a HttpServletRequest.
chain.doFilter(request, response);
}
}
/**
* #see javax.servlet.Filter#destroy()
*/
public void destroy() {
// I am a boring method.
}
// Helpers
// ------------------------------------------------------------------------------------
/**
* Parse the given HttpServletRequest. If the request is a multipart
* request, then all multipart request items will be processed, else the
* request will be returned unchanged. During the processing of all
* multipart request items, the name and value of each regular form field
* will be added to the parameterMap of the HttpServletRequest. The name and
* File object of each form file field will be added as attribute of the
* given HttpServletRequest. If a FileUploadException has occurred when the
* file size has exceeded the maximum file size, then the
* FileUploadException will be added as attribute value instead of the
* FileItem object.
*
* #param request
* The HttpServletRequest to be checked and parsed as multipart
* request.
* #return The parsed HttpServletRequest.
* #throws ServletException
* If parsing of the given HttpServletRequest fails.
*/
#SuppressWarnings("unchecked")
// ServletFileUpload#parseRequest() does not return generic type.
private HttpServletRequest parseRequest(HttpServletRequest request)
throws ServletException {
// Check if the request is actually a multipart/form-data request.
if (!ServletFileUpload.isMultipartContent(request)) {
// If not, then return the request unchanged.
return request;
}
// Prepare the multipart request items.
// I'd rather call the "FileItem" class "MultipartItem" instead or so.
// What a stupid name ;)
List<FileItem> multipartItems = null;
try {
// Parse the multipart request items.
multipartItems = new ServletFileUpload(new DiskFileItemFactory())
.parseRequest(request);
// Note: we could use ServletFileUpload#setFileSizeMax() here, but
// that would throw a
// FileUploadException immediately without processing the other
// fields. So we're
// checking the file size only if the items are already parsed. See
// processFileField().
} catch (FileUploadException e) {
throw new ServletException("Cannot parse multipart request: "
+ e.getMessage());
}
// Prepare the request parameter map.
Map<String, String[]> parameterMap = new HashMap<String, String[]>();
// Loop through multipart request items.
for (FileItem multipartItem : multipartItems) {
if (multipartItem.isFormField()) {
// Process regular form field (input
// type="text|radio|checkbox|etc", select, etc).
processFormField(multipartItem, parameterMap);
} else {
// Process form file field (input type="file").
processFileField(multipartItem, request);
}
}
// Wrap the request with the parameter map which we just created and
// return it.
return wrapRequest(request, parameterMap);
}
/**
* Process multipart request item as regular form field. The name and value
* of each regular form field will be added to the given parameterMap.
*
* #param formField
* The form field to be processed.
* #param parameterMap
* The parameterMap to be used for the HttpServletRequest.
*/
private void processFormField(FileItem formField,
Map<String, String[]> parameterMap) {
String name = formField.getFieldName();
String value = formField.getString();
String[] values = parameterMap.get(name);
if (values == null) {
// Not in parameter map yet, so add as new value.
parameterMap.put(name, new String[] { value });
} else {
// Multiple field values, so add new value to existing array.
int length = values.length;
String[] newValues = new String[length + 1];
System.arraycopy(values, 0, newValues, 0, length);
newValues[length] = value;
parameterMap.put(name, newValues);
}
}
/**
* Process multipart request item as file field. The name and FileItem
* object of each file field will be added as attribute of the given
* HttpServletRequest. If a FileUploadException has occurred when the file
* size has exceeded the maximum file size, then the FileUploadException
* will be added as attribute value instead of the FileItem object.
*
* #param fileField
* The file field to be processed.
* #param request
* The involved HttpServletRequest.
*/
private void processFileField(FileItem fileField, HttpServletRequest request) {
if (fileField.getName().length() <= 0) {
// No file uploaded.
request.setAttribute(fileField.getFieldName(), null);
} else if (maxFileSize > 0 && fileField.getSize() > maxFileSize) {
// File size exceeds maximum file size.
request.setAttribute(fileField.getFieldName(),
new FileUploadException(
"File size exceeds maximum file size of "
+ maxFileSize + " bytes."));
// Immediately delete temporary file to free up memory and/or disk
// space.
fileField.delete();
} else {
// File uploaded with good size.
request.setAttribute(fileField.getFieldName(), fileField);
}
}
// Utility (may be refactored to public utility class)
// ----------------------------------------
/**
* Wrap the given HttpServletRequest with the given parameterMap.
*
* #param request
* The HttpServletRequest of which the given parameterMap have to
* be wrapped in.
* #param parameterMap
* The parameterMap to be wrapped in the given
* HttpServletRequest.
* #return The HttpServletRequest with the parameterMap wrapped in.
*/
private static HttpServletRequest wrapRequest(HttpServletRequest request,
final Map<String, String[]> parameterMap) {
return new HttpServletRequestWrapper(request) {
public Map<String, String[]> getParameterMap() {
return parameterMap;
}
public String[] getParameterValues(String name) {
return parameterMap.get(name);
}
public String getParameter(String name) {
String[] params = getParameterValues(name);
return params != null && params.length > 0 ? params[0] : null;
}
public Enumeration<String> getParameterNames() {
return Collections.enumeration(parameterMap.keySet());
}
};
}
}
Thanks in advance.
Related
How to get OAuth2.0 access token using refresh token in scala .
Sample code using the HttpsURLConnection, without any libraries
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public class Sample_OAuth {
public static void main(String[] args) throws Exception {
Sample_OAuth outhDriver = new Sample_OAuth();
outhDriver.sendRefreshTokenRequestWithOnlyHeader(null);
}
/**
* Send refresh token request to 3rd party with client cred either in body or
* request header.
*
* #param conn
* #param mapListTagToMetaDataName
* #return
* #throws Exception
*/
private Map<String, Object> sendRefreshTokenRequestWithOnlyHeader(Map<String, String> mapListTagToMetaDataName)
throws Exception {
String tokenUrl = "https://xyz.snowflakecomputing.com/oauth/token-request";
URL url = new URL(tokenUrl);
StringBuilder stringBuilder = new StringBuilder();
appendURLParam(stringBuilder, "grant_type", "refresh_token", true);
appendURLParam(stringBuilder, "refresh_token", "ver:2-hint:2065896170862-did:1003-ETMsDgAAAYWAOC1cABRBRVMvQ0JDL1BLQ1M1UGFkZGluZwEAABAAEDu3hgX2UvrDbaMif7uC+ygAAADwoZhxL+aOCvvsmNh0wy0FdNGuDRLCtOq7iQTsZPPmfkRZJnkj3nXgKDxTFeFOmty4ej/O6Fsf17HfNvKdLrqfN3V29FkFQ5S+FktFIznTSjtd7+xaMS+sPEAyey2SFfbSyMvrknjq9F+CQZ50H181OO8Ak4v1uW4ON9Q1UBRd9ywM2Yg5g59hPgy90jtAW0DPQ8gvfAwRJCgg2wzV7tXrQ1H2TQhFEkQH418s5pSNB5V6BSW0fFqOUW3O8X4MmHcWcpTbghZ5aga8+dSKSR8jd2KMmfawyXMdkIYdWEsrpcJozuYDAjFwIT1lkqLxqBnuABQIbwjao0KeWXYU3sYanTb0WoR4Ng==",
false);
String clientRequestType = "Basic Auth Header";
return sendOAuthRequestWithHeader(mapListTagToMetaDataName, url, stringBuilder.toString());
}
private static void appendURLParam(StringBuilder stringBuilder, String name, String value, boolean appendAmpersand)
throws UnsupportedEncodingException {
/*
* if (StringUtil.isNullOrEmptyTrim(name) ||
* StringUtil.isNullOrEmptyTrim(value)) { //log.error(String.
* format("Either Auth attr name : %s or value : %s is Null or empty", name,
* value)); return; }
*/
stringBuilder.append(name);
stringBuilder.append("=");
stringBuilder.append(URLEncoder.encode(value, "UTF-8"));
//stringBuilder.append(value);
if (appendAmpersand) {
stringBuilder.append("&");
}
}
private Map<String, Object> sendOAuthRequestWithHeader(Map<String, String> mapListTagToMetaDataName, URL url,
String postBody) throws Exception {
String clientId = "S0RpOorCRUQOqVncoxc8fXUO22A=";
String client_secret = "MHTOaEmQeLB359K+kEAs/+2ow4AcmqD5/ABckC4E2fQ=";
clientId = clientId + ":" + client_secret;
// Should not be MIME-encode since value is used as a HTTP header and MIME adds
// new lines if over 76 characters
String value = java.util.Base64.getEncoder().encodeToString(clientId.getBytes());
return sendOAuthRequest(url, postBody, value);
}
private Map<String, Object> sendOAuthRequest(URL url, String postBody, String authorizationHeader) throws Exception {
HttpsURLConnection urlConn = (HttpsURLConnection) url.openConnection();
urlConn.setRequestMethod("POST");
urlConn.addRequestProperty("Accept", "application/json");
if (notNullOrEmptyTrim(authorizationHeader)) {
urlConn.addRequestProperty("Content-Type", "application/x-www-form-urlencoded");
urlConn.addRequestProperty("Authorization", "Basic " + authorizationHeader);
}
return sendAccessTokenRequest(urlConn, postBody);
}
public Map<String, Object> getToken(String tokenUrl, String requestBody, String authorizationHeader)
throws Exception {
// LOG.info("Request : getToken "+ tokenUrl);
URL url = new URL(tokenUrl);
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.addRequestProperty("Accept", "application/json");
if (null != authorizationHeader && !authorizationHeader.isEmpty()) {
urlConnection.addRequestProperty("Content-Type", "application/x-www-form-urlencoded");
urlConnection.addRequestProperty("Authorization", "Basic " + authorizationHeader);
}
return sendAccessTokenRequest(urlConnection, requestBody);
}
private Map<String, Object> sendAccessTokenRequest(HttpsURLConnection urlConn, String postBody) throws Exception {
// Write to input stream
try {
//optional
enableAllSSLCert(urlConn);
urlConn.setDoOutput(true);
//optional
urlConn.setHostnameVerifier((name, session) -> true);
DataOutputStream outputStream = new DataOutputStream(urlConn.getOutputStream());
outputStream.writeBytes(postBody);
outputStream.flush();
outputStream.close();
int responseCode = urlConn.getResponseCode();
InputStream is = null;
// LOG.info(" response code is:" + responseCode);
if (responseCode >= 200 && responseCode < 400) {
is = urlConn.getInputStream();
} else {
// LOG.error("Error, sendOAuthRequest response code is:" + responseCode);
is = urlConn.getErrorStream();
}
// Read response
String response = null;
if (null != is) {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
StringBuilder stringBuilder = new StringBuilder();
while (true) {
String line = bufferedReader.readLine();
if (line == null) {
break;
} else {
stringBuilder.append(line);
}
}
response = stringBuilder.toString();
bufferedReader.close();
}
// Logging in case of error
if (responseCode != 200) {
// LOG.error("Get Token error response : " + response);
}
System.out.println(response);
Map<String, Object> retValue = new HashMap<>();
retValue.put("errorCode", responseCode);
retValue.put("token", response);
return retValue;
} catch (Exception exp) {
// LOG.info(" Exception while getting Access Token:", exp);
throw exp;
}
}
public static boolean notNullOrEmptyTrim(String str) {
return !isNullOrEmptyTrim(str);
}
public static boolean isNullOrEmptyTrim(String s) {
return s == null || s.trim().isEmpty();
}
/**
* Enable https client for all SSL cert
*
* #param urlConn
* #throws NoSuchAlgorithmException
* #throws KeyManagementException
*/
private void enableAllSSLCert(HttpsURLConnection urlConn) throws NoSuchAlgorithmException, KeyManagementException {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, new TrustManager[] { new TrustAllTrustManager() }, new java.security.SecureRandom());
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = (hostname, session) -> true;
urlConn.setHostnameVerifier(allHostsValid);
}
/**
* Override Trust All trust manager
*/
private class TrustAllTrustManager implements X509TrustManager {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
}
We have a requirement as below
Integration System needs to call our service
Our service needs to call FlipKart service appending the token in the request
Get the response back to Integration system
The above should work seamlessly for both GET and PUT requests.
I had developed a REST-project in eclipse and was able to get the GET and PUT response back to Integration.
However have few problems
In Get Requests, we are explicitly setting the headers and produces annotation to appication/json. How do we set it for all kind of requests?
In Post Response, we do not get the entire response and we are not able to set the application type in the response (Not sure how!)
All these requests are failing if the application type is pdf, img etc.
Can someone please help on the same?
Code implemented so far:
#GET
#Path("{pathvalue : (.+)?}")
#Produces("{application/json;application/octet-stream}")
public String getFlipKartResponse(#Context UriInfo uriInfo, #PathParam("pathvalue") String pathValue, #Context HttpServletRequest request) throws ClassNotFoundException,IOException {
String methodName = "getFlipKartResponse";
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.entering(CLASSNAME, methodName);
}
MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters();
//if(null == flipkartUrl || flipkartUrl.isEmpty())
flipkartUrl = config.getProperty(ServiceConstants.FLIPKART_URL);
String queryParam = new String();
Iterator<String> iterator = queryParams.keySet().iterator();
while (iterator.hasNext()) {
String parameter = iterator.next();
queryParam = queryParam.concat(parameter + ServiceConstants.EQUALS + queryParams.getFirst(parameter) + ServiceConstants.AMPERSAND);
}
String modifiedflipkartUrl = flipkartUrl.concat(pathValue).concat(ServiceConstants.QUESTION).concat(queryParam);
if (modifiedflipkartUrl.endsWith(ServiceConstants.QUESTION) || modifiedflipkartUrl.endsWith(ServiceConstants.AMPERSAND)) {
modifiedflipkartUrl = modifiedflipkartUrl.substring(0, modifiedflipkartUrl.length()-1);
}
LOGGER.log(Level.INFO, "Flipkart URL framed : "+ modifiedflipkartUrl);
url = new URL(modifiedflipkartUrl);
connection = (HttpsURLConnection) url.openConnection();
setHeadersInConnectionObject(url, connection, request.getMethod());
return handleInvalidToken(connection.getResponseCode(), request);
}
private String handleInvalidToken(int responseCode, HttpServletRequest request){
try {
if (connection.getResponseCode() == 401) {
LOGGER.log(Level.INFO, "ResponseCode " + connection.getResponseCode());
connection.disconnect();
regenerateAccessToken();
connection = (HttpsURLConnection) url.openConnection();
setHeadersInConnectionObject(url, connection, request.getMethod());
inputLine = new BufferedReader(new InputStreamReader(connection.getInputStream()));
} else if (connection.getResponseCode() == 200) {
inputLine = new BufferedReader(new InputStreamReader(connection.getInputStream()));
} else {
inputLine = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
}
String responseInputLine;
String responseMessage = "";
while (null != (responseInputLine = inputLine.readLine())) {
responseMessage = responseMessage + responseInputLine;
}
inputLine.close();
connection.disconnect();
return responseMessage;
} catch (Exception e) {
LOGGER.log(Level.SEVERE,"Exception occured while calling service.Please try again after sometime : ", e);
return this.handleErrorResponse("Exception occured while calling service.Please try again after sometime.");
}
}
private void regenerateAccessToken() throws ClassNotFoundException, IOException, SQLException{
TokenGenerator tokenGenerator = new TokenGenerator();
accessToken= tokenGenerator.getAccessToken();
}
#POST
#Path("{pathvalue : (.+)?}")
#Produces({"application/json;application/octet-stream"})
public String getFlipKartPostResponse(#Context UriInfo uriInfo, #PathParam("pathvalue") String pathValue,#Context HttpServletRequest requestBody) throws ClassNotFoundException,IOException, SQLException {
String methodName = "getFlipKartPostResponse";
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.entering(CLASSNAME, methodName);
}
//if(null == flipkartUrl || flipkartUrl.isEmpty())
flipkartUrl = config.getProperty(ServiceConstants.FLIPKART_URL);
String modifiedflipkartUrl = flipkartUrl + pathValue;
url = new URL(modifiedflipkartUrl);
LOGGER.log(Level.INFO, "Flipkart URL framed : "+ flipkartUrl);
connection = (HttpsURLConnection) url.openConnection();
setHeadersInConnectionObject(url, connection, requestBody.getMethod());
InputStream requestInputStream = requestBody.getInputStream();
String reqBody = getStringFromInputStream(requestBody.getInputStream());
OutputStream outputStream = connection.getOutputStream();
outputStream.write(reqBody.getBytes());
outputStream.flush();
if(connection.getResponseCode() == 401) {
connection.disconnect();
regenerateAccessToken();
connection = (HttpsURLConnection) url.openConnection();
setHeadersInConnectionObject(url, connection, requestBody.getMethod());
outputStream = connection.getOutputStream();
outputStream.write(reqBody.getBytes());
outputStream.flush();
}
String output = getStringFromInputStream (connection.getInputStream());
connection.disconnect();
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.exiting(CLASSNAME, methodName);
}
return output;
}
private static String getStringFromInputStream(InputStream is) {
String methodName = "getStringFromInputStream";
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.entering(CLASSNAME, methodName);
}
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
String line;
try {
br = new BufferedReader(new InputStreamReader(is));
while ((line = br.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.exiting(CLASSNAME, methodName);
}
return sb.toString();
}
/**
* Method to generate the access token
* #return String - Access token
* #throws IOException
*/
private String getAccessToken() throws IOException {
if (null != accessToken) {
return accessToken;
} else {
url = getClass().getResource(ServiceConstants.ACCESS_TOKEN_CONFIG_PATH);
file = new File(url.getPath());
reader = new BufferedReader (new InputStreamReader (new FileInputStream (file), ServiceConstants.UTF_ENCODING));
accessToken = reader.readLine();
reader.close();
return accessToken;
}
}
/**
* Method to construct error response for exception scenario
* #param errorMessage
* #return
*/
private String handleErrorResponse(String errorMessage) {
String methodName = "handleErrorResponse";
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.entering(CLASSNAME, methodName);
}
JSONObject errorResponse = new JSONObject();
JSONArray errorMsg = new JSONArray();
errorResponse.put(ServiceConstants.STATUS, ServiceConstants.STATUS_FAILED);
errorResponse.put(ServiceConstants.ERROR_MESSAGE, errorMessage);
errorMsg.add(errorResponse);
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.exiting(CLASSNAME, methodName);
}
return errorResponse.toString();
}
/**
* Method to form the connection object
* #param url
* #param connection
* #param requestType
* #throws IOException
*/
private void setHeadersInConnectionObject(URL url, HttpsURLConnection connection, String requestType) throws IOException {
String methodName = "setHeadersInConnectionObject";
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.entering(CLASSNAME, methodName);
}
if (null == accessToken) {
getAccessToken();
}
connection.setRequestMethod(requestType);
connection.setRequestProperty(ServiceConstants.AUTHORIZATION, ServiceConstants.BEARER + accessToken);
connection.setDoOutput(true);
if (requestType.equals(ServiceConstants.REQUEST_TYPE_GET)) {
connection.setRequestProperty(ServiceConstants.ACCEPT_HEADER, ServiceConstants.ACCEPT_ALL);
//connection.setRequestProperty(ServiceConstants.ACCEPT_HEADER, ServiceConstants.APPLICATION_JSON);
}
if (requestType.equals(ServiceConstants.REQUEST_TYPE_POST)) {
connection.setRequestProperty(ServiceConstants.ACCEPT_HEADER, ServiceConstants.APPLICATION_JSON);
connection.setRequestProperty(ServiceConstants.CONTENT_TYPE_HEADER, ServiceConstants.APPLICATION_JSON);
//connection.setDoInput(true);
}
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.exiting(CLASSNAME, methodName);
}
}
I have an XMPP Server which I have set up to send and receive Firebase Cloud Messages which has been working fine during testing with debugging turned on through the following 2 lines in my server code:
config.setDebuggerEnabled(true);
XMPPConnection.DEBUG_ENABLED = true;
I would now like to move this to my production ec2 instance and by doing so I have to change the 2 lines of code above to be false. After making this change my jar file no longer works.
Running the jar from CMD:
Microsoft Windows [Version 10.0.10586]
(c) 2015 Microsoft Corporation. All rights reserved.
C:\Users\Riley>cd "C:\Program Files\Java\jdk1.8.0_101\bin"
C:\Program Files\Java\jdk1.8.0_101\bin>java -jar D:\Downloads\XMPP-Chat-Server\server.jar
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.provider.UrlProviderFileInitializer initialize
INFO: Loading providers for file [classpath:META-INF/core.providers]
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.provider.ExtensionInitializer] specified in smack-config.xml could not be loaded:
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.ServiceDiscoveryManager] specified in smack-config.xml could not be loaded:
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.XHTMLManager] specified in smack-config.xml could not be loaded:
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.muc.MultiUserChat] specified in smack-config.xml could not be loaded:
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager] specified in smack-config.xml could not be loaded:
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamManager] specified in smack-config.xml could not be loaded:
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.filetransfer.FileTransferManager] specified in smack-config.xml could not be loaded:
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.LastActivityManager] specified in smack-config.xml could not be loaded:
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.commands.AdHocCommandManager] specified in smack-config.xml could not be loaded:
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.ping.PingManager] specified in smack-config.xml could not be loaded:
C:\Program Files\Java\jdk1.8.0_101\bin>
Here is my XMPP Server code:
package com.fcmserver;
/*
* Most part of this class is copyright Google.
* It is from https://developer.android.com/google/gcm/ccs.html
*/
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.PacketInterceptor;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.DefaultPacketExtension;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.provider.PacketExtensionProvider;
import org.jivesoftware.smack.provider.ProviderManager;
import org.jivesoftware.smack.util.StringUtils;
import org.json.simple.JSONValue;
import org.json.simple.parser.ParseException;
import org.xmlpull.v1.XmlPullParser;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.io.*;
import javax.net.ssl.SSLSocketFactory;
/**
* Sample Smack implementation of a client for GCM Cloud Connection Server.
*
* For illustration purposes only.
*/
public class SmackCcsClient {
static final String REG_ID_STORE = "gcmchat.txt";
static final String MESSAGE_KEY = "SM";
Logger logger = Logger.getLogger("SmackCcsClient");
public static final String GCM_SERVER = "fcm-xmpp.googleapis.com";
public static final int GCM_PORT = 5235;
public static final String GCM_ELEMENT_NAME = "gcm";
public static final String GCM_NAMESPACE = "google:mobile:data";
static Random random = new Random();
XMPPConnection connection;
ConnectionConfiguration config;
/**
* XMPP Packet Extension for GCM Cloud Connection Server.
*/
class GcmPacketExtension extends DefaultPacketExtension {
String json;
public GcmPacketExtension(String json) {
super(GCM_ELEMENT_NAME, GCM_NAMESPACE);
this.json = json;
}
public String getJson() {
return json;
}
#Override
public String toXML() {
return String.format("<%s xmlns=\"%s\">%s</%s>", GCM_ELEMENT_NAME,
GCM_NAMESPACE, json, GCM_ELEMENT_NAME);
}
#SuppressWarnings("unused")
public Packet toPacket() {
return new Message() {
// Must override toXML() because it includes a <body>
#Override
public String toXML() {
StringBuilder buf = new StringBuilder();
buf.append("<message");
if (getXmlns() != null) {
buf.append(" xmlns=\"").append(getXmlns()).append("\"");
}
if (getLanguage() != null) {
buf.append(" xml:lang=\"").append(getLanguage())
.append("\"");
}
if (getPacketID() != null) {
buf.append(" id=\"").append(getPacketID()).append("\"");
}
if (getTo() != null) {
buf.append(" to=\"")
.append(StringUtils.escapeForXML(getTo()))
.append("\"");
}
if (getFrom() != null) {
buf.append(" from=\"")
.append(StringUtils.escapeForXML(getFrom()))
.append("\"");
}
buf.append(">");
buf.append(GcmPacketExtension.this.toXML());
buf.append("</message>");
return buf.toString();
}
};
}
}
public SmackCcsClient() {
// Add GcmPacketExtension
ProviderManager.getInstance().addExtensionProvider(GCM_ELEMENT_NAME,
GCM_NAMESPACE, new PacketExtensionProvider() {
#Override
public PacketExtension parseExtension(XmlPullParser parser)
throws Exception {
String json = parser.nextText();
GcmPacketExtension packet = new GcmPacketExtension(json);
return packet;
}
});
}
/**
* Returns a random message id to uniquely identify a message.
*
* <p>
* Note: This is generated by a pseudo random number generator for
* illustration purpose, and is not guaranteed to be unique.
*
*/
public String getRandomMessageId() {
return "m-" + Long.toString(random.nextLong());
}
/**
* Sends a downstream GCM message.
*/
public void send(String jsonRequest) {
Packet request = new GcmPacketExtension(jsonRequest).toPacket();
connection.sendPacket(request);
}
/**
* Handles an upstream data message from a device application.
*
* <p>
* This sample echo server sends an echo message back to the device.
* Subclasses should override this method to process an upstream message.
*/
public void handleIncomingDataMessage(Map<String, Object> jsonObject) {
String from = jsonObject.get("from").toString();
// PackageName of the application that sent this message.
String category = jsonObject.get("category").toString();
// Use the packageName as the collapseKey in the echo packet
String collapseKey = "echo:CollapseKey";
#SuppressWarnings("unchecked")
Map<String, String> payload = (Map<String, String>) jsonObject
.get("data");
String messageText = payload.get("message_text");
String messageFrom = payload.get("message_userfrom");
String messageTime = payload.get("message_timestamp");
String toUser = payload.get("message_recipient");
String id = payload.get("message_alarm_id");
String messageType = payload.get("binder_message_type");
payload.put("message_text", messageText);
payload.put("message_userfrom", messageFrom);
payload.put("message_timestamp", messageTime);
payload.put("message_alarm_id", id);
payload.put("binder_message_type", messageType);
String message = createJsonMessage(toUser, getRandomMessageId(),
payload, collapseKey, null, false);
send(message);
}
/**
* Handles an ACK.
*
* <p>
* By default, it only logs a INFO message, but subclasses could override it
* to properly handle ACKS.
*/
public void handleAckReceipt(Map<String, Object> jsonObject) {
String messageId = jsonObject.get("message_id").toString();
String from = jsonObject.get("from").toString();
logger.log(Level.INFO, "handleAckReceipt() from: " + from
+ ", messageId: " + messageId);
}
/**
* Handles a NACK.
*
* <p>
* By default, it only logs a INFO message, but subclasses could override it
* to properly handle NACKS.
*/
public void handleNackReceipt(Map<String, Object> jsonObject) {
String messageId = jsonObject.get("message_id").toString();
String from = jsonObject.get("from").toString();
logger.log(Level.INFO, "handleNackReceipt() from: " + from
+ ", messageId: " + messageId);
}
/**
* Creates a JSON encoded GCM message.
*
* #param to
* RegistrationId of the target device (Required).
* #param messageId
* Unique messageId for which CCS will send an "ack/nack"
* (Required).
* #param payload
* Message content intended for the application. (Optional).
* #param collapseKey
* GCM collapse_key parameter (Optional).
* #param timeToLive
* GCM time_to_live parameter (Optional).
* #param delayWhileIdle
* GCM delay_while_idle parameter (Optional).
* #return JSON encoded GCM message.
*/
public static String createJsonMessage(String to, String messageId,
Map<String, String> payload, String collapseKey, Long timeToLive,
Boolean delayWhileIdle) {
Map<String, Object> message = new HashMap<String, Object>();
message.put("to", to);
if (collapseKey != null) {
message.put("collapse_key", collapseKey);
}
if (timeToLive != null) {
message.put("time_to_live", timeToLive);
}
if (delayWhileIdle != null && delayWhileIdle) {
message.put("delay_while_idle", true);
}
message.put("priority", "high");
message.put("message_id", messageId);
message.put("data", payload);
return JSONValue.toJSONString(message);
}
/**
* Creates a JSON encoded ACK message for an upstream message received from
* an application.
*
* #param to
* RegistrationId of the device who sent the upstream message.
* #param messageId
* messageId of the upstream message to be acknowledged to CCS.
* #return JSON encoded ack.
*/
public static String createJsonAck(String to, String messageId) {
Map<String, Object> message = new HashMap<String, Object>();
message.put("message_type", "ack");
message.put("to", to);
message.put("message_id", messageId);
return JSONValue.toJSONString(message);
}
/**
* Connects to GCM Cloud Connection Server using the supplied credentials.
*
* #param username
* GCM_SENDER_ID#gcm.googleapis.com
* #param password
* API Key
* #throws XMPPException
*/
public void connect(String username, String password) throws XMPPException {
config = new ConnectionConfiguration(GCM_SERVER, GCM_PORT);
config.setSecurityMode(SecurityMode.enabled);
config.setReconnectionAllowed(true);
config.setRosterLoadedAtLogin(false);
config.setSendPresence(false);
config.setSocketFactory(SSLSocketFactory.getDefault());
// NOTE: Set to true to launch a window with information about packets
// sent and received
config.setDebuggerEnabled(false);
// -Dsmack.debugEnabled=true
XMPPConnection.DEBUG_ENABLED = false;
connection = new XMPPConnection(config);
connection.connect();
connection.addConnectionListener(new ConnectionListener() {
#Override
public void reconnectionSuccessful() {
logger.info("Reconnecting..");
}
#Override
public void reconnectionFailed(Exception e) {
logger.log(Level.INFO, "Reconnection failed.. ", e);
}
#Override
public void reconnectingIn(int seconds) {
logger.log(Level.INFO, "Reconnecting in %d secs", seconds);
}
#Override
public void connectionClosedOnError(Exception e) {
logger.log(Level.INFO, "Connection closed on error.");
}
#Override
public void connectionClosed() {
logger.info("Connection closed.");
}
});
// Handle incoming packets
connection.addPacketListener(new PacketListener() {
#Override
public void processPacket(Packet packet) {
logger.log(Level.INFO, "Received: " + packet.toXML());
Message incomingMessage = (Message) packet;
GcmPacketExtension gcmPacket = (GcmPacketExtension) incomingMessage
.getExtension(GCM_NAMESPACE);
String json = gcmPacket.getJson();
try {
#SuppressWarnings("unchecked")
Map<String, Object> jsonObject = (Map<String, Object>) JSONValue
.parseWithException(json);
// present for "ack"/"nack", null otherwise
Object messageType = jsonObject.get("message_type");
if (messageType == null) {
// Normal upstream data message
handleIncomingDataMessage(jsonObject);
// Send ACK to CCS
String messageId = jsonObject.get("message_id")
.toString();
String from = jsonObject.get("from").toString();
String ack = createJsonAck(from, messageId);
send(ack);
} else if ("ack".equals(messageType.toString())) {
// Process Ack
handleAckReceipt(jsonObject);
} else if ("nack".equals(messageType.toString())) {
// Process Nack
handleNackReceipt(jsonObject);
} else {
logger.log(Level.WARNING,
"Unrecognized message type (%s)",
messageType.toString());
}
} catch (ParseException e) {
logger.log(Level.SEVERE, "Error parsing JSON " + json, e);
} catch (Exception e) {
logger.log(Level.SEVERE, "Couldn't send echo.", e);
}
}
}, new PacketTypeFilter(Message.class));
// Log all outgoing packets
connection.addPacketInterceptor(new PacketInterceptor() {
#Override
public void interceptPacket(Packet packet) {
logger.log(Level.INFO, "Sent: {0}", packet.toXML());
}
}, new PacketTypeFilter(Message.class));
connection.login(username, password);
}
public void writeToFile(String name, String regId) throws IOException {
Map<String, String> regIdMap = readFromFile();
regIdMap.put(name, regId);
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(
REG_ID_STORE, false)));
for (Map.Entry<String, String> entry : regIdMap.entrySet()) {
out.println(entry.getKey() + "," + entry.getValue());
}
out.println(name + "," + regId);
out.close();
}
public Map<String, String> readFromFile() {
Map<String, String> regIdMap = null;
try {
BufferedReader br = new BufferedReader(new FileReader(REG_ID_STORE));
String regIdLine = "";
regIdMap = new HashMap<String, String>();
while ((regIdLine = br.readLine()) != null) {
String[] regArr = regIdLine.split(",");
regIdMap.put(regArr[0], regArr[1]);
}
br.close();
} catch(IOException ioe) {
}
return regIdMap;
}
public static void main(String [] args) {
final String userName = "USERNAME" + "#gcm.googleapis.com";
final String password = "PASSWORD";
SmackCcsClient ccsClient = new SmackCcsClient();
try {
ccsClient.connect(userName, password);
} catch (XMPPException e) {
e.printStackTrace();
}
}
}
So I figured this out. I changed the following code:
public static void main(String [] args) {
final String userName = "USERNAME" + "#gcm.googleapis.com";
final String password = "PASSWORD";
SmackCcsClient ccsClient = new SmackCcsClient();
try {
ccsClient.connect(userName, password);
} catch (XMPPException e) {
e.printStackTrace();
}
}
}
To the following:
public static void main(String [] args) {
final String userName = "USERNAME" + "#gcm.googleapis.com";
final String password = "PASSWORD";
SmackCcsClient ccsClient = new SmackCcsClient();
try {
ccsClient.connect(userName, password);
} catch (XMPPException e) {
e.printStackTrace();
}
try {
CountDownLatch latch = new CountDownLatch(1);
latch.await();
} catch (InterruptedException e) {
logger.log(Level.SEVERE, "An error occurred while latch was waiting.", e);
}
}
}
}
I know that there are several similar questions that have either been answered or still outstanding, however, for the life of me...
Later Edit 2016-08-25 10:05 CST - Actually, I asked the wrong question.
The question is the following: given that I have both a netty server (taken from DiscardServer example) and a netty client - (see above) what must I do to force the DiscardServer to immediately send the client a request?
I have added an OutboundHandler to the server and to the client.
After looking at both the DiscardServer and PingPongServer examples, there is an external event occurring to kick off all the action. In the case of Discard server, it is originally waiting for a telnet connection, then will transmit whatever was in the telnet msg to the client.
In the case of PingPongServer, the SERVER is waiting on the client to initiate action.
What I want is for the Server to immediately start transmitting after connection with the client. None of the examples from netty seem to do this.
If I have missed something, and someone can point it out, much good karma.
My client:
public final class P4Listener {
static final Logger LOG;
static final String HOST;
static final int PORT;
static final Boolean SSL = Boolean.FALSE;
public static Dto DTO;
static {
LOG = LoggerFactory.getLogger(P4Listener.class);
HOST = P4ListenerProperties.getP4ServerAddress();
PORT = Integer.valueOf(P4ListenerProperties.getListenerPort());
DTO = new Dto();
}
public static String getId() { return DTO.getId(); }
public static void main(String[] args) throws Exception {
final SslContext sslCtx;
if (SSL) {
LOG.info("{} creating SslContext", getId());
sslCtx = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build();
} else {
sslCtx = null;
}
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group).channel(NioSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO))
.handler(new P4ListenerInitializer(sslCtx));
// Start the connection attempt.
LOG.debug(" {} starting connection attempt...", getId());
Channel ch = b.connect(HOST, PORT).sync().channel();
// ChannelFuture localWriteFuture = ch.writeAndFlush("ready\n");
// localWriteFuture.sync();
} finally {
group.shutdownGracefully();
}
}
}
public class P4ListenerHandler extends SimpleChannelInboundHandler<String> {
static final Logger LOG = LoggerFactory.getLogger(P4ListenerHandler.class);
static final DateTimeFormatter DTFormatter = DateTimeFormatter.ofPattern("yyyyMMdd-HHMMss.SSS");
static final String EndSOT;
static final String StartSOT;
static final String EOL = "\n";
static final ClassPathXmlApplicationContext AppContext;
static {
EndSOT = P4ListenerProperties.getEndSOT();
StartSOT = P4ListenerProperties.getStartSOT();
AppContext = new ClassPathXmlApplicationContext(new String[] { "applicationContext.xml" });
}
private final RequestValidator rv = new RequestValidator();
private JAXBContext jaxbContext = null;
private Unmarshaller jaxbUnmarshaller = null;
private boolean initialized = false;
private Dto dto;
public P4ListenerHandler() {
dto = new Dto();
}
public Dto getDto() { return dto; }
public String getId() { return getDto().getId(); }
Message convertXmlToMessage(String xml) {
if (xml == null)
throw new IllegalArgumentException("xml message is null!");
try {
jaxbContext = JAXBContext.newInstance(p4.model.xml.request.Message.class, p4.model.xml.request.Header.class,
p4.model.xml.request.Claims.class, p4.model.xml.request.Insurance.class,
p4.model.xml.request.Body.class, p4.model.xml.request.Prescriber.class,
p4.model.xml.request.PriorAuthorization.class,
p4.model.xml.request.PriorAuthorizationSupportingDocumentation.class);
jaxbUnmarshaller = jaxbContext.createUnmarshaller();
StringReader strReader = new StringReader(xml);
Message m = (Message) jaxbUnmarshaller.unmarshal(strReader);
return m;
} catch (JAXBException jaxbe) {
String error = StacktraceUtil.getCustomStackTrace(jaxbe);
LOG.error(error);
throw new P4XMLUnmarshalException("Problems when attempting to unmarshal transmission string: \n" + xml,
jaxbe);
}
}
#Override
public void channelActive(ChannelHandlerContext ctx) {
LOG.debug("{} let server know we are ready", getId());
ctx.writeAndFlush("Ready...\n");
}
/**
* Important - this method will be renamed to
* <code><b>messageReceived(ChannelHandlerContext, I)</b></code> in netty 5.0
*
* #param ctx
* #param msg
*/
#Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
ChannelFuture lastWriteFuture = null;
LOG.debug("{} -- received message: {}", getId(), msg);
Channel channel = ctx.channel();
Message m = null;
try {
if (msg instanceof String && msg.length() > 0) {
m = convertXmlToMessage(msg);
m.setMessageStr(msg);
dto.setRequestMsg(m);
LOG.info("{}: received TIMESTAMP: {}", dto.getId(), LocalDateTime.now().format(DTFormatter));
LOG.debug("{}: received from server: {}", dto.getId(), msg);
/*
* theoretically we have a complete P4(XML) request
*/
final List<RequestFieldError> errorList = rv.validateMessage(m);
if (!errorList.isEmpty()) {
for (RequestFieldError fe : errorList) {
lastWriteFuture = channel.writeAndFlush(fe.toString().concat(EOL));
}
}
/*
* Create DBHandler with message, messageStr, clientIp to get
* dbResponse
*/
InetSocketAddress socketAddress = (InetSocketAddress) channel.remoteAddress();
InetAddress inetaddress = socketAddress.getAddress();
String clientIp = inetaddress.getHostAddress();
/*
* I know - bad form to ask the ApplicationContext for the
* bean... BUT ...lack of time turns angels into demons
*/
final P4DbRequestHandler dbHandler = (P4DbRequestHandler) AppContext.getBean("dbRequestHandler");
// must set the requestDTO for the dbHandler!
dbHandler.setClientIp(clientIp);
dbHandler.setRequestDTO(dto);
//
// build database request and receive response (string)
String dbResponse = dbHandler.submitDbRequest();
/*
* create ResponseHandler and get back response string
*/
P4ResponseHandler responseHandler = new P4ResponseHandler(dto, dbHandler);
String responseStr = responseHandler.decodeDbServiceResponse(dbResponse);
/*
* write response string to output and repeat exercise
*/
LOG.debug("{} -- response to be written back to server:\n {}", dto.getId(), responseStr);
lastWriteFuture = channel.writeAndFlush(responseStr.concat(EOL));
//
LOG.info("{}: response sent TIMESTAMP: {}", dto.getId(), LocalDateTime.now().format(DTFormatter));
} else {
throw new P4EventException(dto.getId() + " -- Message received is not a String");
}
processWriteFutures(lastWriteFuture);
} catch (Throwable t) {
String tError = StacktraceUtil.getCustomStackTrace(t);
LOG.error(tError);
} finally {
if (lastWriteFuture != null) {
lastWriteFuture.sync();
}
}
}
private void processWriteFutures(ChannelFuture writeFuture) throws InterruptedException {
// Wait until all messages are flushed before closing the channel.
if (writeFuture != null) {
writeFuture.sync();
}
}
#Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
/**
* Creates a newly configured {#link ChannelPipeline} for a new channel.
*/
public class P4ListenerInitializer extends ChannelInitializer<SocketChannel> {
private static final StringDecoder DECODER = new StringDecoder();
private static final StringEncoder ENCODER = new StringEncoder();
private final SslContext sslCtx;
public P4ListenerInitializer(SslContext sslCtx) {
this.sslCtx = sslCtx;
}
#Override
public void initChannel(SocketChannel ch) {
P4ListenerHandler lh = null;
ChannelPipeline pipeline = ch.pipeline();
if (sslCtx != null) {
P4Listener.LOG.info("{} -- constructing SslContext new handler ", P4Listener.getId());
pipeline.addLast(sslCtx.newHandler(ch.alloc(), P4Listener.HOST, P4Listener.PORT));
} else {
P4Listener.LOG.info("{} -- SslContext null; bypassing adding sslCtx.newHandler(ch.alloc(), P4Listener.HOST, P4Listener.PORT) ", P4Listener.getId());
}
// Add the text line codec combination first,
pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
pipeline.addLast(DECODER);
P4Listener.LOG.debug("{} -- added Decoder ", P4Listener.getId());
pipeline.addLast(ENCODER);
P4Listener.LOG.debug("{} -- added Encoder ", P4Listener.getId());
// and then business logic.
pipeline.addLast(lh = new P4ListenerHandler());
P4Listener.LOG.debug("{} -- added P4ListenerHandler: {} ", P4Listener.getId(), lh.getClass().getSimpleName());
}
}
#Sharable
public class P4ListenerOutboundHandler extends ChannelOutboundHandlerAdapter {
static final Logger LOG = LoggerFactory.getLogger(P4ListenerOutboundHandler.class);
private Dto outBoundDTO = new Dto();
public String getId() {return this.outBoundDTO.getId(); }
#Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
try {
ChannelFuture lastWrite = ctx.write(Unpooled.copiedBuffer((String) msg, CharsetUtil.UTF_8));
try {
if (lastWrite != null) {
lastWrite.sync();
promise.setSuccess();
}
} catch (InterruptedException e) {
promise.setFailure(e);
e.printStackTrace();
}
} finally {
ReferenceCountUtil.release(msg);
}
}
}
output from client
Just override channelActive(...) on the handler of the server and trigger a write there.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Running a .sql script using MySQL with JDBC
I have an SQL script file which contains 40-50 SQL statements. Is it possible to run this script file using JDBC?
This link might help you out: http://pastebin.com/f10584951.
Pasted below for posterity:
/*
* Slightly modified version of the com.ibatis.common.jdbc.ScriptRunner class
* from the iBATIS Apache project. Only removed dependency on Resource class
* and a constructor
*/
/*
* Copyright 2004 Clinton Begin
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.sql.*;
/**
* Tool to run database scripts
*/
public class ScriptRunner {
private static final String DEFAULT_DELIMITER = ";";
private Connection connection;
private boolean stopOnError;
private boolean autoCommit;
private PrintWriter logWriter = new PrintWriter(System.out);
private PrintWriter errorLogWriter = new PrintWriter(System.err);
private String delimiter = DEFAULT_DELIMITER;
private boolean fullLineDelimiter = false;
/**
* Default constructor
*/
public ScriptRunner(Connection connection, boolean autoCommit,
boolean stopOnError) {
this.connection = connection;
this.autoCommit = autoCommit;
this.stopOnError = stopOnError;
}
public void setDelimiter(String delimiter, boolean fullLineDelimiter) {
this.delimiter = delimiter;
this.fullLineDelimiter = fullLineDelimiter;
}
/**
* Setter for logWriter property
*
* #param logWriter
* - the new value of the logWriter property
*/
public void setLogWriter(PrintWriter logWriter) {
this.logWriter = logWriter;
}
/**
* Setter for errorLogWriter property
*
* #param errorLogWriter
* - the new value of the errorLogWriter property
*/
public void setErrorLogWriter(PrintWriter errorLogWriter) {
this.errorLogWriter = errorLogWriter;
}
/**
* Runs an SQL script (read in using the Reader parameter)
*
* #param reader
* - the source of the script
*/
public void runScript(Reader reader) throws IOException, SQLException {
try {
boolean originalAutoCommit = connection.getAutoCommit();
try {
if (originalAutoCommit != this.autoCommit) {
connection.setAutoCommit(this.autoCommit);
}
runScript(connection, reader);
} finally {
connection.setAutoCommit(originalAutoCommit);
}
} catch (IOException e) {
throw e;
} catch (SQLException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException("Error running script. Cause: " + e, e);
}
}
/**
* Runs an SQL script (read in using the Reader parameter) using the
* connection passed in
*
* #param conn
* - the connection to use for the script
* #param reader
* - the source of the script
* #throws SQLException
* if any SQL errors occur
* #throws IOException
* if there is an error reading from the Reader
*/
private void runScript(Connection conn, Reader reader) throws IOException,
SQLException {
StringBuffer command = null;
try {
LineNumberReader lineReader = new LineNumberReader(reader);
String line = null;
while ((line = lineReader.readLine()) != null) {
if (command == null) {
command = new StringBuffer();
}
String trimmedLine = line.trim();
if (trimmedLine.startsWith("--")) {
println(trimmedLine);
} else if (trimmedLine.length() < 1
|| trimmedLine.startsWith("//")) {
// Do nothing
} else if (trimmedLine.length() < 1
|| trimmedLine.startsWith("--")) {
// Do nothing
} else if (!fullLineDelimiter
&& trimmedLine.endsWith(getDelimiter())
|| fullLineDelimiter
&& trimmedLine.equals(getDelimiter())) {
command.append(line.substring(0, line
.lastIndexOf(getDelimiter())));
command.append(" ");
Statement statement = conn.createStatement();
println(command);
boolean hasResults = false;
if (stopOnError) {
hasResults = statement.execute(command.toString());
} else {
try {
statement.execute(command.toString());
} catch (SQLException e) {
e.fillInStackTrace();
printlnError("Error executing: " + command);
printlnError(e);
}
}
if (autoCommit && !conn.getAutoCommit()) {
conn.commit();
}
ResultSet rs = statement.getResultSet();
if (hasResults && rs != null) {
ResultSetMetaData md = rs.getMetaData();
int cols = md.getColumnCount();
for (int i = 0; i < cols; i++) {
String name = md.getColumnLabel(i);
print(name + "\t");
}
println("");
while (rs.next()) {
for (int i = 0; i < cols; i++) {
String value = rs.getString(i);
print(value + "\t");
}
println("");
}
}
command = null;
try {
statement.close();
} catch (Exception e) {
// Ignore to workaround a bug in Jakarta DBCP
}
Thread.yield();
} else {
command.append(line);
command.append(" ");
}
}
if (!autoCommit) {
conn.commit();
}
} catch (SQLException e) {
e.fillInStackTrace();
printlnError("Error executing: " + command);
printlnError(e);
throw e;
} catch (IOException e) {
e.fillInStackTrace();
printlnError("Error executing: " + command);
printlnError(e);
throw e;
} finally {
conn.rollback();
flush();
}
}
private String getDelimiter() {
return delimiter;
}
private void print(Object o) {
if (logWriter != null) {
System.out.print(o);
}
}
private void println(Object o) {
if (logWriter != null) {
logWriter.println(o);
}
}
private void printlnError(Object o) {
if (errorLogWriter != null) {
errorLogWriter.println(o);
}
}
private void flush() {
if (logWriter != null) {
logWriter.flush();
}
if (errorLogWriter != null) {
errorLogWriter.flush();
}
}
}
I use this bit of code to import sql statements created by mysqldump:
public static void importSQL(Connection conn, InputStream in) throws SQLException
{
Scanner s = new Scanner(in);
s.useDelimiter("(;(\r)?\n)|(--\n)");
Statement st = null;
try
{
st = conn.createStatement();
while (s.hasNext())
{
String line = s.next();
if (line.startsWith("/*!") && line.endsWith("*/"))
{
int i = line.indexOf(' ');
line = line.substring(i + 1, line.length() - " */".length());
}
if (line.trim().length() > 0)
{
st.execute(line);
}
}
}
finally
{
if (st != null) st.close();
}
}
Another option, this DOESN'T support comments, very useful with AmaterasERD DDL export for Apache Derby:
public void executeSqlScript(Connection conn, File inputFile) {
// Delimiter
String delimiter = ";";
// Create scanner
Scanner scanner;
try {
scanner = new Scanner(inputFile).useDelimiter(delimiter);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
return;
}
// Loop through the SQL file statements
Statement currentStatement = null;
while(scanner.hasNext()) {
// Get statement
String rawStatement = scanner.next() + delimiter;
try {
// Execute statement
currentStatement = conn.createStatement();
currentStatement.execute(rawStatement);
} catch (SQLException e) {
e.printStackTrace();
} finally {
// Release resources
if (currentStatement != null) {
try {
currentStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
currentStatement = null;
}
}
scanner.close();
}
Just read it and then use the preparedstatement with the full sql-file in it.
(If I remember good)
ADD: You can also read and split on ";" and than execute them all in a loop.
Do not forget the comments and add again the ";"
You should be able to parse the SQL file into statements. And run a single statement a time. If you know that your file consists of simple insert/update/delete statements you can use a semicolon as statement delimiter. In common case you have a task to create your specific SQL-dialect parser.
I had the same problem trying to execute an SQL script that creates an SQL database. Googling here and there I found a Java class initially written by Clinton Begin which supports comments (see http://pastebin.com/P14HsYAG). I modified slightly the file to cater for triggers where one has to change the default DELIMITER to something different. I've used that version ScriptRunner (see http://pastebin.com/sb4bMbVv). Since an (open source and free) SQLScriptRunner class is an absolutely necessary utility, it would be good to have some more input from developers and hopefully we'll have soon a more stable version of it.
You can read the script line per line with a BufferedReader and append every line to a StringBuilder so that the script becomes one large string.
Then you can create a Statement object using JDBC and call statement.execute(stringBuilder.toString()).