[JAVA] What I was addicted to with the Redmine REST API


This year I had the opportunity to do the following with the Redmine REST API:


I've never used the Redmine REST API before, and I learned while implementing it. I would like you to share what you were addicted to and avoid the traps that I was addicted to.



Redmine Version

  Redmine version                3.4.6.stable

java Version

java version "1.8.0_221"
Java(TM) SE Runtime Environment (build 1.8.0_221-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.221-b11, mixed mode)



I was addicted to

1. API functions are also limited to the privileges granted to the user

First generate the RedmineManager class to use the Redmine REST API. At this time, we use something called ʻAPI KEY`.

RedmineManager manager = RedmineManagerFactory.createWithApiKey(REDMINE_URL, API_KEY);

This ʻAPI KEY` is given to each Redmine user. At that time, my user privileges were not administrator privileges. Some API methods require Redmine system administrator privileges.

Get all users

     * Load list of users from the server.
     * <p><strong>This operation requires "Redmine Administrator" permission.</strong>
     * <p>
     * This method calls Redmine with "include = memberships,groups" parameter.
     * @return list of User objects
     * @throws RedmineAuthenticationException invalid or no API access key is used with the server, which
     *                                 requires authorization. Check the constructor arguments.
     * @throws NotFoundException
     * @throws RedmineException
    public List<User> getUsers() throws RedmineException {
        return transport.getObjectsList(User.class, new BasicNameValuePair(
                "include", "memberships,groups"));

If you want to use it flexibly, we recommend that you have system administrator privileges.

2. Requires Transport

It seems to be a concept taken from version 4 or later of redmine-java-api. You can get it from the RedmineManager class.

RedmineManager redmineManager = RedmineManagerFactory.createWithApiKey(REDMINE_URL, API_KEY);
Transport transport = redmineManager.getTransport();

Without Transport, the exception" Transport is not set! "Is thrown when creating / updating tickets. So please set Transport to the instance of ʻIssue` before creating / updating.

Create new ticket

//Set Transport
Issue issue = new Issue(manager.getTransport());
issue = issue.create();

Update existing ticket

Issue issue = manager.getIssueManager().getIssueById(fetchedIssue.getTicketId());
//Set Transport

3. How to use Params

When updating an existing ticket, you may want to get a "ticket that meets these conditions". In that case, "this condition" can be expressed by using Params.

The title of the ticket is"actual.getFileName"Condition that matches

Params().add("set_filter", "1")
        .add("f[]", "subject")
        .add("op[subject]", "=")
        .add("v[subject][]", actual.getFileName());

I was addicted to the following three points.

What is the key value when it is not the title (example: person in charge)?

I couldn't find the document, so I used brute force to identify it. If you set the desired conditions in the ticket list filter, the filter conditions will be displayed as URL parameters. You can determine the value of the key by decoding the parameters. flow.png

What if it does not match (eg, does not match, includes)?

Analyze by the above method.

I want to get all the tickets, so if I get them without any conditions, I can only get 500 tickets

The current situation is unknown. If anyone knows how to do this, please let me know.

4. Clear once when updating custom fields of existing tickets

Get the custom field of the existing ticket once and update the value. After that, I had to clearCustomFields and then add the custom fields of the existing ticket to update it successfully.

//This process gets the custom field from the existing ticket, updates it, and returns it.
Collection<CustomField> customFieldCollection = setEachCustomField(issue, fetchedIssue);

5. Format when setting values for custom date fields

yyyy-MM-dd is an option. Otherwise, you will get a parse error.

Above (I will add it when I come up with it.)


Recommended Posts

What I was addicted to with the Redmine REST API
Memorandum: What I was addicted to when I hit the accounting freee API
What I was addicted to when introducing the JNI library
I was addicted to the roll method
I was addicted to the Spring-Batch test
What I was addicted to when implementing google authentication with rails
I was addicted to the API version min23 setting of registerTorchCallback
I was addicted to doing onActivityResult () with DialogFragment
A story I was addicted to when testing the API using MockMVC
Problems I was addicted to when building the digdag environment with docker
I was addicted to unit testing with the buffer operator in RxJava
I was addicted to the NoSuchMethodError in Cloud Endpoints
I was addicted to the record of the associated model
I was addicted to starting sbt
What I was addicted to when developing a Spring Boot application with VS Code
What I fixed when updating to Spring Boot 1.5.12 ・ What I was addicted to
What I was addicted to while using rspec on rails
I was addicted to setting default_url_options with Rails devise introduction
I was addicted to looping the Update statement on MyBatis
I was addicted to the setting of laradock + VSCode + xdebug
I was addicted to using Java's Stream API in Scala
What I was addicted to when trying to properly openAPI/Swagger documentation with Rails + Grape + Grape Swagger
The story I was addicted to when setting up STS
I tried to summarize what was asked at the site-java edition-
About the matter that I was addicted to how to use hashmap
I was addicted to rewriting to @SpringApplicationConfiguration-> @SpringBootTest
I tried to summarize the Stream API
Technical causes and countermeasures for the points I was addicted to with the first Android app & Kotlin
What I was addicted to when updating the PHP version of the development environment (Docker) from 7.2.11 to 7.4.x
[Rails] I was addicted to the nginx settings when using Action Cable.
Recorded because I was addicted to the standard input of the Scanner class
I was addicted to scrollview because I couldn't tap the variable size UIView
[CircleCI] I was addicted to the automatic test of CircleCI (rails + mysql) [Memo]
I was addicted to using RXTX on Sierra
I was addicted to installing Ruby/Tk on MacOS
Try to get redmine API key with ruby
Getting Started with Doma-Introduction to the Criteria API
I was addicted to not being able to connect to AWS-S3 from the Docker container
I was a little addicted to the S3 Checksum comparison, so I made a note.
SpringSecurity I was addicted to trying to log in with a hashed password (solved)
I tried what I wanted to try with Stream softly.
What should I do to reload the updated Dockerfile?
I want to dark mode with the SWT app
I tried to draw animation with Blazor + canvas API
Addicted to the webpacker that comes standard with Rails 6
I tried to check the operation of http request (Put) with Talented API Tester
A memo that I was addicted to when making batch processing with Spring Boot
The part I was addicted to in "Introduction to Ajax in Java Web Applications" of NetBeans
I want to hit the API with Rails on multiple docker-composes set up locally
A memorandum because I was addicted to the setting of the Android project of IntelliJ IDEA
I knew what reflection was
I tried to increase the processing speed with spiritual engineering
When I tried to scroll automatically with JScrollBar, the event handler was drawn only once.
I want to use the Java 8 DateTime API slowly (now)
What I did in the version upgrade from Ruby 2.5.2 to 2.7.1
A story I was addicted to in Rails validation settings
Introduction to EHRbase 2-REST API
I tried to link chat with Minecraft server with Discord API
Implemented a strong API for "I want to display ~~ on the screen" with simple CQRS
REST API testing with REST Assured
I want to distinct the duplicated data with has_many through