cancel
Showing results for 
Search instead for 
Did you mean: 
ajinkya93
Community Member

POST method in Java using Canvas REST API

Jump to solution

********************I have the following Perl code:

#!/usr/bin/perl
use strict;
use JSON::Parse 'parse_json';
my $auth = "xxx";
my $curl = "curl -H 'Authorization: Bearer $auth'";
system("$curl https://canvas.instructure.com/api/v1/courses/10300000000000133 -X PUT -d 'end_at=2017-05-28T04:00:00Z' ");
my $json = '["golden", "fleece"]';
my $perl = parse_json ($json);

********************The function of this code is to change the "end_at" date to 2017-05-28. The output is:

{"id":10300000000000133,"name":"DOV DEV","account_id":10300000000000001,"start_at":"2014-07-01T13:31:00Z","grading_standard_id":null,"is_public":true,"course_code":"DOV DEV","default_view":"feed","enrollment_term_id":10300000000000001,"end_at":"2016-05-28T04:00:00Z","public_syllabus":false,"storage_quota_mb":15000,"is_public_to_auth_users":false,"hide_final_grades":false,"apply_assignment_group_weights":false,"calendar":{"ics":"https://canvas.instructure.com/feeds/calendars/course_Jo1suCoQU3XhYMBJNm3Ziu2POTG4GL6DjzHJ7PM4.ics"},"sis_course_id":null,"integration_id":null,"enrollments":[{"type":"teacher","role":"TeacherEnrollment","role_id":822,"user_id":10300000000020171,"enrollment_state":"active"}],"workflow_state":"available","restrict_enrollments_to_course_dates":false}host-155-246-165-53:~ ajinkyabobade$ 

*********************I converted the Perl code to the following Java code:

package canvas;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;


public class changedate {
public static HttpURLConnection connection;

public static void main(String[] args) throws Exception {
  
String auth = fileReader("auth.dat");
  
// put the required courseID
  
String courseId = "10300000000000133";
  
String url1 = "https://canvas.instructure.com/api/v1/courses/10300000000000133/settings";
  URL url
= new URL(url1 + courseId + "/assignments/10300000000043867/");

  connection
= (HttpURLConnection) url.openConnection();  
  connection
.setDoOutput(true);
  connection
.setRequestProperty("Authorization", "Bearer " + auth);

  connection
.setRequestMethod("PUT");
  
// OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
  
// PrintWriter out = new PrintWriter(new OutputStreamWriter(connection.getOutputStream()));

String input = "{\n" +
" \"name\": DOV DEV,\n" +
" \"start_at\": \"2014-07-01T13:31:00Z\",\n" +
" \"grading_standard_id\": \"2013-08-28T23:59:00-06:00\",\n" +
" \"is_public\": \"true\",\n" +
" \"course_code\": \"DOV DEV\"\n"+
"}\n";
OutputStream os = connection.getOutputStream();
os
.write(input.getBytes());
os
.flush();
if (connection.getResponseCode() != HttpURLConnection.HTTP_CREATED) {
throw new RuntimeException("Failed : HTTP error code : "
  
+ connection.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader(
  
(connection.getInputStream())));

String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}

connection
.disconnect();

}
public static String fileReader(String fileName) throws IOException {
  
BufferedReader br = new BufferedReader(new FileReader(fileName));
  
try {
  
StringBuilder sb = new StringBuilder();
  
String line = br.readLine();

  
while (line != null) {
  sb
.append(line);
  line
= br.readLine();
  
}
  
return sb.toString();
  
} finally {
  br
.close();
  
}
}

}

*****************The purpose of the Java code is to use the Canvas REST API and POST end_date on canvas, but the code is giving error:500. How can I fix this?

Deactivated user​Deactivated user​ @scottdennis ​justjoe​@

1 Solution

Accepted Solutions
James
Navigator

ajinkya93​,

This question sounds like a programming class assignment -- find the error in the poorly written code.

I will address some of the issues that are wrong with your code and provide the evidence that makes me think this is a school assignment. But since I think it is a school assignment, I will not provide working code or links to the other places here in the Community where there is working code or other discussions that have happened around getting Java to work or making the create course API call work. That is, I'm not going to do your work for you.

One thing I learned as I learned PERL is that you try to avoid the system function in favor of PERL modules that can do the same thing. The system command is generally considered a security risk. The system function doesn't return the output to the program, so what you're seeing is output from the curl command that was executed by the system call. But then you have totally unrelated stuff at the end about parsing JSON, but you're not getting the output back from the system call to parse it, so it looks like you have quasi-related debugging code mixed in with the actual code, but it's definitely not germane to the question you're asking, which seems to be "how can I take this working PERL code and make it work in Java". Your PERL code is nothing more than a wrapper around the curl command, which is what is used in the Canvas API documentation for examples.

Your curl command doesn't work though. Get it working from the command line before you try to wrap it in PERL or another language.

However, neither the PERL nor the Java code works. The PUT command on the PERL side returns the course object after the PUT and the parameter you passed is one not recognized, so it returned the current object. If you look closely, the date returned does not match the one you tried to set it to. As I'll note later, you seem to be aware that it doesn't work, but you don't mention that here, you're just talking about porting the PERL to Java.

Then, your Java code isn't trying to accomplish the same thing that your PERL code was attempting to accomplish, despite you "converting" it to Java. In Java, your JSON string is misquoted; the grading standard id is given as a date, not as a grading standard id, which is an integer; the dates are old, the time zones don't match; and then there is the issue from the PERL code that you're using the wrong parameter names. Any one of those, except for the date issues, could lead to the 500 status code.

To address your parameter naming issue: Look at the API documentation for the calls that you are making. You will notice that the names of the parameter are not "name" or "end_at", those are keys within an array and the name of the array needs specified in the information you send.

I can't say anything else about the Java code since I don't drink Java, except that even though I don't speak Java, this is really inefficient Java -- the kind taught in an introductory programming class, but not the kind that someone who knows Java would use in a production script. This isn't even the kind of Java that I would learn if I was scouring the Internet or using Stack Overflow to find help on something. It sounds like a programming problem where you're given the directive to not use any external libraries, which might be appropriate if you are worried about licensing, minimal size, or creating an embedded system. The question sounds like those I've seen other places where the end of the term is coming up, there's a project due, the student doesn't understand, and so they reach out for help, saying "Here's what I've got, can someone help me?"

You asked the same question on Stack Overflow the same day you posted it here. On April 27, you posted your code on Stack Overflow about the PUT request using PERL​ - at least there you acknowledged that your end_at date wasn't getting changed. The person there provided a response about how to better do it using PERL, but doesn't know the Canvas API to realize that's where your real problem lies. You asked about using Java to put assignment due dates on April 23. Other questions you've posted seem very academic in nature -- like trying to multiply a 15715x203 matrix by a 203x16384 matrix using python.

What you're doing here is taking two problems from two separate programming languages and combining them into the same question. Neither one works and both seem highly academic in nature to demonstrate that you can use an API, but not typical tasks that need done. There is no context of why you're trying to do something, just a brief description of what it should do.

And finally, your branded.me page lists you as being a Masters Student in Computer Engineering with a passion in hardware design and embedded systems. Making Java calls to a Canvas API sounds very much like a course assignment rather than something you would have a personal interest in. And even if it was something you had a personal interest in, the things that you're trying to do would not be things that you would choose to do on your own.

We try to be extremely helpful here in the Canvas Community and will go out of our way to help someone who is struggling with a concept. However, this is about the Canvas Learning Management System and so almost everyone here is involved in education. We value learning, but you will be hard pressed in a group of educators to find anyone who will want to do someone's projects for them -- primarily because we value education and learning. Your best bet is to talk to your instructor or to do the research yourself. Canvas uses a REST API, it's well documented, and there is lots of information in general on using REST APIs with all of the modern languages out there. There is a lot of useful information on Stack Overflow and I regularly get directed there when Googling how to do something. I pull information from different sources, assimilate them together, sort the chaff from the wheat, try things, look some more, try it with something simpler, isolate where the problem is occurring, etc.

View solution in original post

10 Replies
chofer
Community Coach
Community Coach

Hello ajinkya93

Because of the highly technical nature of this question, I am going to share your question with the Canvas Developers​ group here in the Canvas Community in hopes that it will get additional exposure.  If you are not yet following that group, you may want to do so by clicking on the link that I provided and then clicking on the "Follow" button.  Hope this helps!

ajinkya93
Community Member

Thank you Chris ,can you please tell me where would I find my question that you shared on canvas developers  forum?

Hi ajinkya93​...

When you go to the Canvas Developers​ group, you can click on the "Content" tab at the top left corner of the group page, and you'll see it there, too.  It's not really creating a second instance of your question, nor is it changing the title or the body of your posting.  Rather, sharing your question to one or more groups essentially make your question available to those groups of people who might not check out the "Find Answers" area (where you initially posted the question) of the Canvas Community.  Hope this helps!

James
Navigator

ajinkya93​,

This question sounds like a programming class assignment -- find the error in the poorly written code.

I will address some of the issues that are wrong with your code and provide the evidence that makes me think this is a school assignment. But since I think it is a school assignment, I will not provide working code or links to the other places here in the Community where there is working code or other discussions that have happened around getting Java to work or making the create course API call work. That is, I'm not going to do your work for you.

One thing I learned as I learned PERL is that you try to avoid the system function in favor of PERL modules that can do the same thing. The system command is generally considered a security risk. The system function doesn't return the output to the program, so what you're seeing is output from the curl command that was executed by the system call. But then you have totally unrelated stuff at the end about parsing JSON, but you're not getting the output back from the system call to parse it, so it looks like you have quasi-related debugging code mixed in with the actual code, but it's definitely not germane to the question you're asking, which seems to be "how can I take this working PERL code and make it work in Java". Your PERL code is nothing more than a wrapper around the curl command, which is what is used in the Canvas API documentation for examples.

Your curl command doesn't work though. Get it working from the command line before you try to wrap it in PERL or another language.

However, neither the PERL nor the Java code works. The PUT command on the PERL side returns the course object after the PUT and the parameter you passed is one not recognized, so it returned the current object. If you look closely, the date returned does not match the one you tried to set it to. As I'll note later, you seem to be aware that it doesn't work, but you don't mention that here, you're just talking about porting the PERL to Java.

Then, your Java code isn't trying to accomplish the same thing that your PERL code was attempting to accomplish, despite you "converting" it to Java. In Java, your JSON string is misquoted; the grading standard id is given as a date, not as a grading standard id, which is an integer; the dates are old, the time zones don't match; and then there is the issue from the PERL code that you're using the wrong parameter names. Any one of those, except for the date issues, could lead to the 500 status code.

To address your parameter naming issue: Look at the API documentation for the calls that you are making. You will notice that the names of the parameter are not "name" or "end_at", those are keys within an array and the name of the array needs specified in the information you send.

I can't say anything else about the Java code since I don't drink Java, except that even though I don't speak Java, this is really inefficient Java -- the kind taught in an introductory programming class, but not the kind that someone who knows Java would use in a production script. This isn't even the kind of Java that I would learn if I was scouring the Internet or using Stack Overflow to find help on something. It sounds like a programming problem where you're given the directive to not use any external libraries, which might be appropriate if you are worried about licensing, minimal size, or creating an embedded system. The question sounds like those I've seen other places where the end of the term is coming up, there's a project due, the student doesn't understand, and so they reach out for help, saying "Here's what I've got, can someone help me?"

You asked the same question on Stack Overflow the same day you posted it here. On April 27, you posted your code on Stack Overflow about the PUT request using PERL​ - at least there you acknowledged that your end_at date wasn't getting changed. The person there provided a response about how to better do it using PERL, but doesn't know the Canvas API to realize that's where your real problem lies. You asked about using Java to put assignment due dates on April 23. Other questions you've posted seem very academic in nature -- like trying to multiply a 15715x203 matrix by a 203x16384 matrix using python.

What you're doing here is taking two problems from two separate programming languages and combining them into the same question. Neither one works and both seem highly academic in nature to demonstrate that you can use an API, but not typical tasks that need done. There is no context of why you're trying to do something, just a brief description of what it should do.

And finally, your branded.me page lists you as being a Masters Student in Computer Engineering with a passion in hardware design and embedded systems. Making Java calls to a Canvas API sounds very much like a course assignment rather than something you would have a personal interest in. And even if it was something you had a personal interest in, the things that you're trying to do would not be things that you would choose to do on your own.

We try to be extremely helpful here in the Canvas Community and will go out of our way to help someone who is struggling with a concept. However, this is about the Canvas Learning Management System and so almost everyone here is involved in education. We value learning, but you will be hard pressed in a group of educators to find anyone who will want to do someone's projects for them -- primarily because we value education and learning. Your best bet is to talk to your instructor or to do the research yourself. Canvas uses a REST API, it's well documented, and there is lots of information in general on using REST APIs with all of the modern languages out there. There is a lot of useful information on Stack Overflow and I regularly get directed there when Googling how to do something. I pull information from different sources, assimilate them together, sort the chaff from the wheat, try things, look some more, try it with something simpler, isolate where the problem is occurring, etc.

View solution in original post

abobade
Community Member

Thank you for your reply I appreciate it, in order to solve the above problem. I have decided to take baby steps so here's what I did: I created the following code which is used to both GET and POST on Apache Tomcat v7.0 server: The following code is from my github account url :POST method using Apache server · patilprasad/CanvasManipulation-java@4cf276f · GitHub

+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Servlet implementation class GETPOSTServelet
+ */
+@WebServlet("/getpost")
+public class GETPOSTServelet extends HttpServlet {
+ private static final long serialVersionUID = 1L;
/**
+  * @see HttpServlet#HttpServlet()
+  */
public GETPOSTServelet() {
super();
// TODO Auto-generated constructor stub
+ }
+
+ /**
+ * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
+ */
+/* protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+
+ PrintWriter printWriter=response.getWriter();
+ printWriter.println(" Welcome ");
+ String firstnme=request.getParameter("fname");
+ printWriter.print(firstnme);
+
+ }
+*/
+ /**
+ * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
+ */
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ PrintWriter printWriter=response.getWriter();
+ printWriter.println("  Welcome  ");
+ String firstnme=request.getParameter("fname");
+ printWriter.print(firstnme);
+ }
+
+}
abobade
Community Member

In the above  code I am using "fname" fname is taken from index.html.The code for index.html is

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>Insert title here</title>

</head>

<body>

<form name="myForm" method="post" action="GETPOSTservlet">

First Name:<input type="text" name="fname">

<input type="submit" value="Ok">

</form>

</body>

</html>

********************************

Using these two codes I am able to get and post on apache server. I want to extend this design to Canvas REST API, my efforts are as follows:

First using the following code I am able to connect java to canvas using my authentication token,The code is as follows :

********************************

package canvas;

 

  import java.io.*;

  import java.net.HttpURLConnection;

  import java.net.MalformedURLException;

  import java.net.URL;

  import java.util.Iterator;

  import org.json.simple.JSONArray;

  import org.json.simple.JSONObject;

  import org.json.simple.parser.ParseException;

  import org.json.simple.parser.JSONParser;

 

  public class project {

  public static HttpURLConnection connection;

  public static void main(String[] args) throws Exception {

  try {

  String auth = fileReader("auth.dat");

  // put the required courseID

  String courseId="10300000000000133";

  String url1= "https://canvas.instructure.com/api/v1/courses/";

  URL url = new URL(url1 + courseId+ "/assignments/10300000000045073");

  connection = (HttpURLConnection) url.openConnection();

  connection.setRequestProperty("Authorization", "Bearer " +auth);

  connection.setRequestMethod("GET");

      System.out.println("\nSending 'GET' request to URL : "  + url);

      System.out.println("Response code:"  + connection.getResponseCode());

      System.out.println("Response message:"  + connection.getResponseMessage());

     

      File file = new File("JSON1.txt");

      // creates the file

      file.createNewFile();

      // creates a FileWriter Object

      FileWriter writer = new FileWriter(file);

      // Writes the content to the file

   

          // Read the response:

          BufferedReader reader = new BufferedReader(new InputStreamReader(

          connection.getInputStream()));

          String line;

          StringBuffer response = new StringBuffer();

          while ((line = reader.readLine()) != null) {

              response.append(line);

          }

          reader.close();

          System.out.println(response.toString());

          writer.write(response.toString());

          writer.flush();

          writer.close();

  }

  catch (MalformedURLException e1) {

  e1.printStackTrace();

  } catch (IOException e2) {

  e2.printStackTrace();

  }

  jsonParser();

  }

 

  public static String fileReader(String fileName) throws IOException {

      BufferedReader br = new BufferedReader(new FileReader(fileName));

      try {

          StringBuilder sb = new StringBuilder();

          String line = br.readLine();

 

          while (line != null) {

              sb.append(line);

              line = br.readLine();

          }

          return sb.toString();

      } finally {

          br.close();

      }

  }

  public static void jsonParser() throws Exception{

      try{

      String jsonData = fileReader("JSON1.txt");

      JSONParser parser = new JSONParser();

      //System.out.println( "\n    id" "\t\t\t"  "dueAt"  "\t"  "assignmentName" "\n");

      // take each value from the json array separately

      JSONObject innerObj = (JSONObject)parser.parse(jsonData);

        

      // get a number from the JSON object

      long id = (long) innerObj.get("id");        

      // get a String from the JSON object

      String assignmentName = (String) innerObj.get("name");

      String dueAt = (String) innerObj.get("due_at");

      System.out.println( id +"\t" + dueAt + "\t" + assignmentName);

      }catch(ParseException ex){

      ex.printStackTrace();       

      }catch (IOException e2) {

      e2.printStackTrace();

  }

  }

  }

***************************************

I am getting the output after parsing , the output I am getting is as follows:

****************************************

Sending 'GET' request to URL : https://canvas.instructure.com/api/v1/courses/10300000000000133/assignments/10300000000045073

Response code:200

Response message:OK

{"id":10300000000045073,"description":"\u003Cp\u003EJust send a java \"HelloWorld\" code.\u003C/p\u003E","due_at":"2016-07-01T03:59:59Z","unlock_at":"2016-04-27T04:00:00Z","lock_at":"2016-07-29T03:59:00Z","points_possible":100,"grading_type":"points","assignment_group_id":10300000000000297,"grading_standard_id":null,"created_at":"2016-04-27T22:25:45Z","updated_at":"2016-05-03T02:05:27Z","peer_reviews":false,"automatic_peer_reviews":false,"position":14,"grade_group_students_individually":false,"anonymous_peer_reviews":false,"group_category_id":null,"post_to_sis":null,"moderated_grading":false,"course_id":10300000000000133,"name":"JavaTestAssignment","submission_types":["online_upload"],"has_submitted_submissions":true,"muted":false,"html_url":"https://canvas.instructure.com/courses/10300000000000133/assignments/1030~45073","has_overrides":false,"needs_grading_count":1,"integration_id":null,"integration_data":{},"allowed_extensions":["java"],"published":true,"unpublishable":false,"only_visible_to_overrides":false,"locked_for_user":false,"submissions_download_url":"https://canvas.instructure.com/courses/1030~133/assignments/1030~45073/submissions?zip=1"}

10300000000045073 2016-07-01T03:59:59Z JavaTestAssignment

*******************************

My objective in this task is to GET the date and POST the new date using POST(please correct me if I should use PUT instead of POST) my efforts in doing so are as follows:

After going through the API Documentation I rearranged my data in the format required i.e I did the following:

String input = "{\n" +

" \"due_at\": 2016-07-01T03:59:59Z,\n" +

"  \"unlock_at\": \"2016-04-27T04:00:00Z\",\n" +

"  \"lock_at\": \"2016-07-29T03:59:00Z\",\n" +

"  \"points_possible\": \"100\",\n" +

"  \"created_at\": \"2016-04-27T22:25:45Z\"\n"+

"}\n";

******************************

I want to post this string and change the due_at part, in order to do so I did the following code

*******************************

package canvas;

import java.io.*;

import java.net.HttpURLConnection;

import java.net.MalformedURLException;

import java.net.URL;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.UnsupportedEncodingException;

import java.nio.charset.Charset;

public class changedate {

  public static HttpURLConnection connection;

  public static void main(String[] args) throws Exception {

  String auth = fileReader("auth.dat");

  // put the required courseID

  String courseId = "10300000000000133";

  String url1 = "https://canvas.instructure.com/api/v1/courses/";

  URL url = new URL(url1 + courseId + "/assignments/10300000000043867/");

  connection = (HttpURLConnection) url.openConnection();

  connection.setDoOutput(true);

  connection.setRequestProperty("Authorization", "Bearer " + auth);

  connection.setRequestMethod("POST");

  // OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());

  // PrintWriter out = new PrintWriter(new OutputStreamWriter(connection.getOutputStream()));

  String input = "{\n" +

  " \"due_at\": 2016-07-01T03:59:59Z,\n" +

  "  \"unlock_at\": \"2016-04-27T04:00:00Z\",\n" +

  "  \"lock_at\": \"2016-07-29T03:59:00Z\",\n" +

  "  \"points_possible\": \"100\",\n" +

  "  \"created_at\": \"2016-04-27T22:25:45Z\"\n"+

  "}\n";

OutputStream os = connection.getOutputStream();

os.write(input.getBytes());

os.flush();

/*

if (connection.getResponseCode() != HttpURLConnection.HTTP_CREATED) {

    throw new RuntimeException("Failed : HTTP error code : "

        + connection.getResponseCode());

    } */

BufferedReader br = new BufferedReader(new InputStreamReader(

        (connection.getInputStream())));

String output;

System.out.println("Output from Server .... \n");

while ((output = br.readLine()) != null) {

    System.out.println(output);

}

}

  public static String fileReader(String fileName) throws IOException {

  BufferedReader br = new BufferedReader(new FileReader(fileName));

  try {

  StringBuilder sb = new StringBuilder();

  String line = br.readLine();

  while (line != null) {

  sb.append(line);

  line = br.readLine();

  }

  return sb.toString();

  } finally {

  br.close();

  }

  }

}

************************************

I understood till opening the HTTP URL connection and representing the string as given in API format but I need help to understand what is the exact error in Post code so that I can read any documentation and correct it. Thank you 

A status code of 500 is an internal server error. In the Canvas API, it frequently happens when you pass input that can't be understood or isn't correct in some way (wrong format or possibly an id that doesn't exist).

You are trying to send a JSON encoded message to a POST, but you're not telling the server that it is coming in JSON format. See the first page of the API documentation for a note about setting your content-type.

Your JSON string is malformed as well. You may want to try pasting the desired string into an online JSON decoder. I use Json Parser Online  and it will highlight where the errors are in black. Until now, I've always used it to take output from Canvas and make it human readable (it adds spacing and indentation), but you can also use it to verify what you're trying to send.

abobade
Community Member

Thank you, I have a question I apologise if this Question sounds too basic but I am trying to learn

my question is as directed by you I went on Canvas LMS REST API Documentation  Under  Schema category there is following : "There is currently no way to upload a file as part of a JSON POST, the multipart form type must be used." .It mentions I cannot upload file using Jason post, does it mean I cannot use Post to change the due_at date? Furthur it specifies to use multipart form type. Would you please elaborate on this comment. I highly appreciate your reply

Re-read it, paying close attention to the part I mentioned about setting the content type.

You're getting sidetracked by things that aren't relevant because you're not trying to upload a file.