I have a problem with springboot application that should work as a server for android application. I have audio file (.wav) that android application should receive from a server.
On local host it works very well, but when I make it on linux server there NullPointerException is appearing.
Here is my code of AudioController:
#RestController
#RequestMapping("/audiovideo")
public class AudioController {
public static final String AUDIO_PATH = "/root/audios/";
public static final int BYTE_RANGE = 128;
#GetMapping("/audios/{fileName}")
public Mono<ResponseEntity<byte[]>> streamAudio(#RequestHeader(value = "Range", required = false) String httpRangeList,
#PathVariable("fileName") String fileName) {
return Mono.just(getContent(AUDIO_PATH, fileName, httpRangeList, "audio"));
}
private ResponseEntity<byte[]> getContent(String location, String fileName, String range, String contentTypePrefix) {
long rangeStart = 0;
long rangeEnd;
byte[] data;
Long fileSize;
String fileType = fileName.substring(fileName.lastIndexOf(".")+1);
try {
fileSize = Optional.ofNullable(fileName)
.map(file -> Paths.get(getFilePath(location), file))
.map(this::sizeFromFile)
.orElse(0L);
if (range == null) {
return ResponseEntity.status(HttpStatus.OK)
.header("Content-Type", contentTypePrefix+"/" + fileType)
.header("Content-Length", String.valueOf(fileSize))
.body(readByteRange(location, fileName, rangeStart, fileSize - 1));
}
String[] ranges = range.split("-");
rangeStart = Long.parseLong(ranges[0].substring(6));
if (ranges.length > 1) {
rangeEnd = Long.parseLong(ranges[1]);
} else {
rangeEnd = fileSize - 1;
}
if (fileSize < rangeEnd) {
rangeEnd = fileSize - 1;
}
data = readByteRange(location, fileName, rangeStart, rangeEnd);
} catch (IOException e) {
e.printStackTrace();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
String contentLength = String.valueOf((rangeEnd - rangeStart) + 1);
return ResponseEntity.status(HttpStatus.PARTIAL_CONTENT)
.header("Content-Type", contentTypePrefix + "/" + fileType)
.header("Accept-Ranges", "bytes")
.header("Content-Length", contentLength)
.header("Content-Range", "bytes" + " " + rangeStart + "-" + rangeEnd + "/" + fileSize)
.body(data);
}
public byte[] readByteRange(String location, String filename, long start, long end) throws IOException {
Path path = Paths.get(getFilePath(location), filename);
try (InputStream inputStream = (Files.newInputStream(path));
ByteArrayOutputStream bufferedOutputStream = new ByteArrayOutputStream()) {
byte[] data = new byte[BYTE_RANGE];
int nRead;
while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
bufferedOutputStream.write(data, 0, nRead);
}
bufferedOutputStream.flush();
byte[] result = new byte[(int) (end - start) + 1];
System.arraycopy(bufferedOutputStream.toByteArray(), (int) start, result, 0, result.length);
return result;
}
}
private String getFilePath(String location) {
URL url = this.getClass().getResource(location);
return new File(url.getFile()).getAbsolutePath();
}
private Long sizeFromFile(Path path) {
try {
return Files.size(path);
} catch (IOException ex) {
e.printStackTrace();
}
return 0L;
}
}
File is located in right path (/root/audios/[FileName])
Is there any solution of this problem?
P.S. There is another controller for music info but it works perfectly and I don't know why is the audio controller isn't working correctly
Here it is:
#RequestMapping("/musicinfo/jsons")
#RestController
public class APIController {
#GetMapping(value = "/{filename}")
public ResponseEntity<StreamingResponseBody> streamInfo(#PathVariable String filename) throws FileNotFoundException{
File file = ResourceUtils.getFile("/root/musicinfo/" + filename);
StreamingResponseBody responseBody = outputStream -> {
Files.copy(file.toPath(), outputStream);
};
return ResponseEntity.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(responseBody);
}
}
Thanks forehead for help!!!
Related
I am unable to do this in my android app using java language. I am using the retrofit library for this but the problem is the signature. unable to generate proper signature which gives me an error. It is working in POSTMAN and getting proper responses. Help me to convert this in JAVA.
Documentation of API - https://docs.wazirx.com/#fund-details-user_data
POSTMAN PRE-REQUEST SCRIPT
MAIN PARAMS --> BASE_URL, API_KEY, SECRET_KEY, SIGNATURE & TIMESTAMP in miliseconds.
var navigator = {}; //fake a navigator object for the lib
var window = {}; //fake a window object for the lib
const privateKey = pm.environment.get("rsa_private_key");
const secretKey = pm.environment.get("secret_key");
// Set Current Time
var time = new Date().getTime()
postman.setEnvironmentVariable("current_time", time)
query_a = pm.request.url.query.toObject(true)
// Generate Request Payload
let query_string_array = []
Object.keys(query_a).forEach(function(key) {
if (key == 'signature') { return }
if (key == 'timestamp') {
query_string_array.push(key + "=" + time)
}
else if (typeof query_a[key] == "string") {
query_string_array.push(key + "=" + query_a[key])
} else {
query_a[key].forEach(function(value){
query_string_array.push(key + "=" + value)
})
}
})
const payload = query_string_array.join("&")
console.log("Request Payload = ", payload)
if(secretKey) {
const signature = CryptoJS.HmacSHA256(payload, secretKey) + ''
pm.environment.set("signature", signature)
console.log("Signature = "+signature);
} else {
// Download RSA Library
pm.sendRequest(pm.environment.get("rsa_library_js"), function (err, res) {
if (err){
console.log("Error: " + err);
}
else {
// Compile & Run RSA Library
eval(res.text())();
// Sign Payload
var signatureLib = new KJUR.crypto.Signature({"alg": "SHA256withRSA"});
signatureLib.init(privateKey);
signatureLib.updateString(payload);
var signatureHash = hex2b64(signatureLib.sign());
console.log("Signature = ", signatureHash)
// Assign Values
pm.environment.set("signature", encodeURIComponent(signatureHash, "UTF-8"))
}
})
}
Java Code:
//REQUEST CLASS START -->
public class Request {
String baseUrl;
String apiKey="1***uR7";
String apiSecret="b1**qVmh";
Signature sign = new Signature();
public Request(String baseUrl, String apiKey, String apiSecret) {
this.baseUrl = baseUrl;
this.apiKey = apiKey;
this.apiSecret = apiSecret;
}
private void printResponse(HttpURLConnection con) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(
con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
}
private void printError(HttpURLConnection con) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(
con.getErrorStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
}
private String getTimeStamp() {
long timestamp = System.currentTimeMillis();
return "timestamp=" + timestamp;
}
//concatenate query parameters
private String joinQueryParameters(HashMap<String,String> parameters) {
String urlPath = "";
boolean isFirst = true;
for (Map.Entry mapElement : parameters.entrySet()) {
if (isFirst) {
isFirst = false;
urlPath += mapElement.getKey() + "=" + mapElement.getValue();
} else {
urlPath += "&" + mapElement.getKey() + "=" + mapElement.getValue();
}
}
return urlPath;
}
private void send(URL obj, String httpMethod) throws Exception {
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
if (httpMethod != null) {
con.setRequestMethod(httpMethod);
}
//add API_KEY to header content
con.setRequestProperty("X-API-KEY", apiKey);
int responseCode = con.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) { // success
printResponse(con);
} else {
printError(con);
}
}
public void sendPublicRequest(HashMap<String,String> parameters, String urlPath) throws Exception {
String queryPath = joinQueryParameters(parameters);
URL obj = new URL(baseUrl + urlPath + "?" + queryPath);
System.out.println("url:" + obj.toString());
send(obj, null);
}
public void sendSignedRequest(HashMap<String,String> parameters, String urlPath, String httpMethod) throws Exception {
String queryPath = "";
String signature = "";
if (!parameters.isEmpty()) {
queryPath += joinQueryParameters(parameters) + "&" + getTimeStamp();
} else {
queryPath += getTimeStamp();
}
try {
signature = sign.getSignature(queryPath, apiSecret);
}
catch (Exception e) {
System.out.println("Please Ensure Your Secret Key Is Set Up Correctly! " + e);
System.exit(0);
}
queryPath += "&signature=" + signature;
URL obj = new URL(baseUrl + urlPath + "?" + queryPath);
System.out.println("url:" + obj.toString());
send(obj, httpMethod);
}
}
//REQUEST CLASS END -->
//SPOT CLASS START -->
public class Spot {
private static final String API_KEY = System.getenv("1***57");
private static final String API_SECRET = System.getenv("b****n8");
HashMap<String,String> parameters = new HashMap<String,String>();
Request httpRequest;
public Spot() {
String baseUrl = "https://api.wazirx.com";
httpRequest = new Request(baseUrl, API_KEY, API_SECRET);
}
public void account() throws Exception {
httpRequest.sendSignedRequest(parameters, "/sapi/v1/funds", "GET");
}
}
//SPOT CLASS END-->
//SIGNATURE CLASS START-->
public class Signature {
final String HMAC_SHA256 = "HmacSHA256";
//convert byte array to hex string
private String bytesToHex(byte[] bytes) {
final char[] hexArray = "0123456789abcdef".toCharArray();
char[] hexChars = new char[bytes.length * 2];
for (int j = 0, v; j < bytes.length; j++) {
v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
public String getSignature(String data, String key) {
byte[] hmacSha256 = null;
try {
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), HMAC_SHA256);
Mac mac = Mac.getInstance(HMAC_SHA256);
mac.init(secretKeySpec);
hmacSha256 = mac.doFinal(data.getBytes());
} catch (Exception e) {
throw new RuntimeException("Failed to calculate hmac-sha256", e);
}
return bytesToHex(hmacSha256);
}
}
//SIGNATURE CLASS END-->
My English Hope you can understand me.
Hello guys, im developing a web program using Apache Velocity, but i meet a problem, i cannot return view after output a file by OutPutStream, following is my code:
#Get("test")
public String getPdfInfoByTestId(Invocation invocation, #Param("testIds") String testIds) throws Exception {
HttpServletResponse response = invocation.getResponse();
if (testIds.length() == 0) {
invocation.addModel("status", PdfStatusEnum.NOT_FOUND.getType());
return "admin_pdf_info";
}
String[] idArray = testIds.split(",");
List<Long> idList = string2LongList(testIds);
List<ContestOneTest> contestOneTestList = contestOneTestService.getByIdList(idList);
if (contestOneTestList.size() == 0) {
invocation.addModel("status", PdfStatusEnum.NOT_FOUND.getType());
//response.sendRedirect("index");
return "admin_pdf_info";
}
List<PdfInfo> pdfInfos = new ArrayList<>(contestOneTestList.size() + 1);
//填充表格需要的数据
for (ContestOneTest contestOneTest : contestOneTestList) {
PdfInfo pdfInfo = new PdfInfo();
CtsTestUser ctsTestUser = ctsTestUserService.getUserById(contestOneTest.getActorId());
pdfInfo.setActorName(ctsTestUser.getName());
pdfInfo.setTestId(contestOneTest.getId());
pdfInfo.setPaperName(contestOneTest.getPaperName());
pdfInfo.setPaperId(contestOneTest.getPaperId());
if (contestOneTest.getStatus() == OneTestStatusEnum.FINISHED.getValue() && StringUtils.isNotBlank(contestOneTest.getPdfUrl())) {
pdfInfo.setGenStatus("已处理");
pdfInfo.setRank("无需排队");
pdfInfo.setPdfUrl(contestOneTest.getPdfUrl());
} else {
pdfInfo.setGenStatus("未处理");
Long rank = JedisAdapter.zRank(RedisKeyUtil.getNewContestPdfGenQueue(),
contestOneTest.getId() + "");
pdfInfo.setRank(String.valueOf(rank));
pdfInfo.setPdfUrl("暂无");
}
}
XSSFWorkbook workbook;
String fileName = new StringBuilder().append(contestOneTestList.size())
.append("位考试的PDF生成进度").toString();
try {
//生成表格并作为下载文件输出
workbook = ExcelUtils.buildWorkbook(pdfInfos);
invocation.addModel("status", PdfStatusEnum.HAS_GENERATED);
invocation.addModel("resultCount", contestOneTestList.size());
response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
response.setHeader("Content-Type",
"application/vnd.ms-excel");
OutputStream out = response.getOutputStream();
workbook.write(out);
} catch (Exception e) {
e.printStackTrace();
invocation.addModel("status", PdfStatusEnum.ExcelGenFailed.getType());
}
return "admin_pdf_info";
}
Is there any way to solve my problem?
Very grateful for all answers or suggesstions!
I am using the following code to build a zip file on my external storage, the only problem is that the file can't be extracted on a Windows PC or be used for anything other than Android, I think I have narrowed the problem to a non-existent folder.
My question is what have I done wrong to cause a weird format of zip?
/**
EXAMPLE USAGE : zipFolder("/sdcard0/downloads", "/sdcard0/Update.zip")
**/
static public void zipFolder(String srcFolder, String destZipFile)
throws Exception
{
ZipOutputStream zip = null;
FileOutputStream fileWriter = null;
fileWriter = new FileOutputStream(destZipFile);
zip = new ZipOutputStream(fileWriter);
addFolderToZip("", srcFolder, zip);
zip.flush();
zip.close();
}
static String firstFolder ="";
static private void addFileToZip(String path, String srcFile,
ZipOutputStream zip) throws Exception
{
if (firstFolder == "")
{
firstFolder = getLastPathComponent(path);
}
File folder = new File(srcFile);
if (folder.isDirectory())
{
addFolderToZip(path, srcFile, zip);
}
else
{
byte[] buf = new byte[1024];
int len;
FileInputStream in = new FileInputStream(srcFile);
zip.putNextEntry(new ZipEntry(path.replace(firstFolder, "") + "/" + folder.getName()));
while ((len = in.read(buf)) > 0)
{
zip.write(buf, 0, len);
}
}
}
public static String getLastPathComponent(String filePath)
{
String[] segments = filePath.split("/");
if (segments.length == 0)
return "";
String lastPathComponent = segments[segments.length - 1];
return lastPathComponent;
}
static private void addFolderToZip(String path, String srcFolder,
ZipOutputStream zip) throws Exception
{
File folder = new File(srcFolder);
for (String fileName : folder.list())
{
if (path.equals(""))
{
addFileToZip(folder.getName().replace(firstFolder, ""), srcFolder + "/" + fileName, zip);
}
else
{
addFileToZip(path + "/" + folder.getName(), srcFolder + "/"
+ fileName, zip);
}
}
}
#RequestMapping(value = "/video/{clientID}/{fileName}", method = RequestMethod.GET)
public ResponseEntity<StreamingResponseBody> getClientVideo(#PathVariable(value = "clientID") Integer clientID, #PathVariable(value = "fileName") final String fileName) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
String absolutePath = new File(".").getAbsolutePath();
File file = new File(Paths.get(absolutePath).getParent() + "/" + clientID);
if (null != file) {
FilenameFilter beginswithm = new FilenameFilter() {
public boolean accept(File directory, String filename) {
return filename.contains("ClientVideo_"+fileName);
}
};
File[] files = file.listFiles(beginswithm);
if (null != files && files.length > 0) {
Resource resource = null;
for (final File f : files) {
headers.set("Content-Disposition", "inline; filename=" + f.getName());
StreamingResponseBody responseBody = new StreamingResponseBody() {
#Override
public void writeTo(OutputStream out) throws IOException {
out.write(Files.readAllBytes(f.toPath()));
out.flush();
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
return ResponseEntity.ok().headers(headers).contentType(MediaType.APPLICATION_OCTET_STREAM).body(responseBody); //(responseBody, headers, HttpStatus.OK);
}
}
}
RecruiterResponseBean resBean = new RecruiterResponseBean();
resBean.setStatusMessage("Video is not present : " + Constants.FAILED);
resBean.setStatusCode(Constants.FAILED_CODE);
return new ResponseEntity(HttpStatus.NOT_FOUND);
}
video streaming is working but it is very slow. how to increase the efficiency?
There is no problem with internet it is 10mbps. i am using tomcat 7 and Spring MVC[4.2.4]. should I change the tomcat capacity or how it can be solve? i am not getting in google.
This question already has answers here:
java.lang.OutOfMemoryError: Java heap space
(12 answers)
Closed 5 years ago.
The following code of servlet receives huge JSON string every minute and near about after 2 hours I always got the OutOfMemoryError: Java Heap Space
public class GetScanAlertServlet extends HttpServlet {
private String scanType = "";
private static final String path = "D:\\Mobile_scan_alerts8180";
private static final String stockFileName = "stock.txt";
private static final String foFileName = "fo.txt";
private static Logger logger = null;
private String currDate = "";
private DateFormat dateFormat;
private StringBuffer stockData;
private StringBuffer foData;
StringBuffer data = new StringBuffer("");
// For average time of received data
private static float sum = 0;
private static float count = 0;
private static float s_sum = 0;
private static float s_count = 0;
private static float fo_sum = 0;
private static float fo_count = 0;
private static final File dir = new File(path);
private static final File stockFile = new File(path + "\\" + stockFileName);
private static final File foFile = new File(path + "\\" + foFileName);
public void init() {
logger = MyLogger.getScanAlertLogger();
if(logger == null) {
MyLogger.createLog();
logger = MyLogger.getScanAlertLogger();
}
}
/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code>
* methods.
*
* #param request servlet request
* #param response servlet response
* #throws ServletException if a servlet-specific error occurs
* #throws IOException if an I/O error occurs
*/
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
response.setContentType("text/plain");
String strScan = "";
try {
String asof = null;
scanType = request.getParameter("type");
scanType = scanType == null ? "" : scanType;
if(scanType.length() > 0){
if(scanType.equalsIgnoreCase("s")) {
stockData = null;
stockData = new StringBuffer(request.getParameter("scanData"));
stockData = stockData == null ? new StringBuffer("") : stockData;
} else {
foData = null;
foData = new StringBuffer(request.getParameter("scanData"));
foData = foData == null ? new StringBuffer("") : foData;
}
}
asof = request.getParameter("asof");
asof = asof == null ? "" : asof.trim();
// Date format without seconds
DateFormat formatWithoutSec = new SimpleDateFormat("yyyy/MM/dd HH:mm");
dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date tmp = new Date();
// format: yyyy/MM/dd HH:mm:ss
currDate = dateFormat.format(tmp);
//format: yyyy/MM/dd HH:mm
Date asofDate = formatWithoutSec.parse(asof);
Date cDate = formatWithoutSec.parse(currDate);
cDate.setSeconds(0);
System.out.println(asofDate.toString()+" || "+cDate.toString());
int isDataExpired = asofDate.toString().compareTo(cDate.toString());
if(isDataExpired > 0 || isDataExpired == 0) {
if(scanType != null && scanType.length() > 0) {
checkAndCreateDir();
strScan = scanType.equalsIgnoreCase("s") ? "Stock Data Recieved at "+currDate
: "FO Data Recieved at "+currDate;
//System.out.println(strScan);
} else {
strScan = "JSON of scan data not received properly at "+currDate;
//System.out.println("GSAS: received null or empty");
}
} else {
strScan = "GSAS: " + scanType + ": Received Expired Data of "+asofDate.toString()+" at "+cDate.toString();
System.out.println(strScan);
}
scanType = null;
} catch (Exception ex) {
strScan = "Mobile server issue for receiving scan data";
System.out.println("GSAS: Exception-1: "+ex);
logger.error("GetScanAlertServlet: processRequest(): Exception: "+ex.toString());
} finally {
logger.info("GetScanAlertServlet: "+strScan);
out.println(strScan);
}
}
private void checkAndCreateDir() {
try {
boolean isStock = false;
Date ddate = new Date();
currDate = dateFormat.format(ddate);
sum += ddate.getSeconds();
count++;
logger.info("Total Average Time: "+(sum/count));
if(scanType.equalsIgnoreCase("s")){ //For Stock
setStockData(stockData);
Date date1 = new Date();
currDate = dateFormat.format(date1);
s_sum += date1.getSeconds();
s_count++;
logger.info("Stock Average Time: "+(s_sum/s_count));
//file = new File(path + "\\" + stockFileName);
isStock = true;
} else if (scanType.equalsIgnoreCase("fo")) { //For FO
setFOData(foData);
Date date2 = new Date();
currDate = dateFormat.format(date2);
fo_sum += date2.getSeconds();
fo_count++;
logger.info("FO Average Time: "+(fo_sum/fo_count));
//file = new File(path + "\\" +foFileName);
isStock = false;
}
if(!dir.exists()) { // Directory not exists
if(dir.mkdir()) {
if(isStock)
checkAndCreateFile(stockFile);
else
checkAndCreateFile(foFile);
}
} else { // Directory already exists
if(isStock)
checkAndCreateFile(stockFile);
else
checkAndCreateFile(foFile);
}
} catch (Exception e) {
System.out.println("GSAS: Exception-2: "+e);
logger.error("GetScanAlertServlet: checkAndCreateDir(): Exception: "+e);
}
}
private void checkAndCreateFile(File file) {
try{
if(!file.exists()){ // File not exists
if(file.createNewFile()){
writeToFile(file);
}
} else { // File already exists
writeToFile(file);
}
} catch (Exception e) {
System.out.println("GSAS: Exception-3: "+e);
logger.error("GetScanAlertServlet: checkAndCreateFile(): Exception: "+e.toString());
}
}
private void writeToFile(File file) {
FileOutputStream fop = null;
try{
if(scanType.equalsIgnoreCase("s")){ //For Stock
data = getStockData();
} else if (scanType.equalsIgnoreCase("fo")) { //For FO
data = getFOData();
}
if(data != null && data.length() > 0 && file != null){
fop = new FileOutputStream(file);
byte[] contentBytes = data.toString().getBytes();
for(byte b : contentBytes){
fop.write(b);
}
//fop.write(contentBytes);
fop.flush();
} else {
System.out.println("GSAS: Data is null/empty string");
logger.info("GSAS: Data is null or empty string");
}
data = null;
} catch (Exception e) {
System.out.println("GSAS: Exception-4: "+e);
logger.info("GetScanAlertServlet: writeToFile(): Exception: "+e.toString());
} finally {
try {
if(fop != null)
fop.close();
} catch (IOException ex) {
java.util.logging.Logger.getLogger(GetScanAlertServlet.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
private String readFromFile(String fileName){
String fileContent = "";
try{
String temp = "";
File file = new File(fileName);
if(file.exists()){
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
while((temp = br.readLine()) != null)
{
fileContent += temp;
}
br.close();
} else {
System.out.println("GSAS: File not exists to read");
logger.info("GetScanAlertServlet: File not exists to read");
}
temp = null;
file = null;
} catch (Exception e) {
System.out.println("GSAS: Exception-5: "+e);
logger.error("GetScanAlertServlet: readFromFile(): Exception: "+e.toString());
}
return fileContent;
}
public StringBuffer getStockData() {
//String temp="";
//StringBuffer temp = (StringBuffer)scanDataSession.getAttribute("stock");
//if(temp != null && temp.length() > 0) {
// return temp;
//}
if(stockData != null && stockData.length() > 0){
return stockData;
} else {
stockData = null;
stockData = new StringBuffer(readFromFile(path + "\\"+ stockFileName));
return stockData;
}
}
public StringBuffer getFOData(){
//String temp="";
//StringBuffer temp = (StringBuffer)scanDataSession.getAttribute("fo");
//if(temp != null && temp.length() > 0) {
// return temp;
//}
if(foData != null && foData.length() > 0) {
return foData;
} else {
foData = null;
foData = new StringBuffer(readFromFile(path + "\\" + foFileName));
return foData;
}
}
}
I always get the following exception after every 2 hours when I restart my jboss server and as solution I've also increased Heap size but same problem still exists
ERROR [[GetScanAlertServlet]] Servlet.service() for servlet GetScan
AlertServlet threw exception
java.lang.OutOfMemoryError: Java heap space
at sun.nio.cs.StreamEncoder.write(Unknown Source)
at java.io.OutputStreamWriter.write(Unknown Source)
at java.io.Writer.write(Unknown Source)
at GetScanAlertServlet.writeToFile(GetScanAlertServlet.java:256)
at GetScanAlertServlet.checkAndCreateFile(GetScanAlertServlet.java:236)
at GetScanAlertServlet.checkAndCreateDir(GetScanAlertServlet.java:202)
at GetScanAlertServlet.processRequest(GetScanAlertServlet.java:135)
at GetScanAlertServlet.doPost(GetScanAlertServlet.java:377)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl
icationFilterChain.java:252)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF
ilterChain.java:173)
at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFi
lter.java:81)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl
icationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF
ilterChain.java:173)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperV
alve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextV
alve.java:178)
at org.jboss.web.tomcat.security.CustomPrincipalValve.invoke(CustomPrinc
ipalValve.java:39)
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(Securit
yAssociationValve.java:153)
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValv
e.java:59)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.j
ava:126)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.j
ava:105)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineVal
ve.java:107)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.jav
a:148)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java
:856)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.proce
ssConnection(Http11Protocol.java:744)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpo
int.java:527)
at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWor
kerThread.java:112)
at java.lang.Thread.run(Unknown Source)
Though I do not see the problem right away, your code does not properly handle resource allocation/release. The problems do not have to be caused by manipulating large JSON blob.
I just observed you do not free your resources (you open files, but do not close them in finally blocks -- any reason not to?), you would probably do better with StringBuilder for string manipulation or just use some kind of existing library (apache commons (io, string)) to do it for you.
Scheduled executor service should be properly shutted down (maybe use something your container provides: Jboss thread pool).
To start I had to rewrite most of the code. I know it's bad practice on SO to do that, We are here to teach and help. Not do other peoples work. But I could really stand reading the code and made it hard to follow.
Here are the bullet points of issues I found
No finally clauses, So your FileWriter, 'FileReader, andBufferedReader` were never closed if an exception occurred.
Not using static where it could, path and file names never changed. Also your DateFormat never changed so moved that to static
Not sure why you were setting strings to null when the next line was getting it from the request parameters and if it was null changed it to an empty string anyway.
Not sure why you were converting dates to strings to compare them. Dates are comparable.
anyway here is the code hope it helps
public class GetScanAlertServlet extends HttpServlet
{
private static final String PATH = "D:\\Mobile_scan_alerts";
private static final String STOCK_FILE_NAME = "stock.txt";
private static final String FO_FILE_NAME = "fo.txt";
private static final String EMPTY = "";
private static final DateFormat FORMAT_WITHOUT_SEC = new SimpleDateFormat("yyyy/MM/dd HH:mm");
// For average time of received data
private static float SUM = 0;
private static float S_SUM = 0;
private static float FO_SUM = 0;
private static float COUNT = 0;
private static float S_COUNT = 0;
private static float FO_COUNT = 0;
private static Logger LOGGER = null;
private String scanType;
private String stockData;
private String foData;
#Override
public void init()
{
LOGGER = MyLogger.getScanAlertLogger();
if (LOGGER == null)
{
MyLogger.createLog();
LOGGER = MyLogger.getScanAlertLogger();
}
}
/**
* Returns a short description of the servlet.
*
* #return a String containing servlet description
*/
#Override
public String getServletInfo()
{
return "Short description";
}
/**
* Handles the HTTP <code>GET</code> method.
*
* #param request servlet request
* #param response servlet response
* #throws ServletException if a servlet-specific error occurs
* #throws IOException if an I/O error occurs
*/
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
processRequest(request, response);
}
/**
* Handles the HTTP <code>POST</code> method.
*
* #param request servlet request
* #param response servlet response
* #throws ServletException if a servlet-specific error occurs
* #throws IOException if an I/O error occurs
*/
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
processRequest(request, response);
}
/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code>
* methods.
*
* #param request servlet request
* #param response servlet response
* #throws ServletException if a servlet-specific error occurs
* #throws IOException if an I/O error occurs
*/
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
PrintWriter out = response.getWriter();
response.setContentType("text/plain");
String strScan = EMPTY;
try
{
scanType = getRequestParameter(request, "type");
if (scanType.length() > 0)
{
if (scanType.equalsIgnoreCase("s"))
{
stockData = getRequestParameter(request, "scanData");
}
else
{
foData = getRequestParameter(request, "scanData");
}
}
//format: yyyy/MM/dd HH:mm
Date asofDate = FORMAT_WITHOUT_SEC.parse(getRequestParameter(request, "asof"));
Date currDate = new Date();
currDate.setSeconds(0);
System.out.println(asofDate.toString() + " || " + currDate.toString());
if (asofDate.compareTo(currDate) >= 0)
{
if (scanType != null && scanType.length() > 0)
{
checkAndCreateDir();
strScan =
scanType.equalsIgnoreCase("s") ? "Stock Data Recieved at " + currDate :
"FO Data Recieved at " + currDate;
}
else
{
strScan = "JSON of scan data not received properly at " + currDate;
}
}
else
{
strScan = "GSAS: " + scanType + ": Received Expired Data of " + asofDate.toString()
+ " at " + currDate.toString();
System.out.println(strScan);
}
}
catch (Exception ex)
{
strScan = "Mobile server issue for receiving scan data";
LOGGER.error("GetScanAlertServlet: processRequest(): Exception: " + ex.toString());
}
finally
{
LOGGER.info("GetScanAlertServlet: " + strScan);
out.println(strScan);
out.close();
}
}
private void checkAndCreateDir()
{
try
{
File dir = new File(PATH);
if (!dir.exists())
{
dir.mkdir();
}
File file = null;
SUM += new Date().getSeconds();
COUNT++;
LOGGER.info("Total Average Time: " + (SUM / COUNT));
if (scanType.equalsIgnoreCase("s"))
{ //For Stock
S_SUM += new Date().getSeconds();
S_COUNT++;
LOGGER.info("Stock Average Time: " + (S_SUM / S_COUNT));
file = new File(PATH + System.lineSeparator() + STOCK_FILE_NAME);
}
else if (scanType.equalsIgnoreCase("fo"))
{ //For FO
FO_SUM += new Date().getSeconds();
FO_COUNT++;
LOGGER.info("FO Average Time: " + (FO_SUM / FO_COUNT));
file = new File(PATH + System.lineSeparator() + FO_FILE_NAME);
}
checkAndCreateFile(file);
}
catch (Exception e)
{
//System.out.println("GSAS: Exception-2: "+e);
LOGGER.error("GetScanAlertServlet: checkAndCreateDir(): Exception: " + e.toString());
}
}
private void checkAndCreateFile(File file)
{
try
{
if(!file.exists())
{
file.createNewFile();
}
writeToFile(file);
}
catch (Exception e)
{
LOGGER.error("GetScanAlertServlet: checkAndCreateFile(): Exception: " + e.toString());
}
}
private void writeToFile(File file) throws IOException
{
String data = EMPTY;
if (scanType.equalsIgnoreCase("s"))
{ //For Stock
if (stockData == null)
{
stockData = readFromFile(PATH + System.lineSeparator() + STOCK_FILE_NAME);
}
data = stockData;
}
else if (scanType.equalsIgnoreCase("fo"))
{ //For FO
if (foData == null)
{
foData = readFromFile(PATH + System.lineSeparator() + FO_FILE_NAME);
}
data = foData;
}
FileWriter fileWriter = null;
try
{
if (data != null && data.length() > 0)
{
fileWriter = new FileWriter(file);
fileWriter.write(data.toString());
}
else
{
System.out.println("GSAS: Data is null/empty string");
LOGGER.info("GSAS: Data is null or empty string");
}
}
catch (Exception e)
{
LOGGER.info("GetScanAlertServlet: writeToFile(): Exception: " + e.toString());
}
finally
{
if (fileWriter != null)
{
fileWriter.flush();
fileWriter.close();
}
}
}
private String readFromFile(String fileName) throws IOException
{
String fileContent = EMPTY;
FileReader fr = null;
BufferedReader br = null;
try
{
File file = new File(fileName);
if (file.exists())
{
fr = new FileReader(file);
br = new BufferedReader(fr);
String temp;
while ((temp = br.readLine()) != null)
{
fileContent += temp;
}
}
else
{
System.out.println("GSAS: File not exists to read");
LOGGER.info("GetScanAlertServlet: File not exists to read");
}
}
catch (Exception e)
{
LOGGER.error("GetScanAlertServlet: readFromFile(): Exception: " + e.toString());
}
finally
{
if (fr != null)
{
fr.close();
}
if (br != null)
{
br.close();
}
}
return fileContent;
}
private String getRequestParameter(HttpServletRequest request, String parameter)
{
String str = request.getParameter(parameter);
return str == null ? EMPTY : str.trim();
}
}