error in grader test. Infinite recursion error - java

I am learning Spring MVC online. As part of my course, I have to develop a Cloud Video Service. Specifications are mentioned here.
https://github.com/juleswhite/mobile-cloud-asgn1
Below is my controller class.
#Controller
public class VideosController {
private final AtomicLong currentId = new AtomicLong(1L);
//A Map to hold incoming Video meta data
private HashMap<Long, Video> videoMap = new HashMap<Long, Video>();
//Receives GET requests to /video and returns the current list
// list of videos in memory
#RequestMapping(value = "/video", method = RequestMethod.GET)
public #ResponseBody List<Video> getVideoList() throws IOException{
List<Video> resultList = new ArrayList<Video>();
for(Long id : videoMap.keySet()) {
resultList.add(videoMap.get(id));
}
return resultList;
}
//Receives POST requests to /video and adds the video object
//created from request data to the Map
#RequestMapping(value = "/video", method = RequestMethod.POST)
public #ResponseBody() Video addVideoMetadata(#RequestBody Video data)
{
//create a Video object
Video video = Video.create().withContentType(data.getContentType())
.withDuration(data.getDuration())
.withSubject(data.getSubject())
.withTitle(data.getTitle()).build();
//set the id for the video
long videoId = currentId.incrementAndGet();
video.setId(videoId);
//set the URL for this Video
String videoURL = getDataUrl(videoId);
video.setDataUrl(videoURL);
//save the Video metadata object to map
Video v = save(video);
return v;
}
// Receives POST requests to /video/{id}/data e.g. /videoa/2/data
// uploads the video file sent as MultipartFile
// and writes it to the disc
#RequestMapping(value = "/video/{id}/data", method = RequestMethod.POST)
public #ResponseBody ResponseEntity<VideoStatus> uploadVideo
(#RequestParam("data") MultipartFile data,
#PathVariable("id") long id,
HttpServletResponse response
) throws IOException
{
// if video with id not present
if(!videoMap.containsKey(id)) {
System.out.println(" this id not present");
return new ResponseEntity<>(null, HttpStatus.NOT_FOUND);
//return new ResponseEntity<>(null, HttpStatus.NOT_FOUND);
}
InputStream in = null;
try {
//read the input stream
in = data.getInputStream();
}
catch(IOException ie){
System.out.println("Exception reading inputstream");
}
finally {
in.close();
}
//get the video
Video v = videoMap.get(id);
//write it to disk
VideoFileManager.get().saveVideoData(v, in);
VideoStatus vs = new VideoStatus(VideoStatus.VideoState.READY);
return new ResponseEntity<>(vs, HttpStatus.OK);
//response.setStatus(200);
//return new ResponseEntity<>(vs, HttpStatus.OK);
}
//Reads GET request to /vide/{id}/data and returns the video
//binary data as output stream
#RequestMapping(value = "/video/{id}/data", method = RequestMethod.GET)
public #ResponseBody ResponseEntity<OutputStream> getBinaryData(
#PathVariable("id") long videoId,
HttpServletResponse response) throws IOException {
//if id is incorrect
if(!videoMap.containsKey(videoId)) {
return new ResponseEntity<>(null, HttpStatus.NOT_FOUND);
}
//get the video from Map
Video outVideo = videoMap.get(videoId);
VideoFileManager vm = VideoFileManager.get();
//write the binary data to OutputStream
OutputStream os = response.getOutputStream();
vm.copyVideoData(outVideo, os);
return new ResponseEntity<>(os, HttpStatus.OK);
}
//save incoming video metadata to a Map
public Video save(Video v) {
checkAndSetId(v);
if(!videoMap.containsKey(v.getId())) {
videoMap.put(v.getId(), v);
}
return v;
}
//helper method to generate url for video
private String getDataUrl(long videoId){
String url = getUrlBaseForLocalServer() + "/video/" + videoId + "/data";
return url;
}
private String getUrlBaseForLocalServer() {
HttpServletRequest request =
((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String base =
"http://"+request.getServerName()
+ ((request.getServerPort() != 80) ? ":"+request.getServerPort() : "");
return base;
}
private void checkAndSetId(Video entity) {
if(entity.getId() == 0){
entity.setId(currentId.incrementAndGet());
}
}
}
Now, I pass all the tests in AutoGradingTest.java Unit code but not the testAddVideoData(). It gives a Socket Time out error, followed by Infinite recursion error, pointing to line number 159 in the AutoGradingTest.java
Logically, my code seems to be fine. Lot of other learners are facing problem with thirstiest case too but there is no help from the course instructors.
Can somebody please help me here? Thanks a lot.

Related

How to append input param to string output?

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

File upload from NodeJS to Java Spring framework

I need a simple File Upload (JavaScript code example) from NodeJS to Java Spring framework method as followed.
Any help (approach) would be very much appreciated !
Java Code in Spring framework:
#RequestMapping(value = "/upload", method = RequestMethod.POST)
public ResponseEntity<FileJobResultBase> upload(HttpServletRequest httpServletRequest
) throws IOException {
try {
String storageName = httpServletRequest.getHeader("storageName");
String path = httpServletRequest.getHeader("path");
String fileName = httpServletRequest.getHeader("fileName");
String fileType = httpServletRequest.getHeader("fileType");
String context = httpServletRequest.getHeader("context");
String organization = httpServletRequest.getHeader("organization");
byte[] bytes = IOUtils.toByteArray(httpServletRequest.getInputStream());
FileJobResultBase fileJobResultBase = fileManagerService.upload(bytes, storageName, path, fileName, fileType == null ? "unknown" : fileType,authorization,organization, context);
return new ResponseEntity<>(fileJobResultBase, HttpStatus.OK);
} catch (Exception e) {
return exceptionHandling( e);
}
}
Currently my NodeJS code (but it's no good)
module.exports = {
create : function(req, res) {
var file = Object.keys(req.body.file).map(function(value, index) { return [value]; });
var headerSignature = APISigningService.getHeaderSignature();
}

How to pass InputStream to REST service POST method

How to pass InputStream to createParcel() method using Java REST client? How to call POST request using POSTMAN?
#POST
#Consumes(MediaType.APPLICATION_XML)
#Produces(MediaType.TEXT_PLAIN)
public int createParcel(InputStream is) {
int awbNo = 0;
try {
ParcelInfo parcelInfo = null;
parcelInfo = buildParcelInfo(is);
awbNo = index.incrementAndGet();
parcelInfo.setAwbNo(awbNo);
parcelInfo.setStatus("new");
parcelDataMap.put(awbNo, parcelInfo);
} catch(Exception ex) {
logger.error("Getting some exception for creating parcel : "+ex.getMessage(), ex);
}
return awbNo;
}
#GET
#Produces(MediaType.APPLICATION_XML)
public StreamingOutput getParcelInfo(#QueryParam("awbNo") int awbNo) {
ParcelInfo parcelInfo = null;
String xml = null;
parcelInfo = parcelDataMap.get(awbNo);
if (parcelInfo != null) {
xml = convert(parcelInfo);
}
return new ParcelInfoWriter(xml);
}
Because you are not consuming structured data but rather a raw InputStream, you first remove the #Consumes annotation; so your resource method should be:
#POST
#Produces(MediaType.TEXT_PLAIN)
public int createParcel(InputStream is) {
int awbNo = 0;
try {
ParcelInfo parcelInfo = null;
parcelInfo = buildParcelInfo(is);
// the rest of your code here
}catch(Exception ex) {
// catch specific exception instead of `Exception`
}
return awbNo;
}
Now use Postman to call your resource. The content body of your request can be any conent (in my example it is XML but you can send anything you like). Look at the screenshot below how to set the request correctly:
Execuse me for the drawing :-)

Servlet Image Display

Maybe I do not understand the servlet lifecycle very well, but this is what i want:
I want to display a page generated by a servlet let's say servlet: paginaAmd.
On this page I want to display a list of images stored in folder on web server.
The address of url of the images is something like:
/img/80-80-1-1-1-1-1-1-1-1-1
where /img/* is my servlet for displaying images.
All works well if I want to display one image at a time in browser.
But when I want to put all the list at once, the images are not displayed correctly. Sometimes are not displayed at all, sometimes are displayed in wrong position (the position does not alter in time), and sometimes are displayed only some images.
I suspect that somehow not all the doGet() methods are catched.
Can someone give me some advice?
Here are the servlet code witch is implemented by the tutorial here: http://balusc.blogspot.fr/2007/04/imageservlet.html
#WebServlet(name = "ImgDisplay", urlPatterns = {"/img/*"})
public class ImgDisplay extends HttpServlet
{
private SessionFactory sessionfactory = new AnnotationConfiguration().configure().buildSessionFactory();
private Query query;
private String mesajEroare = "";
private HttpServletRequest _request;
private HttpServletResponse _response;
private int width = 0;
private int height = 0;
private int idImagine = 0;
private int format = 0;
private String titluArticol = "";
private String numeImagine = "";
private boolean imgValida = false;
private int DEFAULT_BUFFER_SIZE = 1024 * 100;
String fileUploadPath = "";
#Override
public void init() throws ServletException {
}
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
this._request = request;
this._response = response;
this.SetVariabile();
if(imgValida)
{
String nImagine = this.GetImageFromDisk();
this.DisplayImage(nImagine);
}
}
private void SetVariabile()
{
String reqUrl = _request.getRequestURL().toString();
String aUrl[] = reqUrl.split("/");
String urlImg = aUrl[aUrl.length - 1];
aUrl = urlImg.split("-");
try
{
this.width = Integer.parseInt(aUrl[0]);
this.height = Integer.parseInt(aUrl[1]);
this.idImagine = Integer.parseInt(aUrl[2]);
this.format = Integer.parseInt(aUrl[3]);
this.numeImagine = aUrl[aUrl.length - 1];
this.imgValida = true;
}
catch(Exception e)
{
this.imgValida = false;
}
}
private String GetImageFromDisk()
{
String nImagine;
//preiau imaginea
PaginiImagini pa = new PaginiImagini();
Session session;
try
{
session = sessionfactory.openSession();
session.beginTransaction();
query = session.getNamedQuery("PaginiImagini.findByImagineID");
query.setInteger("imagineID", this.idImagine);
pa = (PaginiImagini) query.uniqueResult();
session.getTransaction().commit();
session.close();
}
catch( Exception e )
{
this.mesajEroare = "Nu pot citi din baza de date!";
}
// citesc imagine de pe disk
ServletContext sctx = getServletContext();
this.fileUploadPath = sctx.getInitParameter("file-upload-path");
String pathImagine = this.fileUploadPath + "/" + Setari.pathImaginiMici;
if(this.width > Setari.wImagineMica || this.height > Setari.hImagineMica)
{
pathImagine = this.fileUploadPath + "/" + Setari.pathImaginiMari;
}
nImagine = pathImagine + "/" + pa.getNumeImaginePeDisc();
return nImagine;
}
private void DisplayImage(String imageToRead) throws FileNotFoundException, IOException
{
File image = new File(imageToRead);
String contentType = getServletContext().getMimeType(image.getName());
_response.setContentType(contentType);
_response.setHeader("Content-Length", String.valueOf(image.length()));
_response.setHeader("Content-Disposition", "inline; filename=\"" + image.getName() + "\"");
_response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
_response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
_response.setDateHeader("Expires", 0); // Proxies.
// Prepare streams.
BufferedInputStream input = null;
BufferedOutputStream output = null;
try
{
// Open streams.
input = new BufferedInputStream(new FileInputStream(image), DEFAULT_BUFFER_SIZE);
output = new BufferedOutputStream(_response.getOutputStream(), DEFAULT_BUFFER_SIZE);
// Write file contents to response.
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int length;
while ((length = input.read(buffer)) > 0)
{
output.write(buffer, 0, length);
}
}
finally
{
// Gently close streams.
close(output);
close(input);
}
}
/**
*
* #param resource
*/
private static void close(Closeable resource)
{
if (resource != null)
{
try
{
resource.close();
}
catch (IOException e)
{
// Do your thing with the exception. Print it, log it or mail
// it.
//e.printStackTrace();
}
}
}
}
You have serious concurrency issues in your servlet. A single instance of the servlet is used to serve all the requests to this servlet. So a servlet should be stateless. But the first thing you're doing is
this._request = request;
this._response = response;
This means that if two concurrent requests are made to the servlet, you might have the first one set these two instance variables, then the second one resetting the same instance variables. The first image would thus be sent as a response to the second request, and nothing would be sent as a response to the first request. And this is only one of the strange things that could happen. You could also have exceptions and inconsistent data.
Don't store the request and response (and any other state) in instance variables. Pass them from method to method. I've not analyzed the whole code, but the only instance field that you should have in the servlet is sessionFactory field.

Hide #ModelAttribute variables from appearing in URL? Spring MVC

I'm using Spring MVC 3 and I have the following Controller
#RequestMapping(value="FileUploadForm",method=RequestMethod.GET)
public String showForm(ModelMap model){
UploadForm form = new UploadForm();
model.addAttribute("FORM", form);
return "FileUploadForm";
}
#RequestMapping(value="FileUploadForm",method=RequestMethod.POST)
public ModelAndView processForm(#ModelAttribute(value="FORM") UploadForm form,BindingResult result){
if(!result.hasErrors()){
FileOutputStream outputStream = null;
String filePath = System.getProperty("java.io.tmpdir") + "/" + form.getFile().getOriginalFilename();
try {
outputStream = new FileOutputStream(new File(filePath));
outputStream.write(form.getFile().getFileItem().get());
outputStream.close();
System.out.println(form.getName());
return new ModelAndView(new RedirectView("success?Filepath="+filePath, true, true, false));
} catch (Exception e) {
System.out.println("Error while saving file");
return new ModelAndView("FileUploadForm");
}
}else{
return new ModelAndView("FileUploadForm");
}
}
This controller get the filepath and use to do a blast
#RequestMapping(value="success")
public String blasta(#ModelAttribute("Filepath") String filepath, Model model){
Blast sb = new Blast("somepath");
String[] blastIt = sb.blast("somepath", filepath);
String newLine = System.getProperty("line.separator");
ArrayList<Object> result = new ArrayList<>();
for (int i = 5; i < blastIt.length; i++) {
if(blastIt[i].startsWith("Lambda")){
break;
} else {
seila.add(blastIt[i]);
System.out.println(blastIt[i]);
}
model.addAttribute("RESULT", result);
}
File f1 = new File(filepath);
f1.delete();
return "success";
}
Everything works fine, but I still get the filepath in the url.
http://localhost:8081/Ambase/success?Filepath=filePath
And I want this way if it's possible
http://localhost:8081/Ambase/success
try adding this code to servlet-config.xml
<mvc:annotation-driven ignoreDefaultModelOnRedirect="true" />
To avoid this issue you should use RedirectAttributes. It will add the value of filePath to the redirect view params and you can get that in the controller blasta.
To achieve this you need to add one more parameter in the controller function processForm. At the end of all the parameters add RedirectAttributes attributes and then add following line just above the RedirectView statement.
attributes.addFlashAttribute("Filepath",filePath);
And then you can get this attribute in the ModelMap inside blasta controller function.
Hope this helps you. Cheers.

Categories

Resources