Still super new to REST, but close to finishing my first program.
I am attempting to create a CSV with the value of the POST URL Parameter being passed into it each time I POST.
Is there a way of setting my variable to be equal to my POST URL Parameter?
Code below (value is temporarily set to 10 while I figure this out):
#Path("/values")
public class values {
int totalSum = 0;
List<String> list = new ArrayList<String>();
#GET
#Produces(MediaType.TEXT_PLAIN)
public int getSum() throws IOException {
CSVReader reader = new CSVReader(new FileReader("yourfile.csv"));
List<String[]> read = reader.readAll();
return sum.sum(read, totalSum);
}
#POST
public String addValue() throws IOException {
int value = 10;
String valueString = Integer.toString(value);
CSVWriter writer = new CSVWriter(new FileWriter("yourfile.csv", true), ',');
String[] entries = valueString.split(",");
writer.writeNext(entries);
writer.close();
return "ok";
}
#DELETE
#Produces(MediaType.TEXT_PLAIN)
public String deleteList() throws IOException {
FileWriter fw = new FileWriter("yourfile.csv", false);
PrintWriter pw = new PrintWriter(fw, false);
pw.flush();
pw.close();
fw.close();
return "ok";
}
}
So now you need the base url, and when you add /{some_value} it gets mapped via PathVariable to String value test
Like so?
#Path("/{test}")
#POST
// Javax.ws.rs.PathParam
public String addValue(#PathParam("test") final String test) throws
// SpringFramework
//public String addValue(#PathVariable("test") final String test) throws IOException {
final String value = test;
CSVWriter writer = new CSVWriter(new FileWriter(value, true), ',');
String[] entries = valueString.split(",");
writer.writeNext(entries);
writer.close();
return "ok";
}
See link for more information
Related
I have an 3 array of strings ( actually it's an ArrayList ) and I would like to create an InputStream from it, each element of the array being a line in the stream.
String[] business = ['CONSUMER', 'TELUS'];
String[] position = ['Business', 'SMB','THPS'];
String isDone = "Yes";
need to convert the above data into and pass it to InputStream so i can upload the data to ftp server
Business_Unit: 'TELUS', 'CONSUMER'
Position_Group: 'Business', 'SMB', 'THPS'
On-Cycle_Schedule: 'Yes' or 'No
ftp server method as follows
private boolean fileUpload(InputStream isUploadFile, String dirName, String fileName){
boolean storeRetVal = false;
//File submission method
return storeRetVal;
}
the above method gets called from action class
public ActionForward generatePayroll(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
SessionInfoForm _form = (SessionInfoForm) form;
String isDone = "Yes";
String[] business = request.getParameterValues("selectedBusinessValues");
String[] position = request.getParameterValues("selectedPositionValues");
String fileName = "result.csv";
InputStream isUploadFile;
fileUpload(isUploadFile, fileName);
return mapping.findForward("success");
}
You can do something like
String[] business = { "CONSUMER", "TELUS" };
StringWriter sw = new StringWriter();
PrintWriter out = new PrintWriter(sw);
for (String s : business) {
out.println(s);
}
InputStream in = new ByteArrayInputStream(sw.toString().getBytes());
suppose i want to read 1st line in one method and 2nd line in another method , then how to read? how to access file globally?
class File{
private static void createFogDevices(int userId, String appId) throws Exception{
File file = new File("/home/madhu/Desktop/data.txt");
BufferedReader reader = null;
reader = new BufferedReader(new FileReader(file));
FogDevice cloud = createFogDevice(reader.readLine());
}
private static void addMobile(int userId, String appId) throws Exception{
FogDevice mobile = createFogDevice(reader.readLine());
}
}
please help,i am getting error in reader.readLine() in addMobile method.
First of all you can pass additional parameters path, and line number.
If you use java 8. Please see the following example for small files:
private static void addMobile(int userId, String appId, String path, int lineNumb) throws Exception{
String mobile =Files.readAllLines(Paths.get(path)).get(lineNumb);
}
If you use java 7. Please see the following example:
private static void addMobile(int userId, String appId, String path, int lineNumb) throws Exception{
String infoString;
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
for (int i = 0; i < lineNumb; i++) {
br.readLine();
}
infoString = br.readLine();
}
}
If you would like to make BufferedReader and File as global variables you can use the following example:
public class File {
private static java.io.File file;
private static BufferedReader reader;
static {
try {
file = new java.io.File("/home/madhu/Desktop/data.txt");
reader = new BufferedReader(new FileReader(String.valueOf(file)));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
private static void createFogDevices(int userId, String appId) throws Exception {
FogDevice cloud = createFogDevice(reader.readLine());
}
private static void addMobile(int userId, String appId) throws Exception {
FogDevice mobile = createFogDevice(reader.readLine());
}
}
If you want to read from 6 to 8 lines you can use the following code:
String line;
try (Stream<String> lines = Files.lines(Paths.get("G:\\B\\1.txt"))) {
line = lines.skip(6).limit(8).collect(Collectors.joining());
}
I have a method which takes the string as input, filters for specific key and value, returns the value as String output. I have a requirement to append input param to output string. The input is array int id. Here is the method code snippet:
private static String headerstomap(String headers) {
String sHeaders = headers.replace("[", "");
sHeaders = sHeaders.replace("]", "");
String res = Arrays.stream(sHeaders.split(", "))
.filter(s->s.contains("Uniquename"))
.findFirst()
.map(name->name.split(":")[1])
.orElse("Not Present");
return res;
}
Input is: [DomainValue:MYSQL,Oracle,SAP, Uniquename:jvmErrors_v1]
There is a rest API which takes the input param, gets the relevant data. Calls the above method to create a filename. The REST resource is:
public void downloadRecords(#PathVariable Long[] ids, HttpServletResponse response) throws Exception {
I need the method to return: jvmErrors_v1_1
Essentially, add an underscore at the end and append the input param.
Here is the REST resource:
public void downloadRecords(#PathVariable Long[] ids, HttpServletResponse response) throws Exception {
List<IDZip> iDZip = messageRepository.findbyId(ids);
IDZip iDZip = iDZip.get(0);
String xml = new ObjectMapper().writeValueAsString(iDZip);
String fileName = "id.zip";
String xmlname = messageController.headerstomap(iDZip.getheaders());
byte[] data = xml.getBytes();
byte[] bytes;
try (ByteOutputStream bout = new ByteOutputStream(); ZipOutputStream zout = new ZipOutputStream(bout)) {
for (Long id : ids) {
zout.setLevel(1);
ZipEntry ze = new ZipEntry(xmlname);
ze.setSize(data.length);
ze.setTime(System.currentTimeMillis());
zout.putNextEntry(ze);
zout.write(data);
zout.closeEntry();
}
bytes = bout.getBytes();
}
response.setContentType("application/zip");
response.setContentLength(bytes.length);
response.setHeader("Content-Disposition", "attachment; " + String.format("filename=" + fileName));
ServletOutputStream outputStream = response.getOutputStream();
FileCopyUtils.copy(bytes, outputStream);
outputStream.close();
}
There is IDZip class which holds getters and setters...
public String getheaders() {
return headers;
}
public void setheaders(String headers) {
this.headers = headers;
}
I will give you a gift today only if you will accept it, first debugs the process into small section system.out.println("step 1"); in each of the line then i will take it from that point
I want to fetch header from csv file . If I am not use this skipLines then I will get header at 0 index array . But I want to fetch header directly using HeaderColumnNameMappingStrategy but it will not work with my code.
I also want to validate header column list ( like csv had not allowed to contain extra column)
I had also check this How to validate the csv headers using opencsv but it was not helpful to me.
#SuppressWarnings({ "unchecked", "rawtypes" })
public Map<String, Object> handleStockFileUpload(MultipartFile file, Long customerId) {
Map<String, Object> responseMap = new HashMap<>();
responseMap.put("datamap", "");
responseMap.put("errormap", "");
responseMap.put("errorkeys", "");
List<Map<String, Integer>> list = new ArrayList<>();
List<StockCsvDTO> csvStockList = new ArrayList<>();
try {
String fileName = new SimpleDateFormat("yyyy_MM_dd_HHmmss").format(new Date()) + "_" + file.getOriginalFilename();
responseMap.put("filename", fileName);
File stockFile = new File(productsUploadFilePath + fileName);
stockFile.getParentFile().mkdirs();
FileOutputStream fos = new FileOutputStream(stockFile);
fos.write(file.getBytes());
fos.close();
CsvTransfer csvTransfer = new CsvTransfer();
ColumnPositionMappingStrategy ms = new ColumnPositionMappingStrategy();
ms.setType(StockCsv.class);
Reader reader = Files.newBufferedReader(Paths.get(productsUploadFilePath + fileName));
CSVReader csvReader = new CSVReader(reader);
CsvToBean cb = new CsvToBeanBuilder(reader)
.withType(StockCsv.class)
.withMappingStrategy(ms)
.withSkipLines(1)
.build();
csvTransfer.setCsvList(cb.parse());
reader.close();
csvStockList = csvTransfer.getCsvList();
} catch (Exception e) {
e.printStackTrace();
responseMap.put("status", "servererror");
}
responseMap.put("datamap", csvStockList);
return responseMap;
}
I found the following solution:
Use #CsvBindByName with HeaderColumnNameMappingStrategy,e.g. annotate your bean properties with #CsvBindByName:
public static class HollywoodActor {
private int id;
#CsvBindByName(column = "First Name")
private String firstName;
#CsvBindByName(column = "Last Name")
private String lastName;
// getter / setter
}
Add a method like this:
public class CsvParser {
public <T> ParseResult<T> parseByPropertyNames(Reader csvReader, Class<T> beanClass) throws IOException {
CSVReader reader = new CSVReaderBuilder(csvReader).withCSVParser(new
CSVParserBuilder().build()).build();
CsvToBean<T> bean = new CsvToBean();
HeaderColumnNameMappingStrategy<T> mappingStrategy = new HeaderColumnNameMappingStrategy();
mappingStrategy.setType(beanClass);
bean.setMappingStrategy(mappingStrategy);
bean.setCsvReader(reader);
List<T> beans = bean.parse();
return new CsvParseResult<>(mappingStrategy.generateHeader(), beans);
}
and also don't forget to add public class ParseResult
public class ParseResult <T> {
private final String[] headers;
private final List<T> lines;
// all-args constructor & getters
}
Use then use them in your code:
String csv = "Id,First Name,Last Name\n" + "1, \"Johnny\", \"Depp\"\n" + "2, \"Al\", \"Pacino\"";
CsvParseResult<HollywoodActor> parseResult = parser
.parseByPropertyNames(new InputStreamReader(new ByteArrayInputStream(csv.getBytes(StandardCharsets.UTF_8), HollywoodActor.class)));
From ParseResult.headers you can get actual headers from which were in your .csv file. Just compare them with what's expected.
Hope that helps!
Here I was comparing my csvHeader with originalHeader:
List<String> originalHeader = fileUploadUtility.getHeader(new StockCsv());
List<String> invalidHeader = csvHeader.stream().filter(o -> (originalHeader.stream().filter(f -> f.equalsIgnoreCase(o)).count()) < 1).collect(Collectors.toList());
if(null != invalidHeader && invalidHeader.size() > 0 && invalidHeader.toString().replaceAll("\\[\\]", "").length() > 0) {
msg = "Invalid column(s) : " + invalidHeader.toString().replace(", ]", "]") + ". Please remove invalid column(s) from file.";
resultMap.put(1, msg);
}
public List<String> getHeader(T pojo) {
// TODO Auto-generated method stub
final CustomMappingStrategy<T> mappingStrategy = new CustomMappingStrategy<>();
mappingStrategy.setType((Class<? extends T>) pojo.getClass());
String header[] = mappingStrategy.generateHeader();
List<String> strHeader = Arrays.asList(header);
return strHeader;
}
Here is an alternative to your present problem.First, define what you expect your headers to look like. For example:
public static final ArrayList<String> fileFormat = new ArrayList<> (Arrays.asList("Values1", "Values2", "Values3", "Values4"));
Now, write a method to return custom errors if any exist:
public String validateCsvFileDetails(MultipartFile file, Set<String> requiredHeadersArray) {
Set<String> errors = new HashSet<>();
try {
InputStream stream = file.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
String headerLine = reader.readLine();
if (Objects.isNull(headerLine))
return "The file has no headers, please ensure it has the correct upload format";
List<String> headersInFileList;
String[] headersInFileArray;
if (headerLine.contains(",")) {
headersInFileArray = StringUtils.split(headerLine, ",");
headersInFileList = Arrays.asList(headersInFileArray);
} else//the headerline has only one headerfield
{
headersInFileList = Collections.singletonList(headerLine);
}
for (String header : requiredHeadersArray) {
if (!headersInFileList.contains(header))
errors.add("The file has the wrong header format, please ensure " + header + " header is present");
}
//if there are errors, return it
if (!errors.isEmpty())
return sysUtils.getStringFromSet(errors);
//Ensure the csv file actually has values after the header, but don't read beyond the first line
String line;
int counter = 0;
while ((line = reader.readLine()) != null) {
counter++;
if (counter > 0)
break;
}
//if line is null return validation error
if (Objects.isNull(line))
return "Cannot upload empty file";
} catch (Exception e) {
logger.error(new Object() {
}.getClass().getEnclosingMethod().getName(), e);
return "System Error";
}
return null;
}
Now you can validate you file headers as follows:
String errors = validateCsvFileDetails(file, new HashSet<>(fileFormat));
if (errors != null)
return error
//proceed
Give this a try using captureHeader as a pre-filter:
...
private class CustomHeaderColumnNameMappingStrategy<T> extends HeaderColumnNameMappingStrategy {
private String[] expectedHeadersOrdered = {"Column1", "Column2", "Column3", "Column4", "Column5"};
#Override
public void captureHeader(CSVReader reader) throws IOException, CsvRequiredFieldEmptyException {
String[] actualCsvHeaders = reader.peek();
String actualHeader, expectedHeader;
if (expectedHeadersOrdered.length > actualCsvHeaders.length) {
throw new CsvRequiredFieldEmptyException("Missing header column.");
} else if (expectedHeadersOrdered.length < actualCsvHeaders.length) {
throw new IOException("Unexpected extra header column.");
}
// Enforce strict column ordering with index
// TODO: you might want to employ simple hashMap, List, set, etc. as needed
for (int i=0; i<actualCsvHeaders.length; i++) {
actualHeader = actualCsvHeaders[i];
expectedHeader = expectedHeadersOrdered[i];
if ( ! expectedHeader.equals(actualHeader) ) {
throw new IOException("Header columns mismatch in ordering.");
}
}
super.captureHeader(reader); // Back to default processing if the headers include ordering are as expected
}
}
CustomHeaderColumnNameMappingStrategy yourMappingStrategy = new CustomHeaderColumnNameMappingStrategy<YourPOJO>();
ourMappingStrategy.setType(YourPOJO.class);
try {
pojosFromCsv = new CsvToBeanBuilder<YourPOJO>(new FileReader(csvFile))
.withType(YourPOJO.class)
.withMappingStrategy(yourMappingStrategy)
.build();
pojosFromCsv.stream();
}
Inspired by Using captureHeader in OpenCSV
I have a problem with reading specific object from a file and saving it into ArrayList.
First I write a single customer using writeCustomer(). Then I write all records from List customerList and save them to the file. This works great.
Then I want to read the saved file so I read one line using readCustomer(). This method returns one Customer and then I want to return a list with all Clients using readData() and read it, I have nullPointerException in line list.add(readCustomer(bufferedReader));
My Class Customer has one constructor and is has an override method toString().
public class SaveCustomers {
public static void main(String[] args) throws IOException {
List<Customers> customersList = new ArrayList<>();
customersList.add(new Customers("ABC", 10));
customersList.add(new Customers("SGS", 20));
customersList.add(new Customers("FSD", 30));
try (PrintWriter out = new PrintWriter("customer.txt", "UTF-8"))
{ writeData(customersList, out); }
BufferedReader bufferedReader = new BufferedReader(new FileReader("customer.txt"));
List<Customers> newList = readData(bufferedReader);
for(Customers c: newList){
System.out.println(c);
}
}
private static void writeCustomer(PrintWriter out, Customers customers){
out.println(customers.getName()+"|"+customers.getTarrif());
}
private static void writeData(List<Customers> customersList, PrintWriter out){
for(Customers c:customersList){
writeCustomer(out, c);
}
}
public static Customers readCustomer(BufferedReader bufferedReader) throws IOException {
String line = bufferedReader.readLine();
String [] tokens = line.split("\\|");
String name = tokens[0];
int time = Integer.valueOf(tokens[1]);
return new Customers(name, time);
}
public static List<Customers> readData(BufferedReader bufferedReader) throws IOException {
List<Customers> list = new ArrayList<>();
while (bufferedReader.readLine() != null) {
list.add(readCustomer(bufferedReader));
}
return list;
}}
You are close to the solution ;)
In method :
readData(BufferedReader bufferedReader)
Just change this line
for(Customers l : list) {
to this one :
while (bufferedReader.ready()) {