grails-jaxrs

7 篇文章 0 订阅
A quick guide to getting started with the JSR 311 plugin for Grails.

Important note : This page still describes version 0.1 of the plugin. Documentation for version 0.2 is work in progress.

Overview (version 0.2)

This page helps you getting started with the JSR 311 plugin for Grails. It is assumed that you have a basic understanding of Grails and the JSR 311 (JAX-RS: The Java API for RESTful Web Services). The examples in the following chapters have been tested with Grails 1.1.1. For instructions how to download and install Grails refer to the Grails reference documentation section 2.1 .

Hello world

Create a project

To use the plugin we create a new Grails project. Change the working directory to a location where you want to create a new Grails project and enter

grails create
-
app hello

on the command line. This creates a new directory hello .

Install the plugin

To install the plugin from the Grails Plugin Repository , go to the created hello directory and enter

grails install
-
plugin jaxrs

This will download the latest released version of the plugin from the Grails Plugin Repository . For further installation options refer to the installation instructions .

Create a resource

To create a JAX-RS resource named test enter

grails create
-
resource test

This will create a TestResource.groovy file under grails-app/resources and a TestResourceTests.groovy file under test/unit . The TestResourceTests.groovy file is a unit test template. The TestResource.groovy file is the generated JAX-RS resource.

import
 javax
.
ws
.
rs
.
GET
import javax . ws . rs . Path
import javax . ws . rs . Produces


@Path ( '/test' )
class TestResource {

   
@GET
   
@Produces ( 'text/plain' )
   
String getTestRepresentation () {
       
'Test'
   
}
   
}

It defines a single method that responds to HTTP GET operations. The response entity is set to the return value of the method, Test in this example. The content type of the response (Content-Type header) is text/plain . The created resource is ready to use as shown in the next section.

Creating resources via the command line is only one option. An alternative is to create resource files by hand. Any *Resource.groovy file created under grails-app/resources is assumed to be a JAX-RS resource and auto-detected by the grails-jaxrs plugin.

Run the application

To start the application enter

grails run
-
app

on the comamnd line. Then open a browser window and go to http://localhost:8080/hello/test . The browser should now display "Test ".

Change the code

The grails-jaxrs plugin also support code changes at runtime i.e. without restarting the server. To demonstrate that, open the TestResource.groovy file and change the return value of getTestRepresentation() to e.g. Hello world . Then, refresh the browser window and you should now see Hello world .

Using Eclipse

Using the hello project with the grails-jaxrs plugin in Eclipse requires a bit more than just importing the hello project. After import, the grails-jaxrs classes are not on the classpath of the project, therefore, you'll see compile errors for generated JAX-RS resources. The best way to resolve the compile errors is to import the grails-jaxrs plugin project as a separate project in Eclipse and reference that project from the hello project.

To checkout a released version of the grails-jaxrs project enter

svn 
export
 http
:
//grails-jaxrs.googlecode.com/svn/tags/jaxrs-<version> jaxrs

on the command line where <version> must be replaced by the version of the plugin you're using. This will create a local directory jaxrs , the root directory of the project. If you use a development snapshot checkout the sources from http://grails-jaxrs.googlecode.com/svn/trunk/jaxrs .

To import the project into Eclipse go to File -> Import... -> General -> Existing Projects Into Workspace and press Next . Then select the project's root directory and click Finish . You should now see a jaxrs project in the package explorer.

To add this new project as dependency to the hello project, right-click on the hello project and go to Properties -> Java Build Path -> Projects -> Add... . Select the jaxrs project from the list of projects in the workspace and press OK . The compile erros should now disappear.

Scaffolding

The grails-jaxrs plugin also supports scaffolding. It allows you to create a RESTful service interface for one or more domain classes based on JAX-RS resource classes. The following sections walk through a very simple example. Please note that the scaffolding feature of the plugin is still early-access .

Create a domain class

To create a Person domain class go to the project's root directory and enter

grails create
-
domain
-
class
 person

Open the generated Person.groovy file (under grails-app/domain ) and add two properties, firstName and lastName .

class
 
Person
 
{


   
static constraints = {
   
}
   
   
String firstName
   
   
String lastName
   
}

Generate the REST API

To generate JAX-RS resources that implement the RESTful service interface for that domain class enter

grails generate
-
resources person

This will generate two resource classes, PersonCollectionResource.groovy and PersonResource.groovy that support HTTP POST, GET, PUT and DELETE operations for creating, reading, updating and deleting Person objects, respectively. PersonCollectionResource.groovy is related Person lists, PersonResource.groovy is related to individual Person instances. Before digging into the generated code let's take a look at how to use the generated RESTful Person interface.

Use the REST API

... work in progress

Overview (version 0.1)

The following sections describe the (old) version 0.1 of the grails-jaxrs plugin.

This page helps you getting started with the JSR 311 plugin for Grails. It is assumed that you have a basic understanding of Grails and the JSR 311 (JAX-RS: The Java API for RESTful Web Services).

Prerequisites

Getting the plugin

Note: You can skip this section if you want to get the plugin directly from the Grails Plugin Repository .

Either download the latest plugin binary directly from directly from here or build it from its sources:

  • Checkout the code from Subversion via svn checkout http://grails-jaxrs.googlecode.com/svn/trunk/jaxrs jaxrs
  • Go to the created jaxrs directory.
  • Enter grails test-app on the command line to run the unit and integration tests (optional)
  • Enter grails package-plugin on the command line to create the plugin binary

The filename of the created plugin is grails-jaxrs-<version>.zip where <version> is the current development version. Alternatively, build the plugin from a tagged version .

Hello world

Create a project

To use the plugin we create a new Grails project. Change the working directory to a location where you want to create a new Grails project and enter

grails create-app hello

on the command line. This creates a new directory hello .

Install the plugin

Go to the created hello directory and enter

grails install-plugin jaxrs

on the comamnd line. This will download the latest released version of the plugin from the Grails Plugin Repository . If you downloaded or built the plugin as described in Getting the plugin enter

grails install-plugin /path/to/grails-jaxrs-<version>.zip

where /path/to needs to be replaced by the absolute or relative path to the grails-jaxrs plugin file.

Required libraries

In order work with JSR 311 annotations and classes the JSR 311 jar file (version 1.1) must be added to the project's lib folder.

Create a resource

In the hello project under src/groovy create a new Groovy class HelloResource.groovy :

import
 javax
.
ws
.
rs
.
GET
import javax . ws . rs . Path
import javax . ws . rs . Produces

import org . springframework . stereotype . Component

@Component
@Path ( '/test' )
class HelloResource {

   
@GET
   
@Produces ( 'text/plain' )
   
String greet () {
       
'Hello grails-jaxrs'
   
}
   
}

This implements a resource that responds to HTTP GET and produces representations of content type text/plain . The path of the resource URL is /test .

Setup the application context

Before the application can be started we need to add the resource to the Spring application context. We do this with a component scan . A component scan looks in the classpath for beans annotated with @Component and adds them to the application context. Here's the application context XML file (resources.xml ) that needs to be added to the grails-app/conf/spring directory of the hello project.

<beans
 
xmlns
=
"http://www.springframework.org/schema/beans"

       
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
       
xmlns:context = "http://www.springframework.org/schema/context"
       
xsi:schemaLocation = "
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd"
>

   
<context:annotation-config/>
   
<context:component-scan base-package = "**" />

</beans>

This scans components from all packages including the default package. If you don't want to use context:component-scan add the bean <bean class="HelloResource" /> directly to the application context.

Run the application

To start the application type

grails run-app

on the comamnd line. Then open a browser window and go to http://localhost:8080/hello/test . The browser should now display a "Hello grails-jaxrs".

Advanced topics

Configuration

By default all requests are forwarded to the JaxrsController which is contained in the grails-jaxrs plugin. In order to use "regular" Grails controllers besides the JaxrsController we need to extend the URL mappings.

Instead of extending the grails-app/conf/UrlMappings.groovy file directly the URL mappings for the JaxrsController are set via the org.grails.jaxrs.url.mappings configuration property. The property value is a list of URL patterns. For example, assuming that a Grails application is accessible under http://localhost:8080/hello where /hello is the context path and all JAX-RS resources are accessible via

we need to add the following entry to grails-app/conf/Config.groovy :

  • org.grails.jaxrs.url.mappings=['/test', '/notes']

This ensures that only requests with a URL path matching /test/... and /notes/... are forwarded to the JaxrsController , all other requests may go to other Grails controllers. More detailed, the grails-jaxrs plugin creates the following URL mappings when it is loaded:

  • "/test"(controller:"jaxrs")
  • "/test/**"(controller:"jaxrs")
  • "/notes"(controller:"jaxrs")
  • "/notes/**"(controller:"jaxrs")

Applying filters

Grails filters can be applied to JAX-RS resources as well. For example, to add a filter for the /test/** URL pattern, create a file TestFilters.groovy under grails-app/conf with a content like

class
 
TestFilters
 
{


   
def filters = {
           
        testUris
( uri : '/test/**' ) {
            before
= {
               
// do some preprocessing
           
}
            after
= {
               
// do some postprocessing
           
}
           
       
}  
   
}
}

Using GORM

Usage of GORM is demonstrated on a (over-simplified) web application that keeps track of notes that have been POSTed via HTTP.

  • POSTing to http://localhost:8080/hello/notes creates a new Note domain object in the database containing the actual note from the request body. The request content type is text/plain . The response content type is text/xml representing the created domain object including its identifier. The response Location header contains the URL of the created note resource.
  • GETing from http://localhost:8080/hello/notes obtains a list of all created notes so far or an empty list. The response content type is text/xml .
  • GETing from http://localhost:8080/hello/notes/{id } obtains a note with a certain id or an error message (along with status code 404) if a note with the given id doesn't exist.

The first step is to create the Note domain object. This can be either done via grails create-domain-class note from the command line or manually by adding a Note.groovy file with the following content to the grails-app/domain directory.

class
 
Note
 
{


   
static constraints = {
   
}
   
   
String text
   
}

The only thing a note object stores is the note text (and an id property that is available on every Grails domain object).

For creating new Note instances i.e. note resources we POST the notes text to http://localhost:8080/hello/notes . This resource is implemented with a NotesResource class

import
 grails
.
converters
.*

 
import javax . ws . rs . Consumes
import javax . ws . rs . GET
import javax . ws . rs . Produces
import javax . ws . rs . Path
import javax . ws . rs . PathParam
import javax . ws . rs . POST
import javax . ws . rs . core . Response
import javax . ws . rs . core . UriBuilder

import org . springframework . stereotype . Component

@Component
@Path ( '/notes' )
class NotesResource {

     
@POST
     
@Consumes ( 'text/plain' )
     
@Produces ( 'text/xml' )
     
Response addNote ( String text ) {
         
def note = new Note ( text : text ). save ()
         URI uri
= UriBuilder . fromPath ( note . id as String ). build ()
         
Response . created ( uri ). entity ( note as XML ). build ()
     
}

     
@GET
     
@Produces ( 'text/xml' )
     
Response getNotes () {
         
Response . ok ( Note . findAll () as XML ). build ()
     
}
     
}

Save this class as NotesResource.groovy in the src/groovy directory. Let's take a closer look at it. The class-level @Path annotation makes this resource accessible under the /notes path i.e. the full URL is http://localhost:8080/hello/notes . POSTing to this URL will call the addNote(String) method passing the request body via the text parameter. The text parameter is used to construct a Note object which is then stored in the database. The URL for the newly created note is constructed in the second line. We use this URL to set the Location response header with Response.created(uri) . The response body contains the XML representation of the note object. To create the XML representation the XML converter of Grails is used. Here's a sample HTTP request:

POST 
/
hello
/
notes
/
 HTTP
/
1.1

Content - Type : text / plain
Host : localhost : 8080
Content - Length : 27

Don 't forget to learn Scala

Here's a sample HTTP response:

HTTP
/
1.1
 
201
 
Created

Content - Type : text / xml
Location : http : //localhost:8080/hello/notes/1

<? xml version = "1.0" encoding = "UTF-8" ?>
< note id = "1" >
 
< text > Don 't forget to learn Scala</text>
</note>

To obtain a list of all notes send a GET request to http://localhost:8080/hello/notes which will call the getNotes() method. This method again uses the Grails XML converter to create an XML representation of the notes collection, such as

HTTP
/
1.1
 
200
 OK
Content - Type : text / xml

<? xml version = "1.0" encoding = "UTF-8" ?>
< list >
 
< note id = "1" >
   
< text > Don 't forget to learn Scala</text>
  </note>
  <note id="2">
    <text>Another important note</text>
  </note>
</list>

Finally we want to obtain individual notes via http://localhost:8080/hello/notes/{id} where id is in range 1..n. This can be achieved by adding a getNote(String method to the NotesResource class:

@Component

@Path ( '/notes' )
class NotesResource {

     
// ... other methods omitted

     
@Path ( '/{id}' )
     
NoteResource getNote ( @PathParam ( 'id' ) String id ) {
         
new NoteResource ( note : Note . get ( id ))
     
}
     
}

Instead of using a fixed path we use a path template where the last path segment is the variable part of the path. It is bound to the id parameter of the getNote(String) method using a @PathParam annotation. Instead of rendering the response directly in the NotesResource class it is delegated to the NoteResource class after we've loaded the note object from the database:

import
 
static
 javax
.
ws
.
rs
.
core
.
Response
.
Status
.
NOT_FOUND
 
import grails . converters .*
 
import javax . ws . rs . GET
import javax . ws . rs . Produces
import javax . ws . rs . core . Response

class NoteResource {

   
Note note

   
@GET
   
@Produces ( 'text/xml' )
   
Response getNote () {
       
if ( note ) {
           
Response . ok ( note as XML ). build ()
       
} else {
           
Response . status ( NOT_FOUND ). entity ( '<error>not found</error>' ). build ()
       
}
   
}
   
}

If a note object with the requested id exists an XML representation is returned, otherwise, an error message is created along with a status code 404 (NOT FOUND). For example, GETing the note http://localhost:8080/hello/notes/1 returns

HTTP
/
1.1
 
200
 OK
Content - Type : text / xml

<? xml version = "1.0" encoding = "UTF-8" ?>
< note id = "1" >
 
< text > Don 't forget to learn Scala</text>
</note>

Entity providers

Entity providers supply mapping services between representations and their associated Java types. They are used to factor out parsing and rendering code from resource classes. The grails-jaxrs plugin provides abstract base classes for entity providers.

These can be used for simple use cases. For example, if you want to use Groovy's markup builder for creating custom XML responses implement a NoteWriter provider class like to following:

import
 groovy
.
xml
.
MarkupBuilder


import java . io . OutputStreamWriter
import javax . ws . rs . Produces
import javax . ws . rs . ext . Provider

import javax . ws . rs . core . MultivaluedMap

import org . grails . jaxrs . support . MessageBodyWriterSupport
import org . grails . jaxrs . test . domain . Foo

import org . springframework . stereotype . Component

@Component
@Provider
@Produces ( 'text/xml' )
class NoteWriter extends MessageBodyWriterSupport < Note > {
   
   
void writeTo ( Note entity , MultivaluedMap httpHeaders , OutputStream entityStream ) {
       
def builder = new MarkupBuilder ( new OutputStreamWriter ( entityStream ))
        builder
. note {
            id
( entity . id )
            content
( entity . text )
       
}
       
// Alternative (default rendering):
       
// entityStream << (entity as XML)
   
}
   
}

Having such a provider in place, resource methods can return a Note object directly:

@Component

@Path ( '/notes' )
class NotesResource {

     
// ... other methods omitted

     
@Path ( '/{id}' )
     
Note getNote ( @PathParam ( 'id' ) String id ) {
         
Note . get ( id )
     
}
     
}

In this case the response looks like:

HTTP
/
1.1
 
200
 OK
Content - Type : text / xml

<? xml version = "1.0" encoding = "UTF-8" ?>
< note >
 
< id > 1 < /id>
  <content>Don't forget to learn Scala</
content >
</ note >

Service injection

Services can be auto-injected into resource objects with the following annotations:

For example, use @Resource(name='sampleService') to inject an instance of SampleService :

@Component

@Path ( '/test' )
public class HelloResource {

   
@Resource ( name = 'sampleService' )
   
def sampleService

   
// ...
     
}

The resource name is the name of the service bean in the application context. Grails adds services automatically to the application context where the bean name is derived from the service class name. Alternatively, add the JAX-RS resource to the application context and do the wiring manually:

<beans
 
xmlns
=
"http://www.springframework.org/schema/beans"

       
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
       
xsi:schemaLocation = "
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"
>

   
<bean class = "HelloResource" >
       
<property name = "sampleService" ref = "sampleService" />
   
</bean>

</beans>

Next steps

The next version (0.2) of the plugin will include:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
提供的源码资源涵盖了小程序应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值