cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache CXF Documentation: JAX-RS (JSR-311) (page edited)
Date Tue, 01 Jul 2008 22:43:00 GMT
<html>
<head>
    <base href="http://cwiki.apache.org/confluence" />
    <style type="text/css">
    <!--
    body, p, td, table, tr, .bodytext, .stepfield {
	font-family: Verdana, arial, sans-serif;
	font-size: 11px;
	line-height: 16px;
	color: #000000;
	font-weight: normal;
}
#PageContent {
	text-align: left;
	background-color: #fff;
	padding: 0px;
	margin: 0px;
    padding-bottom:20px;
}
/*
** when this stylesheet is used for the Tiny MCE Wysiwyg editor's edit area, we can't
** use an id=PageContent or class=wiki-content, so we must
** set the body style to that used for PageContent, and p to that used for wiki-content.
*/

body {
	margin: 0px;
	padding: 0px;
	text-align: center;
    background-color: #f0f0f0;
}

@media print {

body {
    background-color: #fff;
}

}

.monospaceInput {
    font:12px monospace
}

.wiki-content p, .commentblock p {
    margin: 16px 0px 16px 0px;
    padding: 0px;
}

.wiki-content-preview {
    padding: 5px;
    border-left: 1px solid #3c78b5;
    border-right: 1px solid #3c78b5;
}

ul, ol {
    margin-top: 2px;
    margin-bottom: 2px;
    padding-top: 0px;
    padding-bottom: 0px;
}

pre {
    padding: 0px;
    margin-top: 5px;
    margin-left: 15px;
    margin-bottom: 5px;
    margin-right: 5px;
    text-align: left;
}

.helpheading {
    font-weight: bold;
    background-color: #D0D9BD;
        border-bottom: 1px solid #3c78b5;
        padding: 4px 4px 4px 4px;
        margin: 0px;
        margin-top: 10px;
}
.helpcontent {
        padding: 4px 4px 20px 4px;
    background-color: #f5f7f1;
}

.code {
 	border: 1px dashed #3c78b5;
    font-size: 11px;
	font-family: Courier;
    margin: 10px;
	line-height: 13px;
}

.focusedComment {
    background: #ffffce;
}

.commentBox, .focusedComment {
    padding: 10px;
    margin: 5px 0 5px 0;
    border: 1px #bbb solid;
}

.codeHeader {
    background-color: #f0f0f0;
 	border-bottom: 1px dashed #3c78b5;
    padding: 3px;
	text-align: center;
}

.codeContent {
    text-align: left;
    background-color: #f0f0f0;
    padding: 3px;
}

.preformatted {
 	border: 1px dashed #3c78b5;
    font-size: 11px;
	font-family: Courier;
    margin: 10px;
	line-height: 13px;
}

.preformattedHeader {
    background-color: #f0f0f0;
 	border-bottom: 1px dashed #3c78b5;
    padding: 3px;
	text-align: center;
}

.preformattedContent {
    background-color: #f0f0f0;
    padding: 3px;
}

.panel {
 	border: 1px dashed #3c78b5;
    margin: 10px;
    margin-top: 0px;
}

.panelHeader {
    background-color: #f0f0f0;
 	border-bottom: 1px dashed #3c78b5;
    padding: 3px;
	text-align: center;
}

.panelContent {
    background-color: #f0f0f0;
    padding: 5px;
}

.anonymousAlert {
    background-color: #f0f0f0;
 	border: 1px dashed red;
    font-size: 11px;
    padding: 10px 5px 10px 5px;
    margin: 4px;
	line-height: 13px;
}

.lockAlert {
    background-color: #f0f0f0;
    width: 50%;
 	border: 1px dashed red;
    font-size: 11px;
    padding: 10px 5px 10px 5px;
    margin: 4px;
	line-height: 13px;
}


.code-keyword {
  color: #000091;
  background-color: inherit;
}

.code-object {
  color: #910091;
  background-color: inherit;
}

.code-quote {
  color: #009100;
  background-color: inherit;
}

.code-comment {
  color: #808080;
  background-color: inherit;
}


.code-xml .code-keyword {
  color: inherit;
  font-weight: bold;
}

.code-tag {
  color: #000091;
  background-color: inherit;
}

.breadcrumbs {
    background-color: #f0f0f0;
 	border-color: #3c78b5;
	border-width: 1px 0px 1px 0px;
	border-style: solid;
    font-size: 11px;
    padding: 3px 0px 3px 0px;
}

.navmenu {
    border: 1px solid #ccc;
}

.menuheading {
    font-weight: bold;
    background-color: #f0f0f0;
 	border-bottom: 1px solid #3c78b5;
	padding: 4px 4px 2px 4px;
}

.menuitems {
	padding: 4px 4px 20px 4px;
}

.rightpanel {
    border-left: 1px solid #ccc;
    border-bottom: 1px solid #ccc;
}

#helpheading {
    text-align: left;
    font-weight: bold;
    background-color: #D0D9BD;
 	border-bottom: 1px solid #3c78b5;
	padding: 4px 4px 4px 4px;
	margin: 0px;
}
#helpcontent {
	padding: 4px 4px 4px 4px;
    background-color: #f5f7f1;
}
.helptab-unselected {
    font-weight: bold;
	padding: 5px;
    background-color: #f5f7f1;
}
.helptab-selected {
    font-weight: bold;
    background-color: #D0D9BD;
	padding: 5px;
}
.helptabs {
    margin: 0px;
    background-color: #f5f7f1;
	padding: 5px;
}
.infopanel-heading {
    font-weight: bold;
	padding: 4px 0px 2px 0px;
}

.pagebody {
}

.pageheader {
	padding: 5px 5px 5px 0px;
 	border-bottom: 1px solid #3c78b5;
}

.pagetitle {
	font-size: 22px;
	font-weight: bold;
	font-family: Arial, sans-serif;
	color: #003366;
}

.newpagetitle {
    color: #ccc !important;
}

.steptitle {
	font-size: 18px;
	font-weight: bold;
	font-family: Arial, sans-serif;
	color: #003366;
	margin-bottom: 7px;
}

.substeptitle {
    font-size: 12px;
    font-weight: bold;
    font-family: Arial, sans-serif;
    color: #003366;
    margin: 2px 4px 4px 4px;
    padding: 2px 4px 1px 4px;
}

.stepdesc {
    font-family: Verdana, arial, sans-serif;
	font-size: 11px;
	line-height: 16px;
	font-weight: normal;
    color: #666666;
    margin-top: 7px;
    margin-bottom: 7px;
}

.steplabel {
    font-weight: bold;
    margin-right: 4px;
    color: black;
    float: left;
    width: 15%;
    text-align: right;
}

.stepfield {
    background: #f0f0f0;
    padding: 5px;
}

.submitButtons{
    margin-top:5px;
    text-align:right;
}

.formtitle {
	font-size: 12px;
	font-weight: bold;
	font-family: Arial, sans-serif;
	color: #003366;
}

.sectionbottom {
    border-bottom: 1px solid #3c78b5;
}

.topRow {
    border-top: 2px solid #3c78b5;
}

.tabletitle {
	font-size: 14px;
	font-weight: bold;
	font-family: Arial, sans-serif;
    padding: 3px 0px 2px 0px;
    margin: 8px 4px 2px 0px;
	color: #003366;
	border-bottom: 2px solid #3c78b5;
}
.pagesubheading {
    color: #666666;
    font-size: 10px;
    padding: 0px 0px 5px 0px;
}

HR {
	color: 3c78b5;
	height: 1;
}

A:link, A:visited, A:active, A:hover {
	color: #003366;
}

h1 A:link, h1 A:visited, h1 A:active {
	text-decoration: none;
}

h1 A:hover {
    border-bottom: 1px dotted #003366;
}

.wiki-content > :first-child, .commentblock > :first-child {
    margin-top: 3px;
}

.logocell {
    padding: 10px;
}

input {
	font-family: verdana, geneva, arial, sans-serif;
	font-size: 11px;
	color: #000000;
}

textarea, textarea.editor {
	font-family: verdana, geneva, arial, sans-serif;
	font-size: 11px;
	color: #333333;
}

/* use logoSpaceLink instead.
.spacenametitle {
	font: 21px/31px Impact, Arial, Helvetica;
    font-weight: 100;
    color: #999999;
	margin: 0px;
}
.spacenametitle img {
  margin: 0 0 -4px 0;
}
.spacenametitle a {
    text-decoration: none;
    color: #999999;
}
.spacenametitle a:visited {
    text-decoration: none;
    color: #999999;
}*/

.spacenametitle-printable {
	font: 20px/25px Impact, Arial, Helvetica;
    font-weight: 100;
    color: #999999;
	margin: 0px;
}
.spacenametitle-printable a {
    text-decoration: none;
    color: #999999;
}
.spacenametitle-printable a:visited {
    text-decoration: none;
    color: #999999;
}

.blogDate {
	font-weight: bold;
	text-decoration: none;
	color: black;
}

.blogSurtitle {
    background: #f0f0f0;
 	border: 1px solid #ddd;
	padding: 3px;
	margin: 1px 1px 10px 1px;
}

.blogHeading {
    font-size: 20px;
    line-height: normal;
    font-weight: bold;
    padding: 0px;
    margin: 0px;
}

.blogHeading a {
   text-decoration: none;
   color: black;
}

.endsection {
	align: right;
	color: #666666;
	margin-top: 10px;
}
.endsectionleftnav {
	align: right;
	color: #666666;
	margin-top: 10px;
}

h1 {
	font-size: 24px;
	line-height: normal;
	font-weight: bold;
	background-color: #f0f0f0;
	color: #003366;
 	border-bottom: 1px solid #3c78b5;
	padding: 2px;
	margin: 36px 0px 4px 0px;
}

h2 {
	font-size: 18px;
	line-height: normal;
	font-weight: bold;
	background-color: #f0f0f0;
 	border-bottom: 1px solid #3c78b5;
	padding: 2px;
	margin: 27px 0px 4px 0px;
}

h3 {
	font-size: 14px;
	line-height: normal;
	font-weight: bold;
	background-color: #f0f0f0;
	padding: 2px;
	margin: 21px 0px 4px 0px;
}

h4 {
	font-size: 12px;
	line-height: normal;
	font-weight: bold;
	background-color: #f0f0f0;
	padding: 2px;
	margin: 18px 0px 4px 0px;
}

h4.search {
	font-size: 12px;
	line-height: normal;
	font-weight: normal;
	background-color: #f0f0f0;
	padding: 4px;
	margin: 18px 0px 4px 0px;
}

h5 {
	font-size: 10px;
	line-height: normal;
	font-weight: bold;
	background-color: #f0f0f0;
	padding: 2px;
	margin: 14px 0px 4px 0px;
}

h6 {
	font-size: 8px;
	line-height: normal;
	font-weight: bold;
	background-color: #f0f0f0;
	padding: 2px;
	margin: 14px 0px 4px 0px;
}

.smallfont {
    font-size: 10px;
}
.descfont {
    font-size: 10px;
    color: #666666;
}
.smallerfont {
    font-size: 9px;
}
.smalltext {
    color: #666666;
    font-size: 10px;
}
.smalltext a {
    color: #666666;
}
.smalltext-blue {
    color: #3c78b5;
    font-size: 10px;
}
.surtitle {
    margin-left: 1px;
    margin-bottom: 5px;
    font-size: 14px;
    color: #666666;
}

/* css hack found here:  http://www.fo3nix.pwp.blueyonder.co.uk/tutorials/css/hacks/ */
.navItemOver { font-size: 10px; font-weight: bold; color: #ffffff; background-color: #003366; cursor: hand; voice-family: '\'}\''; voice-family:inherit; cursor: pointer;}
.navItemOver a { color: #ffffff; background-color:#003366; text-decoration: none; }
.navItemOver a:visited { color: #ffffff; background-color:#003366; text-decoration: none; }
.navItemOver a:hover { color: #ffffff; background-color:#003366; text-decoration: none; }
.navItem { font-size: 10px; font-weight: bold; color: #ffffff; background-color: #3c78b5; }
.navItem a { color: #ffffff; text-decoration: none; }
.navItem a:hover { color: #ffffff; text-decoration: none; }
.navItem a:visited { color: #ffffff; text-decoration: none; }

div.padded { padding: 4px; }
div.thickPadded { padding: 10px; }
h3.macrolibrariestitle {
    margin: 0px 0px 0px 0px;
}

div.centered { text-align: center; margin: 10px; }
div.centered table {margin: 0px auto; text-align: left; }

.tableview table {
    margin: 0;
}

.tableview th {
    text-align: left;
    color: #003366;
    font-size: 12px;
    padding: 5px 0px 0px 5px;
    border-bottom: 2px solid #3c78b5;
}
.tableview td {
    text-align: left;
    border-color: #ccc;
    border-width: 0px 0px 1px 0px;
    border-style: solid;
    margin: 0;
    padding: 4px 10px 4px 5px;
}

.grid {
    margin: 2px 0px 5px 0px;
    border-collapse: collapse;
}
.grid th  {
    border: 1px solid #ccc;
    padding: 2px 4px 2px 4px;
    background: #f0f0f0;
    text-align: center;
}
.grid td  {
    border: 1px solid #ccc;
    padding: 3px 4px 3px 4px;
}
.gridHover {
	background-color: #f9f9f9;
}

td.infocell {
    background-color: #f0f0f0;
}
.label {
	font-weight: bold;
	color: #003366;
}

label {
	font-weight: bold;
	color: #003366;
}

.error {
	background-color: #fcc;
}

.errorBox {
	background-color: #fcc;
    border: 1px solid #c00;
    padding: 5px;
    margin: 5px;
}

.errorMessage {
	color: #c00;
}

.success {
	background-color: #dfd;
}

.successBox {
	background-color: #dfd;
    border: 1px solid #090;
    padding: 5px;
    margin-top:5px;
    margin-bottom:5px;
}

blockquote {
	padding-left: 10px;
	padding-right: 10px;
	margin-left: 5px;
	margin-right: 0px;
	border-left: 1px solid #3c78b5;
}

table.confluenceTable
{
    margin: 5px;
    border-collapse: collapse;
}

/* Added as a temporary fix for CONF-4223. The table elements appear to be inheriting the border: none attribute from the sectionMacro class */
table.confluenceTable td.confluenceTd
{
    border-width: 1px;
    border-style: solid;
    border-color: #ccc;
    padding: 3px 4px 3px 4px;
}

/* Added as a temporary fix for CONF-4223. The table elements appear to be inheriting the border: none attribute from the sectionMacro class */
table.confluenceTable th.confluenceTh
{
    border-width: 1px;
    border-style: solid;
    border-color: #ccc;
    padding: 3px 4px 3px 4px;
    background-color: #f0f0f0;
    text-align: center;
}

td.confluenceTd
{
    border-width: 1px;
    border-style: solid;
    border-color: #ccc;
    padding: 3px 4px 3px 4px;
}

th.confluenceTh
{
    border-width: 1px;
    border-style: solid;
    border-color: #ccc;
    padding: 3px 4px 3px 4px;
    background-color: #f0f0f0;
    text-align: center;
}

DIV.small {
	font-size: 9px;
}

H1.pagename {
	margin-top: 0px;
}

IMG.inline  {}

.loginform {
    margin: 5px;
    border: 1px solid #ccc;
}

/* The text how the "This is a preview" comment should be shown. */
.previewnote { text-align: center;
                font-size: 11px;
                    color: red; }

/* How the preview content should be shown */
.previewcontent { background: #E0E0E0; }

/* How the system messages should be shown (DisplayMessage.jsp) */
.messagecontent { background: #E0E0E0; }

/* How the "This page has been modified..." -comment should be shown. */
.conflictnote { }

.createlink {
    color: maroon;
}
a.createlink {
    color: maroon;
}
.templateparameter {
    font-size: 9px;
    color: darkblue;
}

.diffadded {
    background: #ddffdd;
    padding: 1px 1px 1px 4px;
	border-left: 4px solid darkgreen;
}
.diffdeleted {
    color: #999;
    background: #ffdddd;
    padding: 1px 1px 1px 4px;
	border-left: 4px solid darkred;
}
.diffnochange {
    padding: 1px 1px 1px 4px;
	border-left: 4px solid lightgrey;
}
.differror {
    background: brown;
}
.diff {
    font-family: lucida console, courier new, fixed-width;
	font-size: 12px;
	line-height: 14px;
}
.diffaddedchars {
    background-color:#99ff99;
    font-weight:bolder;
}
.diffremovedchars {
    background-color:#ff9999;
    text-decoration: line-through;
    font-weight:bolder;
}

.greybackground {
    background: #f0f0f0
}

.greybox {
 	border: 1px solid #ddd;
	padding: 3px;
	margin: 1px 1px 10px 1px;
}

.borderedGreyBox {
    border: 1px solid #cccccc;
    background-color: #f0f0f0;
    padding: 10px;
}

.greyboxfilled {
 	border: 1px solid #ddd;
    background: #f0f0f0;
    padding: 3px;
	margin: 1px 1px 10px 1px;
}

.navBackgroundBox {
    padding: 5px 5px 5px 5px;
    font-size: 22px;
	font-weight: bold;
	font-family: Arial, sans-serif;
	color: white;
    background: #3c78b5;
    text-decoration: none;
}

.previewBoxTop {
	background-color: #f0f0f0;
    border-width: 1px 1px 0px 1px;
    border-style: solid;
    border-color: #3c78b5;
    padding: 5px;
    margin: 5px 0px 0px 0px;
    text-align: center;
}
.previewContent {
    background-color: #fff;
 	border-color: #3c78b5;
	border-width: 0px 1px 0px 1px;
	border-style: solid;
	padding: 10px;
	margin: 0px;
}
.previewBoxBottom {
	background-color: #f0f0f0;
    border-width: 0px 1px 1px 1px;
    border-style: solid;
    border-color: #3c78b5;
    padding: 5px;
    margin: 0px 0px 5px 0px;
    text-align: center;
}

.functionbox {
    background-color: #f0f0f0;
 	border: 1px solid #3c78b5;
	padding: 3px;
	margin: 1px 1px 10px 1px;
}

.functionbox-greyborder {
    background-color: #f0f0f0;
 	border: 1px solid #ddd;
	padding: 3px;
	margin: 1px 1px 10px 1px;
}

.search-highlight {
    background-color: #ffffcc;
}

/* normal (white) background */
.rowNormal {
    background-color: #ffffff;
 }

/* alternate (pale yellow) background */
.rowAlternate {
    background-color: #f7f7f7;
}

/* used in the list attachments table */
.rowAlternateNoBottomColor {
    background-color: #f7f7f7;
}

.rowAlternateNoBottomNoColor {
}

.rowAlternateNoBottomColor td {
    border-bottom: 0px;
}

.rowAlternateNoBottomNoColor td {
    border-bottom: 0px;
}

/* row highlight (grey) background */
.rowHighlight {
    background-color: #f0f0f0;

}

TD.greenbar {FONT-SIZE: 2px; BACKGROUND: #00df00; BORDER: 1px solid #9c9c9c; PADDING: 0px; }
TD.redbar {FONT-SIZE: 2px; BACKGROUND: #df0000; BORDER: 1px solid #9c9c9c; PADDING: 0px; }
TD.darkredbar {FONT-SIZE: 2px; BACKGROUND: #af0000; BORDER: 1px solid #9c9c9c; PADDING: 0px; }

TR.testpassed {FONT-SIZE: 2px; BACKGROUND: #ddffdd; PADDING: 0px; }
TR.testfailed {FONT-SIZE: 2px; BACKGROUND: #ffdddd; PADDING: 0px; }

.toolbar  {
    margin: 0px;
    border-collapse: collapse;
}

.toolbar td  {
    border: 1px solid #ccc;
    padding: 2px 2px 2px 2px;
    color: #ccc;
}

td.noformatting {
    border-width: 0px;
    border-style: none;
    text-align: center;
	padding: 0px;
}

.commentblock {
    margin: 12px 0 12px 0;
}

/*
 * Divs displaying the license information, if necessary.
 */
.license-eval, .license-none, .license-nonprofit {
    border-top: 1px solid #bbbbbb;
    text-align: center;
    font-size: 10px;
    font-family: Verdana, Arial, Helvetica, sans-serif;
}

.license-eval, .license-none {
    background-color: #ffcccc;
}

.license-eval b, .license-none b {
    color: #990000
}

.license-nonprofit {
    background-color: #ffffff;
}

/*
 * The shadow at the bottom of the page between the main content and the
 * "powered by" section.
 */
.bottomshadow {
    height: 12px;
    background-image: url("$req.contextPath/images/border/border_bottom.gif");
    background-repeat: repeat-x;
}

/*
 * Styling of the operations box
 */
.navmenu .operations li, .navmenu .operations ul {
    list-style: none;
    margin-left: 0;
    padding-left: 0;
}

.navmenu .operations ul {
    margin-bottom: 9px;
}

.navmenu .label {
    font-weight: inherit;
}

/*
 * Styling of ops as a toolbar
 */
.toolbar div {
    display: none;
}

.toolbar .label {
    display: none;
}

.toolbar .operations {
    display: block;
}

.toolbar .operations ul {
    display: inline;
    list-style: none;
    margin-left: 10px;
    padding-left: 0;
}

.toolbar .operations li {
    list-style: none;
    display: inline;
}

/* list page navigational tabs */
#foldertab {
padding: 3px 0px 3px 8px;
margin-left: 0;
border-bottom: 1px solid #3c78b5;
font: bold 11px Verdana, sans-serif;
}

#foldertab li {
list-style: none;
margin: 0;
display: inline;
}

#foldertab li a {
padding: 3px 0.5em;
margin-left: 3px;
border: 1px solid #3c78b5;
border-bottom: none;
background: #3c78b5;
text-decoration: none;
}

#foldertab li a:link { color: #ffffff; }
#foldertab li a:visited { color: #ffffff; }

#foldertab li a:hover {
color: #ffffff;
background: #003366;
border-color: #003366;
}

#foldertab li a.current {
background: white;
border-bottom: 1px solid white;
color: black;
}

#foldertab li a.current:link { color: black; }
#foldertab li a.current:visited { color: black; }
#foldertab li a.current:hover {
background: white;
border-bottom: 1px solid white;
color: black;
}

/* alphabet list */
ul#squaretab {
margin-left: 0;
padding-left: 0;
white-space: nowrap;
font: bold 8px Verdana, sans-serif;
}

#squaretab li {
display: inline;
list-style-type: none;
}

#squaretab a {
padding: 2px 6px;
border: 1px solid #3c78b5;
}

#squaretab a:link, #squaretab a:visited {
color: #fff;
background-color: #3c78b5;
text-decoration: none;
}

#squaretab a:hover {
color: #ffffff;
background-color: #003366;
border-color: #003366;
text-decoration: none;
}

#squaretab li a#current {
background: white;
color: black;
}

.blogcalendar * {
    font-family:verdana, arial, sans-serif;
    font-size:x-small;
    font-weight:normal;
    line-height:140%;
    padding:2px;
}


table.blogcalendar {
    border: 1px solid #3c78b5;
}

.blogcalendar th.calendarhead, a.calendarhead {
    font-size:x-small;
    font-weight:bold;
    padding:2px;
    text-transform:uppercase;
    background-color: #3c78b5;
    color: #ffffff;
    letter-spacing: .3em;
    text-transform: uppercase;
}

.calendarhead:visited {color: white;}
.calendarhead:active {color: white;}
.calendarhead:hover {color: white;}

.blogcalendar th {
    font-size:x-small;
    font-weight:bold;
    padding:2px;
    background-color:#f0f0f0;
}

.blogcalendar td {
    font-size:x-small;
    font-weight:normal;
}

.searchGroup { padding: 0 0 10px 0; background: #f0f0f0; }
.searchGroupHeading { font-size: 10px; font-weight: bold; color: #ffffff; background-color: #3c78b5; padding: 2px 4px 1px 4px; }
.searchItem { padding: 1px 4px 1px 4px; }
.searchItemSelected { padding: 1px 4px 1px 4px; font-weight: bold; background: #ddd; }

/* permissions page styles */
.permissionHeading {
    border-bottom: #bbb; border-width: 0 0 1px 0; border-style: solid; font-size: 16px; text-align: left;
}
.permissionTab {
    border-width: 0 0 0 1px; border-style: solid; background: #3c78b5; color: #ffffff; font-size: 10px;
}
.permissionSuperTab {
    border-width: 0 0 0 1px; border-style: solid; background: #003366; color: #ffffff;
}
.permissionCell {
    border-left: #bbb; border-width: 0 0 0 1px; border-style: solid;
}

/* warning panel */
.warningPanel { background: #FFFFCE; border:#F0C000 1px solid; padding: 8px; margin: 10px; }
/* alert panel */
.alertPanel { background: #FFCCCC; border:#C00 1px solid; padding: 8px; margin: 10px; }
/* info panel */
.infoPanel { background: #D8E4F1; border:#3c78b5 1px solid; padding: 8px; margin: 10px; }

/* side menu highlighting (e.g. space content screen) */
.optionPadded { padding: 2px; }
.optionSelected { background-color: #ffffcc; padding: 2px; border: 1px solid #ddd; margin: -1px; }
.optionSelected a { font-weight: bold; text-decoration: none; color: black; }

/* information macros */
.noteMacro { border-style: solid; border-width: 1px; border-color: #F0C000; background-color: #FFFFCE; text-align:left; margin-top: 5px; margin-bottom: 5px}
.warningMacro { border-style: solid; border-width: 1px; border-color: #c00; background-color: #fcc; text-align:left; margin-top: 5px; margin-bottom: 5px}
.infoMacro { border-style: solid; border-width: 1px; border-color: #3c78b5; background-color: #D8E4F1; text-align:left; margin-top: 5px; margin-bottom: 5px}
.tipMacro { border-style: solid; border-width: 1px; border-color: #090; background-color: #dfd; text-align:left; margin-top: 5px; margin-bottom: 5px}
.informationMacroPadding { padding: 5px 0 0 5px; }

table.infoMacro td, table.warningMacro td, table.tipMacro td, table.noteMacro td, table.sectionMacro td {
    border: none;
}

table.sectionMacroWithBorder td.columnMacro { border-style: dashed; border-width: 1px; border-color: #cccccc;}

.pagecontent
{
    padding: 10px;
    text-align: left;
}

/* styles for links in the top bar */
.topBarDiv a:link {color: #ffffff;}
.topBarDiv a:visited {color: #ffffff;}
.topBarDiv a:active {color: #ffffff;}
.topBarDiv a:hover {color: #ffffff;}
.topBarDiv {color: #ffffff;}

.topBar {
    background-color: #003366;
}


/* styles for extended operations */
.greyLinks a:link {color: #666666; text-decoration:underline;}
.greyLinks a:visited {color: #666666; text-decoration:underline;}
.greyLinks a:active {color: #666666; text-decoration:underline;}
.greyLinks a:hover {color: #666666; text-decoration:underline;}
.greyLinks {color: #666666; display:block; padding: 10px}

.logoSpaceLink {color: #999999; text-decoration: none}
.logoSpaceLink a:link {color: #999999; text-decoration: none}
.logoSpaceLink a:visited {color: #999999; text-decoration: none}
.logoSpaceLink a:active {color: #999999; text-decoration: none}
.logoSpaceLink a:hover {color: #003366; text-decoration: none}

/* basic panel (basicpanel.vmd) style */
.basicPanelContainer {border: 1px solid #3c78b5; margin-top: 2px; margin-bottom: 8px; width: 100%}
.basicPanelTitle {padding: 5px; margin: 0px; background-color: #f0f0f0; color: black; font-weight: bold;}
.basicPanelBody {padding: 5px; margin: 0px}

.separatorLinks a:link {color: white}
.separatorLinks a:visited {color: white}
.separatorLinks a:active {color: white}

.greynavbar {background-color: #f0f0f0; border-top: 1px solid #3c78b5; margin-top: 2px}

div.headerField {
    float: left;
    width: auto;
    height: 100%;
}

.headerFloat {
    margin-left: auto;
    width: 50%;
}

.headerFloatLeft {
    float: left;
    margin-right: 20px;
    margin-bottom: 10px;
}

#headerRow {
    padding: 10px;
}

div.license-personal {
   background-color: #003366;
   color: #ffffff;
}

div.license-personal a {
   color: #ffffff;
}

.greyFormBox {
    border: 1px solid #cccccc;
    padding: 5px;
}

/* IE automatically adds a margin before and after form tags. Use this style to remove that */
.marginlessForm {
    margin: 0px;
}

.openPageHighlight {
    background-color: #ffffcc;
    padding: 2px;
    border: 1px solid #ddd;
}

.editPageInsertLinks, .editPageInsertLinks a
{
    color: #666666;
    font-weight: bold;
    font-size: 10px;
}

/* Style for label heatmap. */
.top10 a {
    font-weight: bold;
    font-size: 2em;
    color: #003366;
}
.top25 a {
    font-weight: bold;
    font-size: 1.6em;
    color: #003366;
}
.top50 a {
    font-size: 1.4em;
    color: #003366;
}
.top100 a {
    font-size: 1.2em;
    color: #003366;
}

.heatmap {
    list-style:none;
    width: 95%;
    margin: 0px auto;
}

.heatmap a {
    text-decoration:none;
}

.heatmap a:hover {
    text-decoration:underline;
}

.heatmap li {
    display: inline;
}

.minitab {
padding: 3px 0px 3px 8px;
margin-left: 0;
margin-top: 1px;
margin-bottom: 0px;
border-bottom: 1px solid #3c78b5;
font: bold 9px Verdana, sans-serif;
text-decoration: none;
float:none;
}
.selectedminitab {
padding: 3px 0.5em;
margin-left: 3px;
margin-top: 1px;
border: 1px solid #3c78b5;
background: white;
border-bottom: 1px solid white;
color: #000000;
text-decoration: none;
}
.unselectedminitab {
padding: 3px 0.5em;
margin-left: 3px;
margin-top: 1px;
border: 1px solid #3c78b5;
border-bottom: none;
background: #3c78b5;
color: #ffffff;
text-decoration: none;
}

a.unselectedminitab:hover {
color: #ffffff;
background: #003366;
border-color: #003366;
}

a.unselectedminitab:link { color: white; }
a.unselectedminitab:visited { color: white; }

a.selectedminitab:link { color: black; }
a.selectedminitab:visited { color: black; }

.linkerror { background-color: #fcc;}

a.labelOperationLink:link {text-decoration: underline}
a.labelOperationLink:active {text-decoration: underline}
a.labelOperationLink:visited {text-decoration: underline}
a.labelOperationLink:hover {text-decoration: underline}

a.newLabel:link {background-color: #ddffdd}
a.newLabel:active {background-color: #ddffdd}
a.newLabel:visited {background-color: #ddffdd}
a.newLabel:hover {background-color: #ddffdd}

ul.square {list-style-type: square}

.inline-control-link {
    background: #ffc;
    font-size: 9px;
    color: #666;
    padding: 2px;
    text-transform: uppercase;
    text-decoration: none;
}


.inline-control-link a:link {text-decoration: none}
.inline-control-link a:active {text-decoration: none}
.inline-control-link a:visited {text-decoration: none}
.inline-control-link a:hover {text-decoration: none}

.inline-control-link {
    background: #ffc;
    font-size: 9px;
    color: #666;
    padding: 2px;
    text-transform: uppercase;
    text-decoration: none;
    cursor: pointer;
}

div.auto_complete {
    width: 350px;
    background: #fff;
}
div.auto_complete ul {
    border: 1px solid #888;
    margin: 0;
    padding: 0;
    width: 100%;
    list-style-type: none;
}
div.auto_complete ul li {
    margin: 0;
    padding: 3px;
}
div.auto_complete ul li.selected {
    background-color: #ffb;
}
div.auto_complete ul strong.highlight {
    color: #800;
    margin: 0;
    padding: 0;
}

/******* Edit Page Styles *******/
.toogleFormDiv{
    border:1px solid #A7A6AA;
    background-color:white;
    padding:5px;
    margin-top: 5px;
}

.toogleInfoDiv{
    border:1px solid #A7A6AA;
    background-color:white;
    display:none;
    padding:5px;
    margin-top: 10px;
}

.inputSection{
    margin-bottom:20px;
}

#editBox{
   border:1px solid lightgray;
   background-color:#F0F0F0;
}

/******* Left Navigation Theme Styles ********/
.leftnav li a {
    text-decoration:none;
    color:white;
    margin:0px;
    display:block;
    padding:2px;
    padding-left:5px;
    background-color: #3c78b5;
    border-top:1px solid #3c78b5;
}

.leftnav li a:active {color:white;}
.leftnav li a:visited {color:white;}
.leftnav li a:hover {background-color: #003366; color:white;}

/* Added by Shaun during i18n */
.replaced
{
    background-color: #33CC66;
}

.topPadding
{
    margin-top: 20px;
}

/* new form style */
.form-block {
    padding: 6px;
}
.form-error-block {
    padding: 6px;
    background: #fcc;
    border-top: #f0f0f0 1px solid;
    border-bottom: #f0f0f0 1px solid;
    margin-bottom: 6px;
    padding: 0 12px 0 12px;
}
.form-element-large {
    font-size: 16px;
    font-weight: bold;
    font-family: Arial, sans-serif;
    color: #003366;
}

.form-element-small {
    font-size: 12px;
    font-weight: bold;
    font-family: Arial, sans-serif;
    color: #003366;
}

.form-header {
    background: lightyellow;
    border-top: #f0f0f0 1px solid;
    border-bottom: #f0f0f0 1px solid;
    margin-bottom: 6px;
    padding: 0 12px 0 12px;
}
.form-header p, .form-block p, .form-error-block p {
    line-height: normal;
    margin: 12px 0 12px 0;
}
.form-example {
    color: #888;
    font-size: 11px;
}
.form-divider {
    border-bottom: #ccc 1px solid;
    margin-bottom: 6px;
}
.form-buttons {
    margin-top: 6px;
    border-top: #ccc 1px solid;
    border-bottom: #ccc 1px solid;
    background: #f0f0f0;
    padding: 10px;
    text-align: center;
}
.form-buttons input {
    width: 100px;
}
.form-block .error {
    padding: 6px;
    margin-bottom: 6px;
}
    -->
    </style>
</head>
<body>

<div id="PageContent">
<table class="pagecontent" border="0" cellpadding="0" cellspacing="0" width="100%"><tr>
<td valign="top" class="pagebody">

    <div class="pageheader">
        <span class="pagetitle">
            Page Edited :
            <a href="http://cwiki.apache.org/confluence/display/CXF20DOC">CXF20DOC</a> :
            <a href="http://cwiki.apache.org/confluence/display/CXF20DOC/JAX-RS+%28JSR-311%29">JAX-RS (JSR-311)</a>
        </span>
    </div>

     <p>
        <a href="http://cwiki.apache.org/confluence/display/CXF20DOC/JAX-RS+%28JSR-311%29">JAX-RS (JSR-311)</a>
        has been edited by             <a href="http://cwiki.apache.org/confluence/display/~sergey_beryozkin">Sergey Beryozkin</a>
            <span class="smallfont">(Jul 01, 2008)</span>.
     </p>
    
     <p>
                 <a href="http://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=70366&originalVersion=29&revisedVersion=30">(View changes)</a>
     </p>

    <span class="label">Content:</span><br/>
    <div class="greybox wiki-content"><p>CXF has an initial implementation of JAX-RS (JSR-311): Java API for RESTfulWeb Services. JAX-RS provides a more standard way to build RESTful services in Java. <span class="nobr"><a href="https://jsr311.dev.java.net/nonav/releases/0.8/index.html" title="Visit page outside Confluence" rel="nofollow">0.8 version of JSR-311 API <sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span> is currently supported.</p>

<p>JAX-RS related demos are located under samples\jax_rs directory (CXF 2.1 only).</p>

<h1><a name="JAX-RS%28JSR-311%29-Understandingthebasics"></a>Understanding the basics</h1>

<p>You are encouraged to read <span class="nobr"><a href="http://jcp.org/en/jsr/detail?id=311" title="Visit page outside Confluence" rel="nofollow">JAX-RS spec <sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span> to find out information not covered by this documentation.</p>

<h2><a name="JAX-RS%28JSR-311%29-Resourceclass"></a>Resource class</h2>

<p>A resource class is a Java class annotated with JAX-RS annotations to represent a Web resource. A typical resource class in JAX-RS looks like this below:</p>
<div class="code"><div class="codeContent">
<pre class="code-java"><span class="code-keyword">package</span> demo.jaxrs.server;

<span class="code-keyword">import</span> java.util.HashMap;
<span class="code-keyword">import</span> java.util.Map;

<span class="code-keyword">import</span> javax.ws.rs.GET;
<span class="code-keyword">import</span> javax.ws.rs.ProduceMime;
<span class="code-keyword">import</span> javax.ws.rs.Path;
<span class="code-keyword">import</span> javax.ws.rs.PathParam;
<span class="code-keyword">import</span> javax.ws.rs.core.Context;
<span class="code-keyword">import</span> javax.ws.rs.core.Response;
<span class="code-keyword">import</span> javax.ws.rs.core.UriInfo;

@Path(<span class="code-quote">"/customerservice/"</span>)
@ProduceMime(<span class="code-quote">"application/xml"</span>)
<span class="code-keyword">public</span> class CustomerService {

    <span class="code-keyword">public</span> CustomerService() {
    }

    @GET
    <span class="code-keyword">public</span> Customers getCustomers() {
        ......
    }

    @GET
    @Path(<span class="code-quote">"/customers/{id}"</span>)
    @ProduceMime(<span class="code-quote">"application/json"</span>)
    <span class="code-keyword">public</span> Customer getCustomer(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">String</span> id) {
        ......
    }

    @PUT
    @Path(<span class="code-quote">"/customers/{id}"</span>)
    @ConsumeMime(<span class="code-quote">"application/xml"</span>)
    <span class="code-keyword">public</span> Response updateCustomer(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">Long</span> id, Customer customer) {
        ......
    }

    @POST
    @Path(<span class="code-quote">"/customers"</span>)
    <span class="code-keyword">public</span> Response addCustomer(Customer customer) {
        ......
    }

    @DELETE
    @Path(<span class="code-quote">"/customers/{id}/"</span>)
    <span class="code-keyword">public</span> Response deleteCustomer(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">String</span> id) {
        ......
    }

    @Path(<span class="code-quote">"/orders/{orderId}/"</span>)
    <span class="code-keyword">public</span> Order getOrder(@PathParam(<span class="code-quote">"orderId"</span>) <span class="code-object">String</span> orderId) {
       ......
    }
}</pre>
</div></div>

<p>Customer resource class can handle requests starting from /customerservice. When /customerservice request is matched to this class, its getCustomers() method will be selected. updateCustomer(), deleteCustomer() and addCustomer() are used to serve POST, PUT and DELETE requests starting from /customerservice/customer, while getOrder() method delegates the handling of requests like /customerservice/orders/1 to a subresource locator Order.</p>

<p>ProduceMime annotation is used to specify the format of the response. When not available on the method, it's inherited from a class, and if it's not available on the class then it's inherited from a corresponding message body writer, if any. Default value is &#42;/&#42;, but it's recommended that some definite value is specified. The same applies to ConsumeMime, only it's message body readers that are checked as the last resort.</p>

<p>For example, getCustomers() method inherits the ProduceMime annotation from its class, while getCustomer() method overrides it with its own value.  </p>

<h2><a name="JAX-RS%28JSR-311%29-@Path"></a>@Path</h2>

<p>@Path annotation is applied to resource classes or methods. The value of @Path annotation is a relative URI path and follows the URI Template format. </p>

<p>More information about Path annotations can be found from <span class="nobr"><a href="http://jcp.org/en/jsr/detail?id=311" title="Visit page outside Confluence" rel="nofollow">JAX-RS spec <sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span> section 2.3. </p>

<h2><a name="JAX-RS%28JSR-311%29-HTTPMethod"></a>HTTP Method</h2>

<p>JAX-RS specification defines a number of annotations such as @GET, @PUT, @POST and @DELETE. Using an @HttpMethod designator, one can create a custom annotation such as @Update or @Patch</p>

<h2><a name="JAX-RS%28JSR-311%29-Returntypes"></a>Return types</h2>

<p>Either javax.ws.rs.core.Response or custom type can be returned. javax.ws.rs.core.Response can be used to set the HTTP response code, headers and entity. </p>

<h3><a name="JAX-RS%28JSR-311%29-Exceptionhandling"></a>Exception handling</h3>

<p>One can either throw an unchecked WebApplicationException or return Response with a proper error code set.<br/>
The former option may be a better option when no JAX-RS types can be added to method signatures.</p>

<p>For example :</p>

<div class="code"><div class="codeContent">
<pre class="code-java">@Path(<span class="code-quote">"/customerservice/"</span>)
<span class="code-keyword">public</span> class CustomerService {

    
    @PUT
    @Path(<span class="code-quote">"/customers/{id}"</span>)
    <span class="code-keyword">public</span> Response updateCustomer(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">Long</span> id, Customer customer) {
        <span class="code-keyword">return</span> Response.status(errorCode).build();
    }

    @POST
    @Path(<span class="code-quote">"/customers"</span>)
    <span class="code-keyword">public</span> Customer addCustomer(Customer customer) {
        <span class="code-keyword">throw</span> <span class="code-keyword">new</span> WebApplicationException(errorCode);
    }

}</pre>
</div></div>

<p>Yet another option is to register an ExceptionMapper provider. Ex :</p>

<div class="code"><div class="codeContent">
<pre class="code-java"><span class="code-keyword">public</span> BookExceptionMapper <span class="code-keyword">implements</span> ExceptionMapper&lt;BookException&gt; {
    <span class="code-keyword">public</span> Response toResponse(BookException ex) {
        <span class="code-comment">// convert to Response
</span>    }
}</pre>
</div></div>

<p>This allows to throw exceptions from an application code and deal with the proper mapping to an HTTP response in a registered provider.</p>

<h2><a name="JAX-RS%28JSR-311%29-DealingwithParameters"></a>Dealing with Parameters</h2>

<p>PathParam annotation is used to map a given Path template variable to a method parameter.<br/>
For example :</p>

<div class="code"><div class="codeContent">
<pre class="code-java">@Path(<span class="code-quote">"/customer/{id}"</span>)
<span class="code-keyword">public</span> class CustomerService {

    
    @PUT
    @Path(<span class="code-quote">"{name}"</span>)
    <span class="code-keyword">public</span> Response updateCustomer(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">Long</span> id, @PathParam(<span class="code-quote">"name"</span>) <span class="code-object">String</span> name) {
        ...
    }
}</pre>
</div></div>

<p>In this case a template variable id available from a root class annotation is mapped to a parameter of type Long, while a name variable is mapped to a parameter of type String.</p>

<p>QueryParam, HttpHeader, MatrixParam and CookieParam annotations are also supported.<br/>
Parameters can be of type String or of any type that have constructors accepting a String parameter or static valueOf(String s) methods. JAX-RS PathSegment is also supported. A sequence of identically named parameters (queries, headers, etc) can be mapped to List or Set or SortedSet.  </p>

<p>All the parameters are automatically decoded. This can be disabled by using @Encoded annotation.</p>

<p>Parameters can have a default value set using a DefaultValue annotation :</p>

<div class="code"><div class="codeContent">
<pre class="code-java"><span class="code-keyword">public</span> Response updateCustomer(@DefaultValue(<span class="code-quote">"123"</span>) @QueryParam(<span class="code-quote">"id"</span>) <span class="code-object">Long</span> id, @PathParam(<span class="code-quote">"name"</span>) <span class="code-object">String</span> name) {
        ...
    }
}</pre>
</div></div>

<p>Currently this annotation is only noticed if it targets a parameter, and at the moment it can not be applied to @PathParam</p>

<p>There's also a CXF extension which makes it possible to inject a sequence of Path or Query parameters into a bean. For ex :</p>

<div class="code"><div class="codeContent">
<pre class="code-java">@Path(<span class="code-quote">"/customer/{id}"</span>)
<span class="code-keyword">public</span> class CustomerService {

    
    @PUT
    @Path(<span class="code-quote">"{name}"</span>)
    <span class="code-keyword">public</span> Response updateCustomer(@PathParam("") Customer customer) {
        ...
    }
}

<span class="code-keyword">public</span> class Customer {
   <span class="code-keyword">public</span> void setId(<span class="code-object">Long</span> id) {...}
   <span class="code-keyword">public</span> void setName(<span class="code-object">String</span> s) {...}  
}</pre>
</div></div>

<p>Note that there's a single @PathParam with an empty value - this is an extension bit. The value for a template variable 'id' is<br/>
injected into Customer.setId(Long id), while the value for 'name' is injected into Customer.setName(String s). The setter methods should have a single parameter, the conversion from the actual value to the parameter instance follows the same procedure as outlined above.</p>

<p>Starting from JAX-RS 0.8, it's also possible to inject all types of parameters into fields or through dedicated setters. For ex, the frist code fragment in this section can be rewritten like this  :</p>

<div class="code"><div class="codeContent">
<pre class="code-java">@Path(<span class="code-quote">"/customer/{id}"</span>)
<span class="code-keyword">public</span> class CustomerService {

    @PathParam(<span class="code-quote">"id"</span>)
    <span class="code-keyword">private</span> <span class="code-object">Long</span> id; 
    
    <span class="code-keyword">private</span> <span class="code-object">String</span> name;

    @PathParam(<span class="code-quote">"name"</span>)
    <span class="code-keyword">public</span> setName(<span class="code-object">String</span> name) {
        <span class="code-keyword">this</span>.name = name;
    } 

    @PUT
    @Path(<span class="code-quote">"{name}"</span>)
    <span class="code-keyword">public</span> Response updateCustomer() {
        <span class="code-comment">// use id and name
</span>    }
}</pre>
</div></div>


<h2><a name="JAX-RS%28JSR-311%29-Contextannotations"></a>Context annotations</h2>

<p>A number of context types can be injected as parameters, in fields or through dedicated methods.<br/>
UriInfo, SecurityContext, HttpHeaders, MessageBodyWorkers, ContextResolver, Servlet types such as HttpServletRequest<br/>
can be injected. </p>

<p>Example :</p>

<div class="code"><div class="codeContent">
<pre class="code-java">@Path(<span class="code-quote">"/customer"</span>)
<span class="code-keyword">public</span> class CustomerService {
    
    @Context 
    <span class="code-keyword">private</span> ServletContext sc;
    <span class="code-keyword">private</span> UriInfo ui;
    
    @Context
    <span class="code-keyword">public</span> void setUriInfo(UriInfo ui) {
        <span class="code-keyword">this</span>.ui = ui;
    }

    @PUT
    <span class="code-keyword">public</span> Response updateCustomer(@Context HttpHeaders h, Customer c) {
        ...
    }
}</pre>
</div></div>

<p>Note that all types of supported JAX-RS providers such as MessageBodyWriter, MessageBodyReader, ExceptionMapper and ContextResolver, as well as the list of body providers which can be provided by MessageBodyWorkers can have contexts injected too. The only exception is that no parameter level injection is supported due to provider's methods being fixed.</p>

<p>Note that MessageBodyWorkers and ContextResolver are likely to be of interest to message body providers rather than to the actual application code.</p>

<p>You can also inject Servlet types into @Resource annotated fields. Other types would likely be supported too.</p>



<h2><a name="JAX-RS%28JSR-311%29-Annotationinheritance"></a>Annotation inheritance</h2>

<p>Most of the JAX-RS annotations can be inherited from either an interface or a superclass. JAX-RS specification requires that only the ones applied to methods can be inherited. For example :</p>

<div class="code"><div class="codeContent">
<pre class="code-java"><span class="code-keyword">public</span> <span class="code-keyword">interface</span> CustomerService {

    @PUT
    @Path(<span class="code-quote">"/customers/{id}"</span>)
    Response updateCustomer(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">Long</span> id, Customer customer) {
        <span class="code-keyword">return</span> Response.status(errorCode).build();
    }

    @POST
    @Path(<span class="code-quote">"/customers"</span>)
    Customer addCustomer(Customer customer) {
        <span class="code-keyword">throw</span> <span class="code-keyword">new</span> WebApplicationException(errorCode);
    }

}

@Path(<span class="code-quote">"/customerservice/"</span>)
<span class="code-keyword">public</span> class Customers <span class="code-keyword">implements</span> CustomerService {

    
    <span class="code-keyword">public</span> Response updateCustomer(<span class="code-object">Long</span> id, Customer customer) {
        <span class="code-keyword">return</span> Response.status(errorCode).build();
    }

    <span class="code-keyword">public</span> Customer addCustomer(Customer customer) {
        <span class="code-keyword">throw</span> <span class="code-keyword">new</span> WebApplicationException(errorCode);
    }

}</pre>
</div></div>

<p>Similarly, annotations can be inherited from super-classes. <br/>
The resource class can also inherit the class-level annotations from either one of implemented interfaces or its superclass.    </p>


<h2><a name="JAX-RS%28JSR-311%29-Subresourcelocators."></a>Sub-resource locators.</h2>

<p>A method of a resource class that is annotated with @Path becomes a sub-resource locator when an annotation with an HttpMethod designator like @GET is not present. Sub-resource locators are used to further resolve the object that will handle the request. They can delegate to other sub-resource locators. </p>

<p>In the example below, getOrder method is a sub-resource locator:</p>
<div class="code"><div class="codeContent">
<pre class="code-java">@Path(<span class="code-quote">"/customerservice/"</span>)
<span class="code-keyword">public</span> class CustomerService {

    @Path(<span class="code-quote">"/orders/{orderId}/"</span>)
    <span class="code-keyword">public</span> Order getOrder(@PathParam(<span class="code-quote">"orderId"</span>) <span class="code-object">String</span> orderId) {
       ......
    }
}

@XmlRootElement(name = <span class="code-quote">"Order"</span>)
<span class="code-keyword">public</span> class Order {
    <span class="code-keyword">private</span> <span class="code-object">long</span> id;

    <span class="code-keyword">public</span> Order() {
    }

    <span class="code-keyword">public</span> <span class="code-object">long</span> getId() {
        <span class="code-keyword">return</span> id;
    }


    @GET
    @Path(<span class="code-quote">"products/{productId}/"</span>)
    <span class="code-keyword">public</span> Product getProduct(@PathParam(<span class="code-quote">"productId"</span>)<span class="code-object">int</span> productId) {
       ......
    }
}</pre>
</div></div>
<p>A HTTP GET request to <span class="nobr"><a href="http://localhost:9000/customerservice/orders/223/products/323" title="Visit page outside Confluence" rel="nofollow">http://localhost:9000/customerservice/orders/223/products/323<sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span> is dispatched to getOrder method first. If the Order resource whose id is 223 is found, the Order 223 will be used to further resolve Product resource. Eventually, a Product 323 that belongs to Order 223 is returned.</p>

<p>Note that a given subresource can be represented as an interface and resolved to an actual class at runtime. In this case any resource methods which have to be invoked on a subresource have to be inherited from a given interface :  </p>

<div class="code"><div class="codeContent">
<pre class="code-java">@Path(<span class="code-quote">"/customerservice/"</span>)
<span class="code-keyword">public</span> class CustomerService {

    @Path(<span class="code-quote">"/orders/{orderId}/"</span>)
    <span class="code-keyword">public</span> Order getOrder(@PathParam(<span class="code-quote">"orderId"</span>) <span class="code-object">String</span> orderId) {
       ......
    }
}

<span class="code-keyword">public</span> <span class="code-keyword">interface</span> Order {
    @GET
    @Path(<span class="code-quote">"products/{productId}/"</span>)
    Product getProduct(@PathParam(<span class="code-quote">"productId"</span>)<span class="code-object">int</span> productId);
}

@XmlRootElement(name = <span class="code-quote">"Order"</span>)
<span class="code-keyword">public</span> class OrderImpl <span class="code-keyword">implements</span> Order {
    
    @GET
    @Path(<span class="code-quote">"products/{productId}/"</span>)
    <span class="code-keyword">public</span> Product getProduct(@PathParam(<span class="code-quote">"productId"</span>)<span class="code-object">int</span> productId) {
       ......
    }
}</pre>
</div></div>


<h2><a name="JAX-RS%28JSR-311%29-MessageBodyProviders"></a>Message Body Providers</h2>

<p>JAX-RS relies on MessageBodyReader and MessageBodyWriter implementations to serialize and de-serialize Java types. JAX-RS requires that certain types has to be supported out of the box. <br/>
By default, CXF supports String, byte[], InputStream, Reader, File, JAXP Source, JAX-RS StreamingOutput, JAXB-annotated types with application/xml and application/json formats as well as JAXBElement (see below). JAX-RS MultivaluedMap is also supported for form contents. </p>

<h2><a name="JAX-RS%28JSR-311%29-CustomMessageBodyProviders"></a>Custom Message Body Providers          </h2>

<p>It's likely that a given application may need to deal with types which are not supported by default.<br/>
Alternatively, developers may want to provide a more efficient support for handling default types such as InputStream.</p>

<p>Here's an example of a custom MessageBodyReader for InputStream :</p>

<div class="code"><div class="codeContent">
<pre class="code-java">@ConsumeMime(<span class="code-quote">"application/octet-stream"</span>)
@Provider
<span class="code-keyword">public</span> class InputStreamProvider <span class="code-keyword">implements</span> MessageBodyReader&lt;InputStream&gt; {

    
    <span class="code-keyword">public</span> <span class="code-object">boolean</span> isReadable(<span class="code-object">Class</span>&lt;InputStream&gt; type, Type genericType, Annotation[] annotations) {
        <span class="code-keyword">return</span> InputStream.class.isAssignableFrom(type);
    }

    <span class="code-keyword">public</span> InputStream readFrom(<span class="code-object">Class</span>&lt;InputStream&gt; clazz, Type t, Annotation[] a, MediaType mt, 
                         MultivaluedMap&lt;<span class="code-object">String</span>, <span class="code-object">String</span>&gt; headers, InputStream is) 
        <span class="code-keyword">throws</span> IOException {
        <span class="code-keyword">return</span> <span class="code-keyword">new</span> FilterInputStream(is) {
             @Override
             <span class="code-keyword">public</span> <span class="code-object">int</span> read(<span class="code-object">byte</span>[] b) <span class="code-keyword">throws</span> IOException {
                 <span class="code-comment">// filter out some bytes
</span>             }              
        }     
    }
}</pre>
</div></div>

<p>and here's an example of a custom MessageBodyWriter for Long :</p>

<div class="code"><div class="codeContent">
<pre class="code-java">@ProduceMime(<span class="code-quote">"text/plain"</span>)
@Provider
<span class="code-keyword">public</span> class LongProvider <span class="code-keyword">implements</span> MessageBodyWriter&lt;<span class="code-object">Long</span>&gt; {

    <span class="code-keyword">public</span> <span class="code-object">long</span> getSize(<span class="code-object">Long</span> l) {
        <span class="code-keyword">return</span> -1;
    }

    <span class="code-keyword">public</span> <span class="code-object">boolean</span> isWriteable(<span class="code-object">Class</span>&lt;?&gt; type, Type genericType, Annotation[] annotations) {
        <span class="code-keyword">return</span> <span class="code-object">long</span>.class.isAssignableFrom(type) || <span class="code-object">Long</span>.class.isAssignableFrom(type);
    }

    <span class="code-keyword">public</span> void writeTo(<span class="code-object">Long</span> l, <span class="code-object">Class</span>&lt;?&gt; clazz, Type type, Annotation[] a, 
                        MediaType mt, MultivaluedMap&lt;<span class="code-object">String</span>, <span class="code-object">Object</span>&gt; headers, OutputStream os) 
        <span class="code-keyword">throws</span> IOException {
        os.write(l.toString().getBytes());
        
    }</pre>
</div></div>

<p>CXF ships some custom providers too. These are providers for dealing with Atom (based on Apache Abdera) and XMLObjects.<br/>
CXF also supports primitive types and their Number friends when text/plain media type is used, either on input or output.   </p>

<h3><a name="JAX-RS%28JSR-311%29-Registeringcustomproviders"></a>Registering custom providers  </h3>


<p>Putting @Provider annotation on the provider class is something that should lead to your provider being registered with the runtime. CXF does not support this feature yet. </p>


<p>One can easily register a provider either from the Spring configuration or programmatically :   </p>

<div class="code"><div class="codeContent">
<pre class="code-xml"><span class="code-tag">&lt;beans&gt;</span>
<span class="code-tag">&lt;jaxrs:server id=<span class="code-quote">"customerService"</span> address=<span class="code-quote">"/"</span>&gt;</span>
    <span class="code-tag">&lt;jaxrs:serviceBeans&gt;</span>
      <span class="code-tag">&lt;bean class=<span class="code-quote">"org.CustomerService"</span> /&gt;</span>
    <span class="code-tag">&lt;/jaxrs:serviceBeans&gt;</span>

    <span class="code-tag">&lt;jaxrs:providers&gt;</span>
      <span class="code-tag">&lt;bean ref=<span class="code-quote">"isProvider"</span> /&gt;</span>
      <span class="code-tag">&lt;bean ref=<span class="code-quote">"longProvider"</span> /&gt;</span>
    <span class="code-tag">&lt;/jaxrs:providers&gt;</span>
    <span class="code-tag">&lt;bean id=<span class="code-quote">"isProvider"</span> class=<span class="code-quote">"com.bar.providers.InputStreamProvider"</span>/&gt;</span>
    <span class="code-tag">&lt;bean id=<span class="code-quote">"longProvider"</span> class=<span class="code-quote">"com.bar.providers.LongProvider"</span>/&gt;</span>
<span class="code-tag">&lt;/jaxrs:server&gt;</span>
<span class="code-tag">&lt;/beans&gt;</span></pre>
</div></div>

<p>Note that instead of the older &lt;jaxrs:entityProviders&gt; it's now &lt;jaxrs:providers&gt;. JAX-RS supports different types of providers and having a single &lt;jaxrs:providers&gt; container is in line with the way other JAX-RS implementations discover providers by checking for @Provider annotations only. </p>

<p>See below a more complete beans.xml definition.</p>

<p>While having @Provider-annotated providers automatically registered is a handy feature indeed, sometimes it might actually be problematic.<br/>
For ex, in a large project user providers from different libraries might clash. Also, with a custom configuration (as shown above) a different type of provider (handling the same format of request/response bodies) can be registered with a different jaxrs:server instance.</p>

<h2><a name="JAX-RS%28JSR-311%29-Contenttypenegotiation"></a>Content type negotiation</h2>

<p>One of the coolest thing of REST is that the same resource can be served using multiple representations. @ProduceMime and @ConsumeMime annotations are used to declare the supported request and response media types. </p>


<h3><a name="JAX-RS%28JSR-311%29-JAXBsupport"></a>JAXB support</h3>

<p>The request and response can be marshalled and unmarshalled to/from Java object using JAXB. </p>

<p>There's a number of ways to tell to the JAXB provider how objects can be serialized. The simplest way is to mark a given type with @XmlRootElement annotation. </p>


<p>For example:</p>
<div class="code"><div class="codeContent">
<pre class="code-java">@XmlRootElement(name = <span class="code-quote">"Customer"</span>)
<span class="code-keyword">public</span> class Customer {
    <span class="code-keyword">private</span> <span class="code-object">String</span> name;
    <span class="code-keyword">private</span> <span class="code-object">long</span> id;

    <span class="code-keyword">public</span> Customer() {
    }

    <span class="code-keyword">public</span> void setName(<span class="code-object">String</span> n) {
        name = n;
    }

    <span class="code-keyword">public</span> <span class="code-object">String</span> getName() {
        <span class="code-keyword">return</span> name;
    }

    <span class="code-keyword">public</span> void setId(<span class="code-object">long</span> i) {
        id = i;
    }

    <span class="code-keyword">public</span> <span class="code-object">long</span> getId() {
        <span class="code-keyword">return</span> id;
    }
}</pre>
</div></div>
<p>In the example below, the Customer object returned by getCustomer is marshaled using JAXB data binding:</p>
<div class="code"><div class="codeContent">
<pre class="code-java">@Path(<span class="code-quote">"/customerservice/"</span>)
<span class="code-keyword">public</span> class CustomerService {
    @GET
    @Path(<span class="code-quote">"/customers/{customerId}/"</span>)
    <span class="code-keyword">public</span> Customer getCustomer(@PathParam(<span class="code-quote">"customerId"</span>) <span class="code-object">String</span> id) {
        ....
    }
}</pre>
</div></div>
<p>The wire representation of Customer object is:</p>
<div class="code"><div class="codeContent">
<pre class="code-java">@Path(<span class="code-quote">"/customerservice/"</span>)
&lt;Customer&gt;
    &lt;id&gt;123&lt;/id&gt;
    &lt;name&gt;John&lt;/name&gt;
&lt;/Customer&gt;</pre>
</div></div>

<p>The simplest way to work with the collections is to define a type representing a collection. For example:</p>

<div class="code"><div class="codeContent">
<pre class="code-java">@XmlRootElement(name = <span class="code-quote">"Customers"</span>)
<span class="code-keyword">public</span> class Customers {
    <span class="code-keyword">private</span> Collection&lt;Customer&gt; customers;

    <span class="code-keyword">public</span> Collection&lt;Customer&gt; getCustomer() {
        <span class="code-keyword">return</span> customers;
    }

    <span class="code-keyword">public</span> void setCustomer(Collection&lt;Customer&gt; c) {
        <span class="code-keyword">this</span>.customers = c;
    }
}
@Path(<span class="code-quote">"/customerservice/"</span>)
<span class="code-keyword">public</span> class CustomerService {
    @GET
    @Path(<span class="code-quote">"/customers/"</span>)
    <span class="code-keyword">public</span> Customers getCustomers() {
        ....
    }
}</pre>
</div></div>

<p>Alternatively to using @XmlRootElement and Collection wrappers, one can provide an Object factory which will tell JAXB how to <br/>
marshal a given type (in case of Collections - its template type). Another option is to return/accept a JAXBElement directly from/in <br/>
a given method.</p>

<p>Finally, JAXBProvider provides an experimental support for marshalling response types of methods annotated with @XmlJavaTypeAdapter annotations.<br/>
It's likely that at some point of time JAX-RS runtime will be capable of automatically generating such adapters.     </p>


<h3><a name="JAX-RS%28JSR-311%29-JSONsupport"></a>JSON support</h3>

<p>Default JSON provider relies on Jettison 1.0.1 and it expects the types it deals with to follow the same techniques as described above<br/>
in the JAXB support section for them to be handled properly. </p>

<p>Following code returns a Customer object that is marshaled to JSON format:</p>
<div class="code"><div class="codeContent">
<pre class="code-java">@Path(<span class="code-quote">"/customerservice/"</span>)
<span class="code-keyword">public</span> class CustomerService {
    @ProduceMime(<span class="code-quote">"application/json"</span>)
    @GET
    @Path(<span class="code-quote">"/customers/{customerId}/"</span>)
    <span class="code-keyword">public</span> Customer getCustomer(@PathParam(<span class="code-quote">"customerId"</span>) <span class="code-object">String</span> id) {
        ....
    }</pre>
</div></div>

<p>The wire representation of Customer object is:</p>
<div class="code"><div class="codeContent">
<pre class="code-java">{<span class="code-quote">"Customer "</span>:{<span class="code-quote">"id"</span>:<span class="code-quote">"123"</span>,<span class="code-quote">"name"</span>:<span class="code-quote">"john"</span>}}</pre>
</div></div>


<h3><a name="JAX-RS%28JSR-311%29-Sourcesupport"></a>Source support</h3>

<p>You can also receive the request as a Source object or return a Source object as response:</p>

<div class="code"><div class="codeContent">
<pre class="code-java">@Path(<span class="code-quote">"/customerservice/"</span>)
<span class="code-keyword">public</span> class CustomerService {
    @PUT
    @Path(<span class="code-quote">"/customers/"</span>)
    <span class="code-keyword">public</span> javax.xml.transform.Source updateCustomer(javax.xml.transform.Source ds) {
        ....
    }
}</pre>
</div></div>

<h2><a name="JAX-RS%28JSR-311%29-Debugging"></a>Debugging</h2>

<p>One can easily try from a browser how a given resource class reacts to different HTTP Accept or Accept-Language header values.<br/>
For example, if a resource class supports "/resource" URI then one can test the resource class using one of the following    <br/>
queries :</p>

<p>GET /resource.xml<br/>
GET /resource.en</p>

<p>The runtime will replace '.xml' or '.en' with an appropriate header value. For it to know the type or language value associated with <br/>
a given URI suffix, some configuration needs to be done. Here's an example how to do it in Spring :</p>

<div class="code"><div class="codeContent">
<pre class="code-xml"><span class="code-tag">&lt;jaxrs:server id=<span class="code-quote">"customerService"</span> address=<span class="code-quote">"/"</span>&gt;</span>
    <span class="code-tag">&lt;jaxrs:serviceBeans&gt;</span>
      <span class="code-tag">&lt;ref bean=<span class="code-quote">"customerService"</span> /&gt;</span>
    <span class="code-tag">&lt;/jaxrs:serviceBeans&gt;</span>
    <span class="code-tag">&lt;jaxrs:extensionMappings&gt;</span>
      <span class="code-tag">&lt;entry key=<span class="code-quote">"json"</span> value=<span class="code-quote">"application/json"</span>/&gt;</span>
      <span class="code-tag">&lt;entry key=<span class="code-quote">"xml"</span> value=<span class="code-quote">"application/xml"</span>/&gt;</span>
    <span class="code-tag">&lt;/jaxrs:extensionMappings&gt;</span>
    <span class="code-tag">&lt;jaxrs:languageMappings/&gt;</span>
  <span class="code-tag">&lt;/jaxrs:server&gt;</span></pre>
</div></div>

<p>See below for a more complete configuration example.</p>

<p>See the JAX-RS specification for more details.</p>

<p>CXF also supports _type query as an alternative to appending extensions like '.xml' to request URIs :</p>

<p>GET /resource?_type=xml </p>

<h2><a name="JAX-RS%28JSR-311%29-Filters"></a>Filters</h2>

<p>CXF suports filters. Often it's necessary to pre- or post-process some requests according to a number of requirements.<br/>
For example, a request like </p>

<p>GET /resource?_type=xml is supported by a CXF specific RequestHandler filter which modifices the CXF input Message <br/>
by updating one of its headers.</p>

<p>In some cases users can use the existing filter technologies such as Servler filters or Spring AOP proxies. In other cases, it can be handy<br/>
to write a CXF filter which will introspect the resource class, input or output message, the operation which was invoked and modify the request or response accordingly. </p>

<p>Note that the corresponding interfaces will most likely change in the short term. Here they are anyway, the implementations can be registered like any other types of providers.</p>

<div class="code"><div class="codeContent">
<pre class="code-java"><span class="code-keyword">public</span> <span class="code-keyword">interface</span> RequestHandler {
    
    Response handleRequest(Message inputMessage, 
                           ClassResourceInfo resourceClass);

}</pre>
</div></div>

<p>The request handler implementation can either modify the input Message and let the request to proceed or block the request <br/>
by returning a non-null Response. </p>

<div class="code"><div class="codeContent">
<pre class="code-java"><span class="code-keyword">public</span> <span class="code-keyword">interface</span> ResponseHandler {
    
    Response handleResponse(Message outputMessage,
                           OperationResourceInfo invokedOperation, 
                           Response response);

}</pre>
</div></div>

<p>The response handler implementation can optionally overwrite or modify the application Response.<br/>
Multiple request and response handlers are supported.</p>

<h2><a name="JAX-RS%28JSR-311%29-AdvancedHTTP"></a>Advanced HTTP</h2>

<p>CXF provides a partial support for an advanced content type negotiation by handling If-Match headers and ETags in its JAX-RS Request implementation. Neither If-Modified-Since nor Vary headers are currently supported.</p>

<p>It also supports CacheControl and Cookies.</p>

<h2><a name="JAX-RS%28JSR-311%29-SecureJAXRSservices"></a>Secure JAX-RS services</h2>

<p>A demo called samples\jax_rs\basic_https shows you how to do communications using HTTPS.</p>

<h1><a name="JAX-RS%28JSR-311%29-ConfiguringJAXRSservices"></a>Configuring JAX-RS services</h1>


<h2><a name="JAX-RS%28JSR-311%29-ConfiguringJAXRSservicesprogrammatically"></a>Configuring JAX-RS services programmatically</h2>

<p>You can create a JAX-RS RESTful service by using <span class="nobr"><a href="http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServerFactoryBean.java?view=markup&amp;pathrev=HEAD" title="Visit page outside Confluence" rel="nofollow">JAXRSServerFactoryBean<sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span> from the <em>cxf-rt-frontend-jaxrs</em> package: </p>
<div class="code"><div class="codeContent">
<pre class="code-java">JAXRSServerFactoryBean sf = <span class="code-keyword">new</span> JAXRSServerFactoryBean();
sf.setResourceClasses(CustomerService.class);
sf.setAddress(<span class="code-quote">"http:<span class="code-comment">//localhost:9000/"</span>);
</span>sf.create();</pre>
</div></div>
<p>A couple things to note:</p>
<ul>
	<li>The JAXRSServerFactoryBean creates a Server inside CXF which starts listening for requests on the URL specified.</li>
	<li>By default, the JAX-RS runtime is responsible for the lifecycle of resource classes, default lifecycle is per-request. You can set the lifecycle to singleton by using following line:
<div class="code"><div class="codeContent">
<pre class="code-java">sf.setResourceProvider(BookStore.class, <span class="code-keyword">new</span> SingletonResourceProvider());</pre>
</div></div></li>
	<li>If you prefer not to let the JAX-RS runtime to handle the resource class lifecycle for you (for example, it might be the case that your resource class is created by other containers such as Spring), you can do following:
<div class="code"><div class="codeContent">
<pre class="code-java">JAXRSServerFactoryBean sf = <span class="code-keyword">new</span> JAXRSServerFactoryBean();
CustomerService cs = <span class="code-keyword">new</span> CustomerService();
sf.setServiceBeans(cs);
sf.setAddress(<span class="code-quote">"http:<span class="code-comment">//localhost:9080/"</span>);
</span>sf.create();</pre>
</div></div></li>
</ul>


<h2><a name="JAX-RS%28JSR-311%29-ConfiguringJAXRSservicesincontainerwithSpringconfigurationfile."></a>Configuring JAX-RS services in container with Spring configuration file.</h2>


<h3><a name="JAX-RS%28JSR-311%29-web.xml"></a>web.xml</h3>

<div class="code"><div class="codeContent">
<pre class="code-xml"><span class="code-tag">&lt;?xml version=<span class="code-quote">"1.0"</span> encoding=<span class="code-quote">"ISO-8859-1"</span>?&gt;</span>

&lt;!DOCTYPE web-app
    PUBLIC <span class="code-quote">"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"</span>
    <span class="code-quote">"http://java.sun.com/dtd/web-app_2_3.dtd"</span>&gt;
<span class="code-tag">&lt;web-app&gt;</span>
	<span class="code-tag">&lt;context-param&gt;</span>
		<span class="code-tag">&lt;param-name&gt;</span>contextConfigLocation<span class="code-tag">&lt;/param-name&gt;</span>
		<span class="code-tag">&lt;param-value&gt;</span>WEB-INF/beans.xml<span class="code-tag">&lt;/param-value&gt;</span>
	<span class="code-tag">&lt;/context-param&gt;</span>

	<span class="code-tag">&lt;listener&gt;</span>
		<span class="code-tag">&lt;listener-class&gt;</span>
			org.springframework.web.context.ContextLoaderListener
		<span class="code-tag">&lt;/listener-class&gt;</span>
	<span class="code-tag">&lt;/listener&gt;</span>

	<span class="code-tag">&lt;servlet&gt;</span>
		<span class="code-tag">&lt;servlet-name&gt;</span>CXFServlet<span class="code-tag">&lt;/servlet-name&gt;</span>
		<span class="code-tag">&lt;display-name&gt;</span>CXF Servlet<span class="code-tag">&lt;/display-name&gt;</span>
		<span class="code-tag">&lt;servlet-class&gt;</span>
			org.apache.cxf.transport.servlet.CXFServlet
		<span class="code-tag">&lt;/servlet-class&gt;</span>
		<span class="code-tag">&lt;load-on-startup&gt;</span>1<span class="code-tag">&lt;/load-on-startup&gt;</span>
	<span class="code-tag">&lt;/servlet&gt;</span>

	<span class="code-tag">&lt;servlet-mapping&gt;</span>
		<span class="code-tag">&lt;servlet-name&gt;</span>CXFServlet<span class="code-tag">&lt;/servlet-name&gt;</span>
		<span class="code-tag">&lt;url-pattern&gt;</span>/*<span class="code-tag">&lt;/url-pattern&gt;</span>
	<span class="code-tag">&lt;/servlet-mapping&gt;</span>
<span class="code-tag">&lt;/web-app&gt;</span></pre>
</div></div>

<h3><a name="JAX-RS%28JSR-311%29-beans.xml"></a>beans.xml</h3>

<div class="code"><div class="codeContent">
<pre class="code-xml"><span class="code-tag">&lt;?xml version=<span class="code-quote">"1.0"</span> encoding=<span class="code-quote">"UTF-8"</span>?&gt;</span>
&lt;beans xmlns=<span class="code-quote">"http://www.springframework.org/schema/beans"</span>
  <span class="code-keyword">xmlns:xsi</span>=<span class="code-quote">"http://www.w3.org/2001/XMLSchema-instance"</span>
  <span class="code-keyword">xmlns:jaxrs</span>=<span class="code-quote">"http://cxf.apache.org/jaxrs"</span>
  xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd"&gt;

  <span class="code-tag">&lt;import resource=<span class="code-quote">"classpath:META-INF/cxf/cxf.xml"</span> /&gt;</span>
  <span class="code-tag">&lt;import resource=<span class="code-quote">"classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml"</span> /&gt;</span>
  <span class="code-tag">&lt;import resource=<span class="code-quote">"classpath:META-INF/cxf/cxf-servlet.xml"</span> /&gt;</span>

  <span class="code-tag">&lt;jaxrs:server id=<span class="code-quote">"customerService"</span> address=<span class="code-quote">"/"</span>&gt;</span>
    <span class="code-tag">&lt;jaxrs:serviceBeans&gt;</span>
      <span class="code-tag">&lt;ref bean=<span class="code-quote">"customerService"</span> /&gt;</span>
    <span class="code-tag">&lt;/jaxrs:serviceBeans&gt;</span>
  <span class="code-tag">&lt;/jaxrs:server&gt;</span>

  <span class="code-tag">&lt;bean id=<span class="code-quote">"customerService"</span> class=<span class="code-quote">"demo.jaxrs.server.CustomerService"</span> /&gt;</span>
<span class="code-tag">&lt;/beans&gt;</span></pre>
</div></div>


<h2><a name="JAX-RS%28JSR-311%29-CombiningJAXWSandJAXRS"></a>Combining JAX-WS and JAX-RS</h2>

<p>Here's a beans.xml showing how to have a single service class supporting both SOAP and REST-based invocations at the same time with the help of JAX-WS and JAX-RS : </p>

<div class="code"><div class="codeContent">
<pre class="code-xml"><span class="code-tag">&lt;?xml version=<span class="code-quote">"1.0"</span> encoding=<span class="code-quote">"UTF-8"</span>?&gt;</span>
&lt;beans xmlns=<span class="code-quote">"http://www.springframework.org/schema/beans"</span>
  <span class="code-keyword">xmlns:xsi</span>=<span class="code-quote">"http://www.w3.org/2001/XMLSchema-instance"</span>
  <span class="code-keyword">xmlns:jaxrs</span>=<span class="code-quote">"http://cxf.apache.org/jaxrs"</span>
  <span class="code-keyword">xmlns:jaxws</span>=<span class="code-quote">"http://cxf.apache.org/jaxws"</span>
  xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd"&gt;

  <span class="code-tag">&lt;import resource=<span class="code-quote">"classpath:META-INF/cxf/cxf.xml"</span> /&gt;</span>
  <span class="code-tag">&lt;import resource=<span class="code-quote">"classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml"</span> /&gt;</span>
  <span class="code-tag">&lt;import resource=<span class="code-quote">"classpath:META-INF/cxf/cxf-servlet.xml"</span> /&gt;</span>

  <span class="code-tag"><span class="code-comment">&lt;!-- JAX-RS --&gt;</span></span>
  <span class="code-tag">&lt;jaxrs:server id=<span class="code-quote">"customerService"</span> address=<span class="code-quote">"/"</span>&gt;</span>
    <span class="code-tag">&lt;jaxrs:serviceBeans&gt;</span>
      <span class="code-tag">&lt;ref bean=<span class="code-quote">"customerService"</span> /&gt;</span>
    <span class="code-tag">&lt;/jaxrs:serviceBeans&gt;</span>
  <span class="code-tag">&lt;/jaxrs:server&gt;</span>

  <span class="code-tag"><span class="code-comment">&lt;!-- JAX-WS --&gt;</span></span>
  &lt;jaxws:endpoint implementor=<span class="code-quote">"#customerService"</span>
    address=<span class="code-quote">"/CustomerWorld"</span> wsdlLocation=<span class="code-quote">"..."</span>/&gt;
  
  <span class="code-tag">&lt;bean id=<span class="code-quote">"customerService"</span> class=<span class="code-quote">"demo.jaxrs.server.CustomerService"</span> /&gt;</span>
<span class="code-tag">&lt;/beans&gt;</span></pre>
</div></div>

<p>Either contract-first or Java-first approach can be used for JAX-WS. JAX-RS annotations can be added to the existing service class. Some custom providers may need to be created, depending on the complexity of the method signatures.</p>

<p>When a WSDL-first approach is used then a document-literal-wrapped style may or may not be a good fit as the code generator unwraps all the types into a signature, for example :</p>

<div class="code"><div class="codeContent">
<pre class="code-java"><span class="code-keyword">public</span> class CustomerService {
   void doIt(<span class="code-object">String</span> a, <span class="code-object">String</span> b) {...};
}</pre>
</div></div>  

<p>By default JAX-RS may not be able to handle such methods as it requires that only a single parameter can be available in a signature that is not annotated by one of the JAX-RS annotations like @PathParam. So if <br/>
a 'String a' parameter can be mapped to a @Path template variable or one of the query segments then this signature won't need to be changed :</p>

<div class="code"><div class="codeContent">
<pre class="code-java">@Path(<span class="code-quote">"/customers/{a}"</span>)
<span class="code-keyword">public</span> class CustomerService {
   void doIt(@PathParam(<span class="code-quote">"a"</span>) <span class="code-object">String</span> a, <span class="code-object">String</span> b) {...};
}</pre>
</div></div>  

<p>For methods returning 'void', a simple custom provider can be created which will basically be a no-op implementation. </p>

<h2><a name="JAX-RS%28JSR-311%29-JAXRSandSpringAOP"></a>JAX-RS and Spring AOP</h2>

<p>CXF JAX-RS is capable of working with AOP interceptors applied to resource classes from Spring.<br/>
For example :</p>

<div class="code"><div class="codeContent">
<pre class="code-xml"><span class="code-tag">&lt;beans xsi:schemaLocation=<span class="code-quote">" http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop  http://www.springframework.org/schema/aop/spring-aop.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd"</span>&gt;</span>
<span class="code-tag">&lt;import resource=<span class="code-quote">"classpath:META-INF/cxf/cxf.xml"</span>/&gt;</span>
<span class="code-tag">&lt;import resource=<span class="code-quote">"classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml"</span>/&gt;</span>
<span class="code-tag">&lt;import resource=<span class="code-quote">"classpath:META-INF/cxf/cxf-servlet.xml"</span>/&gt;</span>

  <span class="code-tag">&lt;jaxrs:server id=<span class="code-quote">"bookservice"</span> address=<span class="code-quote">"/"</span>&gt;</span>
	<span class="code-tag">&lt;jaxrs:serviceBeans&gt;</span>
          <span class="code-tag">&lt;ref bean=<span class="code-quote">"bookstore"</span>/&gt;</span>
          <span class="code-tag">&lt;ref bean=<span class="code-quote">"bookstoreInterface"</span>/&gt;</span>
        <span class="code-tag">&lt;/jaxrs:serviceBeans&gt;</span>
   <span class="code-tag">&lt;/jaxrs:server&gt;</span>
   <span class="code-tag">&lt;bean id=<span class="code-quote">"bookstore"</span> class=<span class="code-quote">"org.apache.cxf.systest.jaxrs.BookStore"</span>/&gt;</span>
   <span class="code-tag">&lt;bean id=<span class="code-quote">"bookstoreInterface"</span> class=<span class="code-quote">"org.apache.cxf.systest.jaxrs.BookStoreWithInterface"</span>/&gt;</span>

   <span class="code-tag">&lt;aop:config&gt;</span>
	<span class="code-tag">&lt;aop:aspect id=<span class="code-quote">"loggingAspect"</span> ref=<span class="code-quote">"simpleLogger"</span>&gt;</span>
          <span class="code-tag">&lt;aop:before method=<span class="code-quote">"logBefore"</span> pointcut=<span class="code-quote">"execution(* org.apache.cxf.systest.jaxrs.BookStore*.*(..))"</span>/&gt;</span>
          <span class="code-tag">&lt;aop:after-returning method=<span class="code-quote">"logAfter"</span> pointcut=<span class="code-quote">"execution(* org.apache.cxf.systest.jaxrs.BookStore*.*(..))"</span>/&gt;</span>
        <span class="code-tag">&lt;/aop:aspect&gt;</span>
   <span class="code-tag">&lt;/aop:config&gt;</span>
   <span class="code-tag">&lt;bean id=<span class="code-quote">"simpleLogger"</span> class=<span class="code-quote">"org.apache.cxf.systest.jaxrs.SimpleLoggingAspect"</span>/&gt;</span>
<span class="code-tag">&lt;/beans&gt;</span></pre>
</div></div> 

<p>Note that some AOP configuration is applied to two JAX-RS resource classes. By default Spring uses JDK dynamic proxies every time a class to be proxified implements at least one interface or CGLIB proxies otherwise. </p>

<p>For example, here's how org.apache.cxf.systest.jaxrs.BookStoreWithInterface looks like : </p>

<div class="code"><div class="codeContent">
<pre class="code-java"><span class="code-keyword">public</span> <span class="code-keyword">interface</span> BookInterface {
    @GET
    @Path(<span class="code-quote">"/thosebooks/{bookId}/"</span>)
    @ProduceMime(<span class="code-quote">"application/xml"</span>)
    Book getThatBook(<span class="code-object">Long</span> id) <span class="code-keyword">throws</span> BookNotFoundFault;
}

<span class="code-keyword">public</span> class BookStoreWithInterface <span class="code-keyword">extends</span> BookStoreStorage <span class="code-keyword">implements</span> BookInterface {

    <span class="code-keyword">public</span> Book getThatBook(@PathParam(<span class="code-quote">"bookId"</span>) <span class="code-object">Long</span> id) <span class="code-keyword">throws</span> BookNotFoundFault {
        <span class="code-keyword">return</span> doGetBook(id);
    }

    @Path(<span class="code-quote">"/thebook"</span>)
    <span class="code-keyword">public</span> Book getTheBook(@PathParam(<span class="code-quote">"bookId"</span>) <span class="code-object">Long</span> id) <span class="code-keyword">throws</span> BookNotFoundFault {
        <span class="code-keyword">return</span> doGetBook(id);
    }
}</pre>
</div></div>

<p>In this case Spring will use a JDK proxy to wrap a BookStoreWithInterface class. As such it is important that a method which needs to be invoked such as getThatBook(...) is part of the interface. </p>

<p>The other method, getTheBook() can not be dispatched to by a JAX-RS runtime as it's not possible to discover it through a JDK proxy. If this method also needs to be invoked then this method should either be added to the interface or CGLIB proxies have to be explicitly enabled (consult Spring AOP documentation for more details) </p>

<h2><a name="JAX-RS%28JSR-311%29-AreasforimprovementandTODOlist."></a>Areas for improvement and TODO list.</h2>

<p>TODO : link to JIRAs !</p>

<p> Get rid of a billion of @SuppressWarning<br/>
 Try to decrease the amount of static code<br/>
 Add more tests</p>


<p> Complete the implementation of JAX-RS UriInfo (latest methods to do with the ancestor resources) and in particularly of UriBuilder<br/>
 Complete the implementation of JAX-RS Request (If-Modified-Since, Vary) and ResponseBuilder(Vary)<br/>
 Support Constructor-based injection<br/>
 ASM-generate XmlJavaTypeAdapters when needed<br/>
 Provide AegisBindingProvider<br/>
 Provide JAXP-Source provider capable of applying preconfigured XSLT templates or XPath expressions<br/>
 Proper HTTP status handling in various cases as per the spec<br/>
 Support of @Encoded on a method (class and parameter targets supported)<br/>
 Support of encoded @Path values<br/>
 Support for inheritance of @PathParam and @Context annotations from interface/superclass methods    <br/>
 Investigate the possibility of creating a client-side api using JAXRSClientFactory</p>







</div>


</td></tr></table></div>
<p>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td height="12" background="http://cwiki.apache.org/confluence/images/border/border_bottom.gif"><img src="http://cwiki.apache.org/confluence/images/border/spacer.gif" width="1" height="1" border="0"/></td>
    </tr>
</table>

<div class="smalltext">
    Powered by
    <a href="http://www.atlassian.com/software/confluence/default.jsp?clicked=footer" class="smalltext">Atlassian Confluence</a>
    (Version: 2.2.9 Build:#527 Sep 07, 2006)
    -
    <a href="http://jira.atlassian.com/secure/BrowseProject.jspa?id=10470" class="smalltext">Bug/feature request</a><br/>
    <br>
    <a href="http://cwiki.apache.org/confluence/users/viewnotifications.action">Unsubscribe or edit your notifications preferences</a>

</div>

</body>
</html>


Mime
View raw message