@Path("/message")
public class MyRestResource {
@Autowired
private SpaceManager spaceManager;
@GET
@AnonymousAllowed
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response getMessage(@QueryParam("key") String key)
{
spaceManager.getAllSpaces();
if(key!=null)
return Response.ok(new MyRestResourceModel(key, getMessageFromKey(key))).build();
else
return Response.ok(new MyRestResourceModel("default","Hello World")).build();
}
That’s descriptive 
Can you tell us a bit more about your problem?
Error logs, plugin xml config would be also helpfull
if not add ‘@ComponentImport private SpaceManager spaceManager’ in MyRestResource.class is work, but add, return 404
access : http://localhost:5990/refapp/rest/myrestresource/1.0/message
return : HTTP Status 404 - NoOpServlet received an unexpected request. More information is available in the log file.
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.atlassian.plugins.tutorial</groupId>
<artifactId>Message</artifactId>
<version>1.0</version>
<organization>
<name>Example Company</name>
<url>http://www.example.com/</url>
</organization>
<name>Message</name>
<description>This is the com.atlassian.plugins.tutorial:Message plugin for Atlassian Refapp.</description>
<packaging>atlassian-plugin</packaging>
<dependencies>
<!--<dependency>-->
<!--<groupId>com.atlassian.labs</groupId>-->
<!--<artifactId>rest-api-browser</artifactId>-->
<!--<scope>provided</scope>-->
<!--</dependency>-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.atlassian.sal</groupId>
<artifactId>sal-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-annotation</artifactId>
<version>${atlassian.spring.scanner.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-runtime</artifactId>
<version>${atlassian.spring.scanner.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</dependency>
<dependency>
<groupId>com.atlassian.confluence.plugins</groupId>
<artifactId>confluence-license-rest</artifactId>
<version>6.4.0</version>
<scope>provided</scope>
</dependency>
<!-- WIRED TEST RUNNER DEPENDENCIES -->
<dependency>
<groupId>com.atlassian.plugins</groupId>
<artifactId>atlassian-plugins-osgi-testrunner</artifactId>
<version>${plugin.testrunner.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.2.2-atlassian-1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.atlassian.plugins.rest</groupId>
<artifactId>atlassian-rest-common</artifactId>
<version>1.0.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.wink</groupId>
<artifactId>wink-client</artifactId>
<version>1.1.3-incubating</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.8.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.atlassian.templaterenderer</groupId>
<artifactId>atlassian-template-renderer-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.atlassian.confluence</groupId>
<artifactId>confluence</artifactId>
<version>6.4.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.atlassian.platform</groupId>
<artifactId>platform</artifactId>
<version>${platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.atlassian.platform</groupId>
<artifactId>third-party</artifactId>
<version>${platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>com.atlassian.maven.plugins</groupId>
<artifactId>maven-refapp-plugin</artifactId>
<version>${amps.version}</version>
<extensions>true</extensions>
<configuration>
<productVersion>${refapp.version}</productVersion>
<enableQuickReload>true</enableQuickReload>
<enableFastdev>false</enableFastdev>
<!-- See here for an explanation of default instructions: -->
<!-- https://developer.atlassian.com/docs/advanced-topics/configuration-of-instructions-in-atlassian-plugins -->
<instructions>
<Atlassian-Plugin-Key>${atlassian.plugin.key}</Atlassian-Plugin-Key>
<!-- Add package to export here -->
<Export-Package>com.atlassian.plugins.tutorial.api,</Export-Package>
<!-- Add package import here -->
<Import-Package>
org.springframework.osgi.*; resolution:="optional",
org.eclipse.gemini.blueprint.*; resolution:="optional",
*
</Import-Package>
<!-- Ensure plugin is spring powered -->
<Spring-Context>*</Spring-Context>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-maven-plugin</artifactId>
<version>${atlassian.spring.scanner.version}</version>
<executions>
<execution>
<goals>
<goal>atlassian-spring-scanner</goal>
</goals>
<phase>process-classes</phase>
</execution>
</executions>
<configuration>
<scannedDependencies>
<dependency>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-external-jar</artifactId>
</dependency>
</scannedDependencies>
<verbose>false</verbose>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<platform.version>3.0.0</platform.version>
<refapp.version>3.3.6</refapp.version>
<amps.version>6.2.6</amps.version>
<plugin.testrunner.version>1.2.3</plugin.testrunner.version>
<atlassian.spring.scanner.version>1.2.13</atlassian.spring.scanner.version>
<!-- This key is used to keep the consistency between the key in atlassian-plugin.xml and the key to generate bundle. -->
<atlassian.plugin.key>${project.groupId}.${project.artifactId}</atlassian.plugin.key>
</properties>
</project>
atlassian-plugin.xml
<?xml version="1.0" encoding="UTF-8"?>
<atlassian-plugin key="${atlassian.plugin.key}" name="${project.name}" plugins-version="2">
<plugin-info>
<description>${project.description}</description>
<version>${project.version}</version>
<vendor name="${project.organization.name}" url="${project.organization.url}"/>
<param name="plugin-icon">images/pluginIcon.png</param>
<param name="plugin-logo">images/pluginLogo.png</param>
</plugin-info>
<!-- add our i18n resource -->
<resource type="i18n" name="i18n" location="Message"/>
<!-- add our web resources -->
<web-resource key="Message-resources" name="Message Web Resources">
<dependency>com.atlassian.auiplugin:ajs</dependency>
<resource type="download" name="Message.css" location="/css/Message.css"/>
<resource type="download" name="Message.js" location="/js/Message.js"/>
<resource type="download" name="images/" location="/images"/>
<context>Message</context>
</web-resource>
<rest name="My Rest Resource" i18n-name-key="my-rest-resource.name" key="my-rest-resource" path="/myrestresource" version="1.0">
<description key="my-rest-resource.description">The My Rest Resource Plugin</description>
</rest>
</atlassian-plugin>
Use code tags to post your pom.xml and atlassian-plugin.xml cause it is truncated and doesnt make any sense. I can only guess that you are using scanner 1.2.13 and amps 6.2.6 which requires the @ComponentImport annotation along with @Inject on constructor and @Scanned in the class.
Your class should become
@Path("/message")
@Scanned
public class MyRestResource {
@ComponentImport
private SpaceManager spaceManager;
@Inject
public MyRestResource(SpaceManager spaceManager){
this.spaceManager=spaceManager;
}
@GET
@AnonymousAllowed
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response getMessage(@QueryParam("key") String key)
{
spaceManager.getAllSpaces();
if(key!=null)
return Response.ok(new MyRestResourceModel(key, getMessageFromKey(key))).build();
else
return Response.ok(new MyRestResourceModel("default","Hello World")).build();
}
....
}
On top of that, why are you using refapp? Are you building cross platform plugin?
In my personal experience things are much easier for newcomers if you install a dev server.
I use altas-run, get error
…
[INFO] [talledLocalContainer] ERROR - 12:19:29,760 - assian.plugin.osgi.container.felix.FelixOsgiContainerManager - [FelixDispatchQueue] - Framework error in bundle com.atlassian.plugins.tutorial.Message
[INFO] [talledLocalContainer] org.osgi.framework.BundleException: Unresolved constraint in bundle com.atlassian.plugins.tutorial.Message [58]: Unable to resolve 58.0: missing requirement [58.0] osgi.wiring.package; (osgi.wiring.package=com.atlassian.confluence.spaces)
…
…
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.atlassian.plugins.tutorial</groupId>
<artifactId>Message</artifactId>
<version>1.0</version>
<organization>
<name>Example Company</name>
<url>http://www.example.com/</url>
</organization>
<name>Message</name>
<description>This is the com.atlassian.plugins.tutorial:Message plugin for Atlassian Refapp.</description>
<packaging>atlassian-plugin</packaging>
<repositories>
<repository>
<id>maven-external</id>
<url>https://maven.atlassian.com/maven-external/</url>
</repository>
</repositories>
<dependencies>
<!--<dependency>-->
<!--<groupId>com.atlassian.labs</groupId>-->
<!--<artifactId>rest-api-browser</artifactId>-->
<!--<scope>provided</scope>-->
<!--</dependency>-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.atlassian.sal</groupId>
<artifactId>sal-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-annotation</artifactId>
<version>${atlassian.spring.scanner.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-runtime</artifactId>
<version>${atlassian.spring.scanner.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</dependency>
<dependency>
<groupId>com.atlassian.confluence.plugins</groupId>
<artifactId>confluence-license-rest</artifactId>
<version>6.4.0</version>
<scope>provided</scope>
</dependency>
<!-- WIRED TEST RUNNER DEPENDENCIES -->
<dependency>
<groupId>com.atlassian.plugins</groupId>
<artifactId>atlassian-plugins-osgi-testrunner</artifactId>
<version>${plugin.testrunner.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.2.2-atlassian-1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.atlassian.plugins.rest</groupId>
<artifactId>atlassian-rest-common</artifactId>
<version>1.0.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.wink</groupId>
<artifactId>wink-client</artifactId>
<version>1.1.3-incubating</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.8.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.atlassian.templaterenderer</groupId>
<artifactId>atlassian-template-renderer-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.atlassian.confluence</groupId>
<artifactId>confluence</artifactId>
<version>6.4.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.atlassian.platform</groupId>
<artifactId>platform</artifactId>
<version>${platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.atlassian.platform</groupId>
<artifactId>third-party</artifactId>
<version>${platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>com.atlassian.maven.plugins</groupId>
<artifactId>maven-refapp-plugin</artifactId>
<version>${amps.version}</version>
<extensions>true</extensions>
<configuration>
<productVersion>${refapp.version}</productVersion>
<enableQuickReload>true</enableQuickReload>
<enableFastdev>false</enableFastdev>
<!-- See here for an explanation of default instructions: -->
<!-- https://developer.atlassian.com/docs/advanced-topics/configuration-of-instructions-in-atlassian-plugins -->
<instructions>
<Atlassian-Plugin-Key>${atlassian.plugin.key}</Atlassian-Plugin-Key>
<!-- Add package to export here -->
<Export-Package>com.atlassian.plugins.tutorial.api,</Export-Package>
<!-- Add package import here -->
<Import-Package>
org.springframework.osgi.*; resolution:="optional",
org.eclipse.gemini.blueprint.*; resolution:="optional",
*
</Import-Package>
<!-- Ensure plugin is spring powered -->
<Spring-Context>*</Spring-Context>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-maven-plugin</artifactId>
<version>${atlassian.spring.scanner.version}</version>
<executions>
<execution>
<goals>
<goal>atlassian-spring-scanner</goal>
</goals>
<phase>process-classes</phase>
</execution>
</executions>
<configuration>
<scannedDependencies>
<dependency>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-external-jar</artifactId>
</dependency>
</scannedDependencies>
<verbose>false</verbose>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<platform.version>3.0.0</platform.version>
<refapp.version>3.3.6</refapp.version>
<amps.version>6.2.6</amps.version>
<plugin.testrunner.version>1.2.3</plugin.testrunner.version>
<atlassian.spring.scanner.version>1.2.13</atlassian.spring.scanner.version>
<!-- This key is used to keep the consistency between the key in atlassian-plugin.xml and the key to generate bundle. -->
<atlassian.plugin.key>${project.groupId}.${project.artifactId}</atlassian.plugin.key>
</properties>
</project>
atlassian-plugin.xml
<?xml version="1.0" encoding="UTF-8"?>
<atlassian-plugin key="${atlassian.plugin.key}" name="${project.name}" plugins-version="2">
<plugin-info>
<description>${project.description}</description>
<version>${project.version}</version>
<vendor name="${project.organization.name}" url="${project.organization.url}"/>
<param name="plugin-icon">images/pluginIcon.png</param>
<param name="plugin-logo">images/pluginLogo.png</param>
</plugin-info>
<!-- add our i18n resource -->
<resource type="i18n" name="i18n" location="Message"/>
<!-- add our web resources -->
<web-resource key="Message-resources" name="Message Web Resources">
<dependency>com.atlassian.auiplugin:ajs</dependency>
<resource type="download" name="Message.css" location="/css/Message.css"/>
<resource type="download" name="Message.js" location="/js/Message.js"/>
<resource type="download" name="images/" location="/images"/>
<context>Message</context>
</web-resource>
<rest name="My Rest Resource" i18n-name-key="my-rest-resource.name" key="my-rest-resource" path="/myrestresource" version="1.0">
<description key="my-rest-resource.description">The My Rest Resource Plugin</description>
</rest>
</atlassian-plugin>
class
package com.atlassian.plugins.tutorial.rest;
import com.atlassian.confluence.spaces.SpaceManager;
import com.atlassian.plugin.spring.scanner.annotation.component.Scanned;
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import com.atlassian.plugins.rest.common.security.AnonymousAllowed;
import javax.inject.Inject;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
/**
* A resource of message.
*/
@Path("/message")
@Scanned
public class MyRestResource {
@ComponentImport
private final SpaceManager spaceManager;
@Inject
public MyRestResource(SpaceManager spaceManager) {
this.spaceManager = spaceManager;
}
@GET
@AnonymousAllowed
@Produces({MediaType.APPLICATION_JSON})
public Response getMessage(@QueryParam("key") String key)
{
if(key!=null)
return Response.ok("").build();
else
return Response.ok("").build();
}
}
Hi, @jiangwubo.
Since you are planning to create an app for Confluence Server, I would recommend using atlas-create-confluence-plugin as a starting point. This command creates a basic Confluence plugin for you and the project components like the proper dependencies, plugin, etc.
Cheers,
Ian
I want to create rest api plug
Hi, @jiangwubo.
Based on the tags Confluence Development and confluence-server, I assume that the REST API plugin you want to create is for Confluence Server. From what I understood in the previous comments that you have, you are starting off with a refapp, in which I believe might add unnecessary complexity, hence, here are the steps to create a Confluence plugin with a REST API module.
-
Run
atlas-create-confluence-plugin -
cd to the newly created project folder
-
Run
atlas-create-confluence-plugin-module. You will see something similar to this.
-
Please select REST Plugin Module.
-
The necessary files, resources, and configuration will be created for you.
A class file like this will be created.
package com.atlassian.tutorial.rest;
import com.atlassian.plugins.rest.common.security.AnonymousAllowed;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
/**
* A resource of message.
*/
@Path("/message")
public class MyRestResource {
@GET
@AnonymousAllowed
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response getMessage()
{
return Response.ok(new MyRestResourceModel("Hello World")).build();
}
}
Cheers,
Ian
If not add SpaceManager api in MyRestResource, it is work.
【
@Path("/message")
public class MyRestResource {
@GET
@AnonymousAllowed
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response getMessage()
{
return Response.ok(new MyRestResourceModel("Hello World")).build();
}
}
】
my question is add @annotation SpaceManager after, is it not work.
@Path("/message")
@Scanned
public class MyRestResource {
**@ComponentImport**
** private final SpaceManager spaceManager;**
** @Inject**
** public MyRestResource(SpaceManager spaceManager) {**
** this.spaceManager = spaceManager;**
** }**
@GET
@AnonymousAllowed
@Produces({MediaType.APPLICATION_JSON})
public Response getMessage(@QueryParam("key") String key)
{
if(key!=null)
return Response.ok("").build();
else
return Response.ok("").build();
}
can you gei me email of you, I send example source code to you, you trying run
can you gei me help?
How I import SpaceManager.class?
give me any way, please.
//such as, It is not work
@ComponentImport
private final SpaceManager spaceManager;
@Inject
public MyPluginComponentImpl(final SpaceManager spaceManager)
{
this.spaceManager = spaceManager;
}
Try this :
/**
* A resource of message.
*/
@Path("/message")
@Scanned
public class MyRestResource {
private final SpaceManager spaceManager;
@Autowired
public MyRestResource(@ComponentImport SpaceManager spaceManager) {
this.spaceManager = spaceManager;
}
It is not work, too
package com.ele.me.atlas.rest;
import com.atlassian.confluence.spaces.SpaceManager;
import com.atlassian.plugin.spring.scanner.annotation.component.Scanned;
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import com.atlassian.plugins.rest.common.security.AnonymousAllowed;
import org.springframework.beans.factory.annotation.Autowired;
import javax.inject.Inject;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
/**
-
A resource of message.
*/
@Path("/message")
@Scanned
public class MyRestResource {private final SpaceManager spaceManager;
@Autowired
public MyRestResource(@ComponentImport SpaceManager spaceManager) {
this.spaceManager = spaceManager;
}@GET
@AnonymousAllowed
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response getMessage()
{
return Response.ok(new MyRestResourceModel(“Hello World”)).build();
}
}
Do you have any logs we can use? errors?
Does your rest service appear in REST API Browser?
Start giving relative logs otherwise we are in a loop.
I made this github project for you, clone it using
git clone https://github.com/chmod/jiangwubo.git
and there run atlas-mvn clean && atlas-run -DskipTests on the project folder.
When it loads navigate to http://localhost:1990/confluence/rest/myrestresource/1.0/message.
You should see:
[“Demonstration Space”]
In the addons, for some weird reason the test gets installed… remove it.
