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 (page edited)
Date Sun, 10 May 2009 17:39: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">JAX-RS</a>
        </span>
    </div>

     <p>
        <a href="http://cwiki.apache.org/confluence/display/CXF20DOC/JAX-RS">JAX-RS</a>
        has been edited by             <a href="http://cwiki.apache.org/confluence/display/~sergey_beryozkin">Sergey Beryozkin</a>
            <span class="smallfont">(May 10, 2009)</span>.
     </p>
    
     <p>
                 <a href="http://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=70366&originalVersion=77&revisedVersion=78">(View changes)</a>
     </p>

    <span class="label">Content:</span><br/>
    <div class="greybox wiki-content"><span style="font-size:2em;font-weight:bold"> JAX-RS (JSR-311) </span>

<div>
<ul>
  <li><a href='#JAX-RS-Introduction'>Introduction</a></li>
  <li><a href='#JAX-RS-Migratingfrom0.8to1.0'>Migrating from 0.8 to 1.0</a></li>
  <li><a href='#JAX-RS-Mavendependencies'>Maven dependencies</a></li>
  <li><a href='#JAX-RS-CXFJAXRSbundle'>CXF JAX-RS bundle</a></li>
  <li><a href='#JAX-RS-Understandingthebasics'>Understanding the basics</a>
<ul>
  <li><a href='#JAX-RS-Resourceclass'>Resource class</a></li>
  <li><a href='#JAX-RS-@Path'>@Path</a></li>
  <li><a href='#JAX-RS-HTTPMethod'>HTTP Method</a></li>
  <li><a href='#JAX-RS-Returntypes'>Return types</a>
<ul>
  <li><a href='#JAX-RS-Exceptionhandling'>Exception handling</a></li>
</ul></li>
  <li><a href='#JAX-RS-DealingwithParameters'>Dealing with Parameters</a>
<ul>
  <li><a href='#JAX-RS-Parameterbeans'>Parameter beans</a></li>
</ul></li>
  <li><a href='#JAX-RS-Resourcelifecycle'>Resource life-cycle</a></li>
  <li><a href='#JAX-RS-Overviewoftheselectionalgorithm.'>Overview of the selection algorithm.</a>
<ul>
  <li><a href='#JAX-RS-Selectingbetweenmultipleresourceclasses'>Selecting between multiple resource classes</a></li>
  <li><a href='#JAX-RS-Selectingbetweenmultipleresourcemethods'>Selecting between multiple resource methods</a></li>
  <li><a href='#JAX-RS-Resourcemethodsandmediatypes'>Resource methods and media types</a></li>
</ul></li>
  <li><a href='#JAX-RS-Contextannotations'>Context annotations</a>
<ul>
  <li><a href='#JAX-RS-URIscalculationusingUriInfoandUriBuilder'>URIs calculation using UriInfo and UriBuilder</a></li>
</ul></li>
  <li><a href='#JAX-RS-Annotationinheritance'>Annotation inheritance</a></li>
  <li><a href='#JAX-RS-Subresourcelocators.'>Sub-resource locators.</a>
<ul>
  <li><a href='#JAX-RS-Staticresolutionofsubresources'>Static resolution of subresources</a></li>
</ul></li>
  <li><a href='#JAX-RS-MessageBodyProviders'>Message Body Providers</a>
<ul>
  <li><a href='#JAX-RS-CustomMessageBodyProviders'>Custom Message Body Providers          </a></li>
  <li><a href='#JAX-RS-Registeringcustomproviders'>Registering custom providers  </a></li>
</ul></li>
  <li><a href='#JAX-RS-Customizingmediatypesformessagebodyproviders'>Customizing media types for message body providers</a></li>
  <li><a href='#JAX-RS-Supportfordatabindings'>Support for data bindings</a>
<ul>
  <li><a href='#JAX-RS-JAXBsupport'>JAXB support</a>
<ul>
  <li><a href='#JAX-RS-ConfiguringJAXBprovider'>Configuring JAXB provider</a></li>
</ul></li>
  <li><a href='#JAX-RS-JSONsupport'>JSON support</a>
<ul>
  <li><a href='#JAX-RS-ConfiguringJSONprovider'>Configuring JSON provider</a></li>
  <li><a href='#JAX-RS-DealingwithJSONarrayserializationissues'>Dealing with JSON array serialization issues </a></li>
</ul></li>
  <li><a href='#JAX-RS-AegisDataBinding'>Aegis Data Binding</a></li>
  <li><a href='#JAX-RS-XMLBeans'>XMLBeans</a></li>
</ul></li>
  <li><a href='#JAX-RS-Schemavalidationsupport'>Schema validation support</a></li>
  <li><a href='#JAX-RS-Contenttypenegotiation'>Content type negotiation</a></li>
  <li><a href='#JAX-RS-Debugging'>Debugging</a></li>
  <li><a href='#JAX-RS-Logging'>Logging</a></li>
  <li><a href='#JAX-RS-Filters'>Filters</a>
<ul>
  <li><a href='#JAX-RS-DifferencebetweenJAXRSfiltersandCXFinterceptors'>Difference between JAXRS filters and CXF interceptors</a></li>
</ul></li>
  <li><a href='#JAX-RS-Custominvokers'>Custom invokers</a></li>
  <li><a href='#JAX-RS-AdvancedHTTP'>Advanced HTTP</a></li>
  <li><a href='#JAX-RS-SupportforContinuations'>Support for Continuations </a></li>
  <li><a href='#JAX-RS-SecureJAXRSservices'>Secure JAX-RS services</a></li>
  <li><a href='#JAX-RS-SecurityManagerandIllegalAccessExceptions'>SecurityManager and IllegalAccessExceptions</a></li>
</ul></li>
  <li><a href='#JAX-RS-ConfiguringJAXRSservices'>Configuring JAX-RS services</a>
<ul>
  <li><a href='#JAX-RS-ConfiguringJAXRSservicesprogrammatically'>Configuring JAX-RS services programmatically</a></li>
  <li><a href='#JAX-RS-ClientAPI'>Client API</a>
<ul>
  <li><a href='#JAX-RS-ProxybasedAPI'>Proxy-based API</a>
<ul>
  <li><a href='#JAX-RS-Customizingproxies'>Customizing proxies </a></li>
  <li><a href='#JAX-RS-Handlingexceptions'>Handling exceptions</a></li>
  <li><a href='#JAX-RS-ConvertingtoHTTPcentricclients'>Converting to HTTP-centric clients</a></li>
</ul></li>
</ul></li>
  <li><a href='#JAX-RS-HTTPcentricclients'>HTTP-centric clients</a>
<ul>
  <li>
<ul>
  <li><a href='#JAX-RS-Convertingtoproxies'>Converting to proxies</a></li>
</ul></li>
</ul></li>
  <li><a href='#JAX-RS-XMLcentricclients'>XML-centric clients</a></li>
  <li><a href='#JAX-RS-ConfiguringJAXRSservicesincontainerwithSpringconfigurationfile.'>Configuring JAX-RS services in container with Spring configuration file.</a>
<ul>
  <li><a href='#JAX-RS-web.xml'>web.xml</a>
<ul>
  <li><a href='#JAX-RS-UsingSpringContextLoaderListener'>Using Spring ContextLoaderListener</a></li>
  <li><a href='#JAX-RS-UsingCXFServletinitparameters'>Using CXFServlet init parameters </a></li>
</ul></li>
  <li><a href='#JAX-RS-beans.xml'>beans.xml</a></li>
</ul></li>
  <li><a href='#JAX-RS-RegisteringendpointswithoutSpring'>Registering endpoints without Spring</a></li>
  <li><a href='#JAX-RS-Multipleendpointsandresourceclasses'>Multiple endpoints and resource classes</a></li>
  <li><a href='#JAX-RS-HowtherequestURIismatchedagainstagivenjaxrsendpoint'>How the request URI is matched against a given jaxrs endpoint</a></li>
  <li><a href='#JAX-RS-CombiningJAXWSandJAXRS'>Combining JAX-WS and JAX-RS</a>
<ul>
  <li><a href='#JAX-RS-Dealingwithcontexts'>Dealing with contexts</a></li>
</ul></li>
  <li><a href='#JAX-RS-JAXRSandSpringAOP'>JAX-RS and Spring AOP</a></li>
  <li><a href='#JAX-RS-AreasforimprovementandTODOlist.'>Areas for improvement and TODO list.</a>
<ul>
  <li><a href='#JAX-RS-Howtocontribute'>How to contribute</a></li>
</ul></li>
</ul></li>
</ul></div>

<h1><a name="JAX-RS-Introduction"></a>Introduction</h1>

<p>CXF supports JAX-RS (JSR-311), Java API for RESTful Web Services. JAX-RS provides a more standard way to build RESTful services in Java. CXF 2.2.x supports the <span class="nobr"><a href="https://jsr311.dev.java.net/nonav/releases/1.0/index.html" title="Visit page outside Confluence" rel="nofollow">final 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> while CXF 2.1.x currently supports the <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>. </p>

<p>JAX-RS related demos are located under samples/jax_rs directory (CXF 2.2 and CXF 2.1 only).<br/>
This documentation will refer to <span class="nobr"><a href="https://jsr311.dev.java.net/nonav/releases/1.0/index.html" title="Visit page outside Confluence" rel="nofollow">JSR-311 API 1.0 <sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span>.</p>

<h1><a name="JAX-RS-Migratingfrom0.8to1.0"></a>Migrating from 0.8 to 1.0</h1>

<p>The following major changes in 1.0 will most likely affect users migrating from 0.8</p>

<ul class="alternate" type="square">
	<li>@ProduceMime and @ConsumeMime have been replaced with @Produces and @Consumes respectively</li>
	<li>HttpHeaders has had some of its methods returning a string representation of Locale updated to return Locale instead</li>
</ul>


<p>Note that all the fixes applied to the JAX-RS implementation in the trunk will be available for users of 0.8 api, with the exception of 1.0 api specific fixes.</p>

<p>As JAX-RS API 1.0 is currently supported in CXF 2.2.x, it's also worth noting of the following changes in dependencies :</p>

<ul class="alternate" type="square">
	<li>Spring version have changed from 2.0.8 in 2.1.x to 2.5.6</li>
	<li>jaxb-api version has changed to javax.xml.bind/jaxb-api/2.1</li>
	<li>jaxb-impl version has changed to com.sun.xml.bind/jaxb-impl/2.1.7</li>
</ul>


<p>Additionally, org.apache.cxf/cxf-rt-databinding-aegis/2.2.x compile-time dependency has been added</p>

<h1><a name="JAX-RS-Mavendependencies"></a>Maven dependencies</h1>
<p><span class="nobr"><a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/pom.xml" title="Visit page outside Confluence" rel="nofollow">The following 3rd-party dependencies<sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span> are used when building CXF JAX-RS implementation :</p>

<p>1. javax.ws.rs/jsr311-api/1.0</p>

<p>available from either </p>
<div class="code"><div class="codeContent">
<pre class="code-xml"><span class="code-tag">&lt;repository&gt;</span>
            <span class="code-tag">&lt;id&gt;</span>java.net.2<span class="code-tag">&lt;/id&gt;</span>
            <span class="code-tag">&lt;name&gt;</span>Java Net 2 Repository<span class="code-tag">&lt;/name&gt;</span>
            <span class="code-tag">&lt;url&gt;</span>http://download.java.net/maven/2<span class="code-tag">&lt;/url&gt;</span>
<span class="code-tag">&lt;/repository&gt;</span></pre>
</div></div>

<p>or from a central maven repository</p>

<p>2. org.apache.abdera groupId : abdera-core, abdera-parser and abdera-extensions-json artifacts, version 0.4.0-incubating. It's a compile time dependency. Available from </p>

<div class="code"><div class="codeContent">
<pre class="code-xml"><span class="code-tag">&lt;repository&gt;</span>
<span class="code-tag">&lt;id&gt;</span>apache.incubating<span class="code-tag">&lt;/id&gt;</span>
<span class="code-tag">&lt;name&gt;</span>Apache Incubating Repository<span class="code-tag">&lt;/name&gt;</span>
<span class="code-tag">&lt;url&gt;</span>http://people.apache.org/repo/m2-incubating-repository<span class="code-tag">&lt;/url&gt;</span>
<span class="code-tag">&lt;/repository&gt;</span></pre>
</div></div>

<p>3. org.springframework/spring-core/2.5.6</p>

<p>4. org.codehaus.jettison/jettison/1.0.1</p>

<p>5. org.apache.xmlbeans/xmlbeans/2.3.0 - compile time</p>

<p>Please check <span class="nobr"><a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/pom.xml" title="Visit page outside Confluence" rel="nofollow">the pom.xml<sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span> for the list of cxf components used by the JAX-RS implementation. Snapshots are available from <span class="nobr"><a href="http://repository.apache.org/snapshots/org/apache/cxf/apache-cxf/" title="Visit page outside Confluence" rel="nofollow">http://repository.apache.org/snapshots/org/apache/cxf/apache-cxf/<sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span></p>


<h1><a name="JAX-RS-CXFJAXRSbundle"></a>CXF JAX-RS bundle</h1>

<p>A standalone <span class="nobr"><a href="http://svn.apache.org/repos/asf/cxf/trunk/distribution/bundle/jaxrs/pom.xml" title="Visit page outside Confluence" rel="nofollow">JAX-RS bundle<sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span> is now available which may be of interest to users doing JAX-RS work only.</p>

<h1><a name="JAX-RS-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-Resourceclass"></a>Resource class</h2>

<p>A resource class is a Java class annotated with JAX-RS annotations to represent a Web resource. Two types of resource classes are available : root resource classes and subresource classes. A root resource class is annotated at least with a @Path annotation, while subresource classes typically have no root @Path values. A typical root 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.Path;
<span class="code-keyword">import</span> javax.ws.rs.PathParam;
<span class="code-keyword">import</span> javax.ws.rs.Produces;
<span class="code-keyword">import</span> javax.ws.rs.core.Response;

@Path(<span class="code-quote">"/customerservice/"</span>)
@Produces(<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>)
    @Produces(<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>)
    @Consumes(<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>&#64;Produces annotation is used to specify the format of the response. When not available on the resource 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 &#64;Consumes, only it's message body readers that are checked as the last resort.</p>

<p>For example, getCustomers() method inherits &#64;Produces annotation from its class, while getCustomer() method overrides it with its own value.  </p>

<h2><a name="JAX-RS-@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 and may include arbitrary regular expressions. When not available on the resource method, it's inherited from a class. For example :</p>

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

    @GET
    <span class="code-keyword">public</span> Customer getCustomer(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">Long</span> id) {
        ......
    }

    @GET
    @Path(<span class="code-quote">"/order/{orderid}"</span>)
    <span class="code-keyword">public</span> Order getOrder(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">Long</span> customerId, @PathParam(<span class="code-quote">"orderid"</span>) <span class="code-object">Long</span> orderId) {
        ......
    }

    @GET
    @Path(<span class="code-quote">"/order/{orderid}/{search:.*}"</span>)
    <span class="code-keyword">public</span> Item findItem(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">Long</span> customerId, 
                         @PathParam(<span class="code-quote">"orderid"</span>) <span class="code-object">Long</span> orderId,
                         @PathParam(<span class="code-quote">"search"</span>) <span class="code-object">String</span> searchString,
                         @PathParam(<span class="code-quote">"search"</span>) List&lt;PathSegment&gt; searchList) {
        ......
    }
}</pre>
</div></div> 

<p>This example is similar to the one above it, but it also shows that an {id} template variable specified as part of the root &#64;Path expression is reused by resource methods and a custom regular expression is specified by a findItem() method (note that a variable name is separated by ':' from an actual expression).</p>

<p>In this example, a request like 'GET /customers/1/order/2/price/2000/weight/2' will be served by the findItem() method.<br/>
List&lt;PathSegment&gt; can be used to get to all the path segments in 'price/2000/weight/2' captured by the regular expression.</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-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. For example :</p>

<div class="code"><div class="codeContent">
<pre class="code-java"><span class="code-keyword">package</span> org.apache.cxf.customverb;

<span class="code-keyword">import</span> java.lang.annotation.ElementType;
<span class="code-keyword">import</span> java.lang.annotation.Retention;
<span class="code-keyword">import</span> java.lang.annotation.RetentionPolicy;
<span class="code-keyword">import</span> java.lang.annotation.Target;

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@HttpMethod(<span class="code-quote">"PATCH"</span>)
<span class="code-keyword">public</span> @<span class="code-keyword">interface</span> PATCH { 
}</pre>
</div></div>

<h2><a name="JAX-RS-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. JAX-RS MessageBodyWriters (see below) are in charge of serializing the response entities, those which are returned directly or as part of javax.ws.rs.core.Response.</p>

<h3><a name="JAX-RS-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 one 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 a checked or runtime exception from an application code and map it to an HTTP response in a registered provider.</p>

<h2><a name="JAX-RS-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>&#64;QueryParam, &#64;HttpHeader, &#64;MatrixParam, &#64;FormParam and &#64;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. <br/>
Additionally CXF JAXRS checks for static fromString(String s) method, so types with no valueOf(String) factory methods can also be dealt with :</p>

<div class="code"><div class="codeContent">
<pre class="code-java"><span class="code-keyword">public</span> <span class="code-keyword">enum</span> Gender {
   MALE,
   FEMALE;

   <span class="code-keyword">public</span> <span class="code-keyword">static</span> fromString(<span class="code-object">String</span> s) {
       <span class="code-keyword">if</span> (<span class="code-quote">"1"</span>.equals(s)) {
           <span class="code-keyword">return</span> FEMALE;
       } <span class="code-keyword">else</span> <span class="code-keyword">if</span> (<span class="code-quote">"1"</span>.equals(s)) {
           <span class="code-keyword">return</span> MALE;
       }  
       <span class="code-keyword">return</span> valueOf(s); 
   }
}

@Path(<span class="code-quote">"/{g}"</span>)
<span class="code-keyword">public</span> class Service {

    
    @PUT
    @Path(<span class="code-quote">"{id}"</span>)
    <span class="code-keyword">public</span> Response update(@PathParam(<span class="code-quote">"g"</span>) Gender g, @PathParam(<span class="code-quote">"id"</span>) UUID u) {
        ...
    }
}</pre>
</div></div>

<p>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>CXF JAXRS supports ParameterHandler extensions which can be used to deal with method parameters annotated with one of the JAXRS parameter annotations :  </p>

<div class="code"><div class="codeContent">
<pre class="code-java"><span class="code-keyword">public</span> class MapHandler <span class="code-keyword">implements</span> ParameterHandler&lt;Map&gt; {
    <span class="code-keyword">public</span> Map fromString(<span class="code-object">String</span> s) {...}
}

@Path(<span class="code-quote">"/"</span>)
<span class="code-keyword">public</span> class Service {

    
    @PUT
    @Path(<span class="code-quote">"{id}"</span>)
    <span class="code-keyword">public</span> Response update(@PathParam(<span class="code-quote">"g"</span>) Map m, <span class="code-object">byte</span>[] bytes) {
        ...
    }
}</pre>
</div></div>

<p>Note that ParameterHandlers can not be used to deal with parameters representing a message body, "byte[] byte" in this example. MessageBodyReaders have to deal with this task. That said, a given MessageBodyReader implementation can also implement ParameterHandler.</p>

<p>ParameterHandlers can be registered as providers either from Spring or programmatically.</p>

<p>All the parameters are automatically decoded. This can be disabled by using @Encoded annotation.<br/>
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>JAX-RS mandates that only a single method parameter which is not annotated with JAXRS annotations applicable to method parameters is allowed in a resource method. For example :</p>

<div class="code"><div class="codeContent">
<pre class="code-java"><span class="code-keyword">public</span> Response <span class="code-keyword">do</span>(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">String</span> id, <span class="code-object">String</span> body) {
}</pre>
</div></div>

<p>Parameters like 'String body' are expected to represent the request body/input stream. It's the job of JAX-RS MessageBodyReaders to deserialize the request body into an object of the expected type.</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 first 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>

<h3><a name="JAX-RS-Parameterbeans"></a>Parameter beans</h3>

<p>There's a CXF extension which makes it possible to inject a sequence of &#64;PathParam, &#64;QueryParam, &#64;FormParam or @MatrixParam 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) {
        ...
    }

    @GET
    @Path(<span class="code-quote">"/order"</span>)
    <span class="code-keyword">public</span> Response getCustomerOrder(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">int</span> customerId, 
                                     @QueryParam("") OrderBean bean,
                                     @MatrixParam("") OrderBean bean) {
        ...
    }

    @POST
    <span class="code-keyword">public</span> Response addCustomerOrder(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">int</span> customerId,
                                     @FormParam("") OrderBean bean) {
        ...
    }
}

<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) {...}  
}

<span class="code-keyword">public</span> class OrderBean {
   <span class="code-keyword">public</span> void setId(<span class="code-object">Long</span> id) {...}
   <span class="code-keyword">public</span> void setWeight(<span class="code-object">int</span> w) {...}  
}</pre>
</div></div>

<p>Note that there's a single @PathParam with an empty value in updateCustomer() - this is an extension bit. The value for a template variable 'id' is 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>Similarly, in getCustomerOrder(), OrderBean can be injected with corresponding values from a query string like ?id=1&amp;weight=2 or from matrix parameters set as part of one of the path segments : /customer/1/order;id=1;weight=2. Likewise, in addCustomerOrder(), FormParam("") can capture all the values submitted from an HTML form and inject them into OrderBean.</p>

<p>Nested beans are also supported, which among other things, makes it possible to formulate advanced search queries.</p>

<h2><a name="JAX-RS-Resourcelifecycle"></a>Resource life-cycle</h2>

<p>By default, resource classes are instantiated every request. In CXF, when resource classes are registered from Spring, singleton scope is always used, though the support for prototype beans is on the way. Providers are always singletons. </p>

<p>At the moment you can register per-request resource classes either programmatically (see below for code samples) or using a CXFNonSpringJaxrsServlet. Note that per-request resource classes can have JAX-RS contexts or parameters injected at the construction time :</p>

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

   <span class="code-keyword">public</span> PerRequestResourceClass(@Context HttpHeaders headers, @QueryParam(<span class="code-quote">"id"</span>) <span class="code-object">Long</span> id) {}
}</pre>
</div></div> 


<h2><a name="JAX-RS-Overviewoftheselectionalgorithm."></a>Overview of the selection algorithm.</h2>

<p>The JAX-RS Selection algorithm is used to select root resource classes, resource methods and subresource locators.</p>

<h3><a name="JAX-RS-Selectingbetweenmultipleresourceclasses"></a>Selecting between multiple resource classes</h3>

<p>When multiple resource classes match a given URI request, the following algorithm is used :<br/>
1. Prefer the resource class which has more literal characters in its &#64;Path annotation.</p>
<div class="code"><div class="codeContent">
<pre class="code-java">@Path(<span class="code-quote">"/bar/{id}"</span>)
<span class="code-keyword">public</span> class Test1 {}
@Path(<span class="code-quote">"/bar/{id}/baz"</span>)
<span class="code-keyword">public</span> class Test2 {}
@Path(<span class="code-quote">"/foo"</span>)
<span class="code-keyword">public</span> class Test3 {}
@Path(<span class="code-quote">"/foo/"</span>)
<span class="code-keyword">public</span> class Test4 {}</pre>
</div></div> 

<p>Both classes match /bar/1/baz requests but Test2 will be selected as it has 9 Path literal characters compared to 5 in Test1. Similarly, Test4 wins against Test3 when a /foo/ request arrives. </p>

<p>2. Prefer the resource class which has more capturing groups in its &#64;Path annotation.</p>

<div class="code"><div class="codeContent">
<pre class="code-java">@Path(<span class="code-quote">"/bar/{id}/"</span>)
<span class="code-keyword">public</span> class Test1 {}
@Path(<span class="code-quote">"/bar/{id}/{id2}"</span>)
<span class="code-keyword">public</span> class Test2 {}</pre>
</div></div>

<p>Both classes match /bar/1/2 requests and both have the same number of literal characters but Test2 will be selected as it has 2 Path capturing groups (id and id1) as opposed to 1 in Test1. </p>

<p>3. Prefer the resource class which has more capturing groups with arbitrary regular expressions in its &#64;Path annotation.</p>

<div class="code"><div class="codeContent">
<pre class="code-java">@Path(<span class="code-quote">"/bar/{id:.+}/baz/{id2}"</span>)
<span class="code-keyword">public</span> class Test1 {}
@Path(<span class="code-quote">"/bar/{id}/{bar}/{id2}"</span>)
<span class="code-keyword">public</span> class Test2 {}</pre>
</div></div>

<p>Both classes match /bar/1/baz/2 requests and both have the same number of literal characters and capturing groups but Test1 will be selected as it has 1 Path capturing groups with the arbitrary regular expression (id) as opposed to 0 in Test2. </p>

<h3><a name="JAX-RS-Selectingbetweenmultipleresourcemethods"></a>Selecting between multiple resource methods</h3>

<p>Once the resource class has been selected, the next step is to choose a resource method. If multiple methods can be matched then the same rules which are used for selecting resource classes are applied. Additionally, one more rule is used.</p>

<p>4. Prefer a resource method to a subresource locator method</p>

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

 @Path(<span class="code-quote">"/bar"</span>)
 @GET
 <span class="code-keyword">public</span> Order getOrder() {...}

 @Path(<span class="code-quote">"/bar"</span>)
 <span class="code-keyword">public</span> Order getOrderFromSubresource() {...}
}

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

 @Path(<span class="code-quote">"/"</span>)
 @GET
 <span class="code-keyword">public</span> Order getOrder() { <span class="code-keyword">return</span> <span class="code-keyword">this</span>; }

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

<p>Both getOrderFromSubresource() and getOrder() methods can be used to serve a /bar request. However, getOrder() wins. </p>

<h3><a name="JAX-RS-Resourcemethodsandmediatypes"></a>Resource methods and media types</h3>

<p>Consider this resource class with 2 resource methods :</p>

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

 @Path(<span class="code-quote">"/bar"</span>)
 @POST 
 @Consumes(<span class="code-quote">"application/json"</span>)
 @Produces(<span class="code-quote">"application/json"</span>)
 <span class="code-keyword">public</span> Order addOrderJSON(OrderDetails details) {...}

 @Path(<span class="code-quote">"/bar"</span>)
 @POST
 @Consumes(<span class="code-quote">"application/xml"</span>)
 @Produces(<span class="code-quote">"application/xml"</span>)
 <span class="code-keyword">public</span> Order getOrderXML(OrderDetails details) {...}
 
}</pre>
</div></div>

<p>Both methods match /bar requests. If in a given request both Content-Type and Accept are set to application/xml then <br/>
getOrderXML will be selected. If both Content-Type and Accept are set to application/json then <br/>
getOrderJSON will be chosen instead.</p>

<p>For this specific example, in both cases either JAXB or JSON message body readers and writers will be selected to deserialize the input stream into OrderDetails and serialize Order into the output stream. Message body providers can have @Produces and @Consumes set too, and they have to match those on a chosen resource method.  </p>

<p>The above code can be replaced with this one :</p>

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

 @Path(<span class="code-quote">"/bar"</span>)
 @POST 
 @Consumes({<span class="code-quote">"application/json"</span>, <span class="code-quote">"application/xml"</span>})
 @Produces({<span class="code-quote">"application/json"</span>, <span class="code-quote">"application/xml"</span>})
 <span class="code-keyword">public</span> Order addOrder(OrderDetails details) {...}

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


<p>TODO : more info</p>

<h2><a name="JAX-RS-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, Providers, Request, ContextResolver, Servlet types (HttpServletRequest, HttpServletResponse, ServletContext, ServletConfig) can be injected.</p>

<p>A CXF-specific composite context interface, <span class="nobr"><a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContext.java" title="Visit page outside Confluence" rel="nofollow">MessageContext<sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span> is also supported which makes it easier to deal with all the supported JAX-RS contexts (and indeed with the future ones) and also lets check the current message's properties.</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> org.apache.cxf.jaxrs.ext.MessageContext mc; 
    @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) {
        mc.getHttpHeaders();
    }
}</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 Providers can have contexts injected too. The only exception is that no parameter level injection is supported for providers due to methods of JAXRS providers being fixed.</p>

<p>Note that Providers and ContextResolver are likely to be of interest to message body providers rather than to the actual application code. You can also inject all the context types into @Resource annotated fields.</p>

<h3><a name="JAX-RS-URIscalculationusingUriInfoandUriBuilder"></a>URIs calculation using UriInfo and UriBuilder</h3>

<p>Mapping of particular URI to service that returns some resource is straightforward using @Path annotation. However RESTful services are often connected: one service returns data that is used as key in another service. Listing entities and accessing particular entity is typical example:</p>

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

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

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

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

<p>For this service we can assume that returned list is brief of customers exposing only basic attributes and more details is returned referring to second URL, using customer id as key. Something like this:</p>

<div class="code"><div class="codeContent">
<pre class="code-java">GET http:<span class="code-comment">//foobar.com/api/customers
</span>
&lt;customers&gt;
    &lt;customer id=<span class="code-quote">"1005"</span>&gt;John Doe&lt;/customer&gt;
    &lt;customer id=<span class="code-quote">"1006"</span>&gt;Jane Doe&lt;/customer&gt;
    ...
&lt;/customers&gt;
    
GET http:<span class="code-comment">//foobar.com/api/customers/1005
</span>
&lt;customer id=<span class="code-quote">"1005"</span>&gt;
    &lt;first-name&gt;John&lt;/first-name&gt;
    &lt;last-name&gt;Doe&lt;/last-name&gt;
    ...
&lt;/customer&gt;</pre>
</div></div>

<p>How does client of this service know how to get from list of customers to given customer? Trivial approach is to expect client to compute proper URI. Wouldn't be better to ease flow through services attaching full URLs that can be used directly? This way client is more decoupled from service itself (that may evolve changing URLs). This way want get something like this:</p>

<div class="code"><div class="codeContent">
<pre class="code-java">GET http:<span class="code-comment">//foobar.com/api/customers
</span>
&lt;customers-list&gt;
    &lt;customer id=<span class="code-quote">"1005"</span> url=<span class="code-quote">"http:<span class="code-comment">//foobar.com/api/customers/1005"</span>&gt;John Doe&lt;/customer&gt;
</span>    &lt;customer id=<span class="code-quote">"1006"</span> url=<span class="code-quote">"http:<span class="code-comment">//foobar.com/api/customers/1006"</span>&gt;Jane Doe&lt;/customer&gt;
</span>    ...
&lt;/customers-list&gt;</pre>
</div></div>

<p>The problem is how to compute URIs when paths come from @Path annotations. It complicates when we consider paths with templates (variables) on multiple levels or sub-resources introducing dynamic routing to different URIs.</p>

<p>The core part of solution is to use injected <span class="nobr"><a href="https://jsr311.dev.java.net/nonav/javadoc/javax/ws/rs/core/UriInfo.html" title="Visit page outside Confluence" rel="nofollow">UriInfo<sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span> object. Method "getCustomers" has to have UriInfo object injected. This helper object allows to extract some useful information about current URI context, but what's more important, allow to get <span class="nobr"><a href="https://jsr311.dev.java.net/nonav/javadoc/javax/ws/rs/core/UriBuilder.html" title="Visit page outside Confluence" rel="nofollow">UriBuilder<sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span> object. UriBuilder has multiple appender methods that extends final URI it can build; in our case to current URI we can append path in multiple ways, providing it as string (which we actually want to avoid here) or providing resource (class or method) to extract @Path value. Finally UriBuilder that is composed of paths with templates (variables) must have variables bound to values to render URI. This case in action looks like this:</p>

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

    @GET
    <span class="code-keyword">public</span> Customers getCustomers(@Context UriInfo ui) {
        ......
        <span class="code-comment">// builder starts with current URI and has appended path of getCustomer method
</span>        UriBuilder ub = ui.getAbsolutePathBuilder().path(<span class="code-keyword">this</span>.getClass(), <span class="code-quote">"getCustomer"</span>);
        <span class="code-keyword">for</span> (Customer customer: customers) {
            <span class="code-comment">// builder has {id} variable that must be filled in <span class="code-keyword">for</span> each customer
</span>            URI uri = ub.build(customer.getId());
            c.setUrl(uri);
        }
        <span class="code-keyword">return</span> customers;
    }

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

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


<h2><a name="JAX-RS-Annotationinheritance"></a>Annotation inheritance</h2>

<p>Most of the JAX-RS annotations can be inherited from either an interface or a superclass. 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);

    @POST
    @Path(<span class="code-quote">"/customers"</span>)
    Customer addCustomer(Customer customer);

}

@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. In CXF, the resource class can also inherit the class-level annotations from either one of its implemented interfaces or its superclass.    </p>


<h2><a name="JAX-RS-Subresourcelocators."></a>Sub-resource locators.</h2>

<p>A method of a resource class that is annotated with @Path becomes a sub-resource locator when no annotation with an HttpMethod designator like @GET is present. Sub-resource locators are used to further resolve the object that will handle the request. They can delegate to other sub-resource locators, including themselves. </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">private</span> Items items;

    <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) {
       ......
    }

    @Path(<span class="code-quote">"products/{productId}/items"</span>)
    <span class="code-keyword">public</span> Order getItems(@PathParam(<span class="code-quote">"productId"</span>) <span class="code-object">int</span> productId) {
       <span class="code-keyword">return</span> <span class="code-keyword">this</span>;
    }

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

}</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.<br/>
The request to <span class="nobr"><a href="http://localhost:9000/customerservice/orders/223/products/323/items" title="Visit page outside Confluence" rel="nofollow">http://localhost:9000/customerservice/orders/223/products/323/items<sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span> will be delivered to getItems() method which in turn will delegate to an overloaded getItems().</p>

<p>Note that a subresource class like Order is often has no root &#64;Path annotations which means that they're delegated to dynamically at runtime, in other words, they can not be invoked upon before one of the root resource classes is invoked first. A root resource class (which has a root @\Path annotation) can become a subresource too if one of its subresource locator methods delegates to it, similarly to Order.getItems() above.   </p>


<p>Note that a given subresource can be represented as an interface or some base class resolved to an actual class at runtime. In this case any resource methods which have to be invoked on an actual subresource instance are discovered dynamically at runtime :  </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 {
    
    <span class="code-keyword">public</span> Product getProduct(<span class="code-object">int</span> productId) {
       ......
    }
}

@XmlRootElement(name = <span class="code-quote">"Order"</span>)
<span class="code-keyword">public</span> class OrderImpl2 <span class="code-keyword">implements</span> Order {
    
    <span class="code-comment">// overrides JAXRS annotations
</span>    @GET
    @Path(<span class="code-quote">"theproducts/{productId}/"</span>)
    Product getProduct(@PathParam(<span class="code-quote">"id"</span>)<span class="code-object">int</span> productId) {...}
}</pre>
</div></div>

<h3><a name="JAX-RS-Staticresolutionofsubresources"></a>Static resolution of subresources</h3>

<p>By default, subresources are resolved dynamically at runtime. This is a slower procedure, partly due to the fact that a concrete subresource implementation may introduce some JAXRS annotations in addition to those which might be available at the interface typed by a subresource locator method and different to those available on another subresource instance implementing the same interface.</p>

<p>If you know that all the JAXRS annotations are available on a given subresource type (or one of its superclasses or interfaces) returned by a subresource locator method then you may want to disable the dynamic resolution :</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 staticSubresourceResolution=<span class="code-quote">"true"</span>&gt;</span>
<span class="code-tag"><span class="code-comment">&lt;!-- more configuration --&gt;</span></span>
<span class="code-tag">&lt;/jaxrs:server&gt;</span>
<span class="code-tag">&lt;/beans&gt;</span></pre>
</div></div>


<h2><a name="JAX-RS-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, text/xml and application/json formats as well as JAXBElement (see below). JAX-RS MultivaluedMap is also supported for form contents. </p>

<p>See also a "Support for data bindings" section below.</p>

<h3><a name="JAX-RS-CustomMessageBodyProviders"></a>Custom Message Body Providers          </h3>

<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">@Consumes(<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, MediaType mt) {
        <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-object">Class</span>&lt;?&gt; type, Type genericType, Annotation[] annotations, MediaType mt) {
        <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, MediaType mt) {
        <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-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;ref bean=<span class="code-quote">"isProvider"</span> /&gt;</span>
      <span class="code-tag">&lt;ref bean=<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. For ex, in a large project user providers from different libraries might clash. </p>

<p>When using the custom configuration (as shown above) provider instances of different types (handling the same format of request/response bodies) or differently configured instances of the same type can be registered with a different jaxrs:server instance. Yet another requirement might be to have only a given jaxrs:server endpoint among multiple available ones to handle requests with a given media type :</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">"customerService1"</span> address=<span class="code-quote">"/1"</span>&gt;</span>
   <span class="code-tag">&lt;bean id=<span class="code-quote">"serviceBean"</span> class=<span class="code-quote">"org.CustomerService"</span> /&gt;</span> 

   <span class="code-tag">&lt;jaxrs:serviceBeans&gt;</span>
      <span class="code-tag">&lt;ref bean=<span class="code-quote">"serviceBean"</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 class=<span class="code-quote">"com.bar.providers.InputStreamProvider"</span>/&gt;</span>
   <span class="code-tag">&lt;/jaxrs:providers&gt;</span>
<span class="code-tag">&lt;/jaxrs:server&gt;</span>
<span class="code-tag">&lt;jaxrs:server id=<span class="code-quote">"customerService2"</span> address=<span class="code-quote">"/2"</span>&gt;</span>
    <span class="code-tag">&lt;jaxrs:serviceBeans&gt;</span>
      <span class="code-tag">&lt;ref bean=<span class="code-quote">"serviceBean"</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 id=<span class="code-quote">"isProvider"</span> class=<span class="code-quote">"baz.foo.jaxrsproviders.InputStreamProvider"</span>/&gt;</span>
    <span class="code-tag">&lt;/jaxrs:providers&gt;</span>
<span class="code-tag">&lt;/jaxrs:server&gt;</span>

<span class="code-tag">&lt;jaxrs:server id=<span class="code-quote">"customerService3"</span> address=<span class="code-quote">"/3"</span>&gt;</span>
    <span class="code-tag">&lt;jaxrs:serviceBeans&gt;</span>
      <span class="code-tag">&lt;ref bean=<span class="code-quote">"serviceBean"</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;ref bean=<span class="code-quote">"isProvider"</span>/&gt;</span>
    <span class="code-tag">&lt;/jaxrs:providers&gt;</span>
<span class="code-tag">&lt;/jaxrs:server&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;property name=<span class="code-quote">"limit"</span> value=<span class="code-quote">"5"</span>/&gt;</span>
<span class="code-tag">&lt;/bean&gt;</span>

<span class="code-tag">&lt;/beans&gt;</span></pre>
</div></div>

<p>In this example a single service bean can be accessed through 3 different paths, /1, /2 and /3. InputStream provider is available on all the 3 paths. com.bar.providers.InputStreamProvider is used in 2 cases, while a special InputStream handler baz.foo.jaxrsproviders.InputStreamProvider from another library is also involved in one case.</p>


<h2><a name="JAX-RS-Customizingmediatypesformessagebodyproviders"></a>Customizing media types for message body providers</h2>

<p>As explained above, message body providers can play a major part in affecting the way target resource methods are matched. If a method returns a custom type Foo and a MessageBodyWriter&lt;Foo&gt; is available then it will be used only if one of the media types specified in a given request's HTTP Accept header matches or intersects with one of the media types specified by &#64;Produces annotation in a MessageBodyWriter&lt;Foo&gt; implementation. The same applies if a method accepts a custom type Foo, but this time the value of &#64;Consumes in MessageBodyReader&lt;Foo&gt; will be matched against a request's ContentType value.    </p>

<p>Sometimes users would like to experiment with media types different to those statically supported by a given message body reader/writer. For example, application/xml might seem a bit too general in some cases and people may want to try some custom/xml type and still use a default JAXB provider. </p>

<p>In such cases it's possible to override the default @Produces and/or @Consumes types supported by a given provider. It only currently works for JAXBElementProvider and JSONProvider, but any custom provider can avail of this support by simply having setter/getter pairs for either produce and/or consume types and the JAXRS runtime will use them instead.<br/>
See <span class="nobr"><a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/src/test/resources/jaxrs/WEB-INF/beans.xml" title="Visit page outside Confluence" rel="nofollow">this example<sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span> on how to provide custom media types from Spring.</p>

<h2><a name="JAX-RS-Supportfordatabindings"></a>Support for data bindings</h2>

<h3><a name="JAX-RS-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-xml"><span class="code-tag">&lt;Customer&gt;</span>
    <span class="code-tag">&lt;id&gt;</span>123<span class="code-tag">&lt;/id&gt;</span>
    <span class="code-tag">&lt;name&gt;</span>John<span class="code-tag">&lt;/name&gt;</span>
<span class="code-tag">&lt;/Customer&gt;</span></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>Another option is to register one or more JAX-RS ContextResolver providers capable of creating JAXBContexts for a number of different types. The default JAXBElementProvider will check these resolvers first before attempting to create a JAXBContext on its own.   </p>

<p>Finally, JAXBProvider provides a support for serializing response types and deserializing parameters of methods annotated with @XmlJavaTypeAdapter annotations.     </p>

<h4><a name="JAX-RS-ConfiguringJAXBprovider"></a>Configuring JAXB provider</h4>

<p>The default JAXB provider can be configured in a number of ways. For example, here's how to set up marshall properties :</p>

<div class="code"><div class="codeContent">
<pre class="code-xml"><span class="code-tag">&lt;beans <span class="code-keyword">xmlns:util</span>=<span class="code-quote">"http://www.springframework.org/schema/util"</span>&gt;</span>
<span class="code-tag">&lt;bean id=<span class="code-quote">"jaxbProvider"</span> class=<span class="code-quote">"org.apache.cxf.jaxrs.provider.JAXBElementProvider"</span>&gt;</span>
<span class="code-tag">&lt;property name=<span class="code-quote">"marshallerProperties"</span> ref=<span class="code-quote">"propertiesMap"</span>/&gt;</span>
<span class="code-tag">&lt;/bean&gt;</span>
<span class="code-tag">&lt;util:map id=<span class="code-quote">"propertiesMap"</span> map-class=<span class="code-quote">"java.util.Hashtable"</span>&gt;</span>
<span class="code-tag">&lt;entry key=<span class="code-quote">"jaxb.formatted.output"</span> value=<span class="code-quote">"true"</span>/&gt;</span>
<span class="code-tag">&lt;/util:map&gt;</span>
/<span class="code-tag">&lt;beans&gt;</span></pre>
</div></div>

<p>Individual marshal properties can be injected as simple properties. At the moment, Marshaller.JAXB_SCHEMA_LOCATION can be injected as "schemaLocation" property. Schema validation can be enabled and custom &#64;Consume and &#64;Produce media types can be injected, see <span class="nobr"><a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/src/test/resources/jaxrs/WEB-INF/beans.xml" title="Visit page outside Confluence" rel="nofollow">this example<sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span> and "Customizing media types for message body providers" and "Schema Validation Support" sections for more information. </p>

<p>One issue which one may need to be aware of it is that an exception may occur during the JAXB serialization process, after some content has already been processed and written to the output stream. By default, the output goes directly to the output HTTP stream so if an exception occurs midway through the process then the output will likely be malformed. If you set 'enableBuffering' property to 'true' then a JAXB provider will write to the efficient CXF CachedOutputStream instead and if an exception occurs then no text which has already been written will make it to the outside world and it will be only this exception that will be reported to the client.  </p>

<p>When enabling buffering, you can also control how the data being serialized will be buffered. By default, an instance of CXF CachedOutputStream will be used. If you set an "enableStreaming" property on the JAXBElementProvider then it will be a CXF CachingXMLEventWriter that will cache the serialization events.</p>

<p>If you would like your own custom provider to write to a cached stream then you can either set an "org.apache.cxf.output.buffering" property to 'true' on a jaxrs endpoint or "enableBuffering" property on the provider. If this provider deals with XML and has a "getEnableStreaming" method returning 'true' then CachingXMLEventWriter will be used, in all other cases CachedOutputStream will be used.</p>

<h3><a name="JAX-RS-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 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 {
    @Produces(<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>

<h4><a name="JAX-RS-ConfiguringJSONprovider"></a>Configuring JSON provider</h4>

<p>The default JSON provider can be configured in a number of ways. For example, here's how to set up namespace-to-prefix mappings :</p>

<div class="code"><div class="codeContent">
<pre class="code-xml"><span class="code-tag">&lt;beans <span class="code-keyword">xmlns:util</span>=<span class="code-quote">"http://www.springframework.org/schema/util"</span>&gt;</span>
<span class="code-tag">&lt;bean id=<span class="code-quote">"jaxbProvider"</span> class=<span class="code-quote">"org.apache.cxf.jaxrs.provider.JSONProvider"</span>&gt;</span>
<span class="code-tag">&lt;property name=<span class="code-quote">"namespaceMap"</span> ref=<span class="code-quote">"jsonNamespaceMap"</span>/&gt;</span>
<span class="code-tag">&lt;/bean&gt;</span>
<span class="code-tag">&lt;util:map id=<span class="code-quote">"jsonNamespaceMap"</span> map-class=<span class="code-quote">"java.util.Hashtable"</span>&gt;</span>
<span class="code-tag">&lt;entry key=<span class="code-quote">"http://www.example.org/books"</span> value=<span class="code-quote">"b"</span>/&gt;</span>
<span class="code-tag">&lt;/util:map&gt;</span>
/<span class="code-tag">&lt;beans&gt;</span></pre>
</div></div>

<p>Schema validation can be enabled and custom &#64;Consume and &#64;Produce media types can be injected, see <span class="nobr"><a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/src/test/resources/jaxrs/WEB-INF/beans.xml" title="Visit page outside Confluence" rel="nofollow">this example<sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span> and "Customizing media types for message body providers" and "Schema Validation Support" sections for more information. </p>

<h4><a name="JAX-RS-DealingwithJSONarrayserializationissues"></a>Dealing with JSON array serialization issues </h4>

<p>There's a well known problem in the JSON community which shows itself in the wrong serialization of List objects containing a single value only. To work around this issue, one needs to enable a 'serializeAsArray' feature on a JSONProvider, with the additional option of specifying the individual fields which needs to be processed accordingly using an 'arrayKeys' property. Please see <span class="nobr"><a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/src/test/resources/jaxrs/WEB-INF/beans.xml" title="Visit page outside Confluence" rel="nofollow">this example<sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span> for more information. </p>

<h3><a name="JAX-RS-AegisDataBinding"></a>Aegis Data Binding</h3>

<p>Use org.apache.cxf.provider.AegisElementProvider to start doing Aegis with JAX-RS</p>

<h3><a name="JAX-RS-XMLBeans"></a>XMLBeans</h3>

<p>Use org.apache.cxf.provider.XmlBeansElementProvider to start doing XmlBeans with JAX-RS</p>

<h2><a name="JAX-RS-Schemavalidationsupport"></a>Schema validation support</h2>

<p>There're two ways you can enable a schema validation.</p>

<p>1. Using jaxrs:schemaLocations element :</p>

<div class="code"><div class="codeContent">
<pre class="code-xml"><span class="code-tag">&lt;beans <span class="code-keyword">xmlns:util</span>=<span class="code-quote">"http://www.springframework.org/schema/util"</span>&gt;</span>
<span class="code-tag">&lt;jaxrs:server address=<span class="code-quote">"/"</span>&gt;</span>
  <span class="code-tag">&lt;jaxrs:schemaLocations&gt;</span>
     <span class="code-tag">&lt;jaxrs:schemaLocation&gt;</span>classpath:/schemas/a.xsd<span class="code-tag">&lt;/jaxrs:schemaLocation&gt;</span>
     <span class="code-tag">&lt;jaxrs:schemaLocation&gt;</span>classpath:/schemas/b.xsd<span class="code-tag">&lt;/jaxrs:schemaLocation&gt;</span>
  <span class="code-tag">&lt;/jaxrs:schemaLocations&gt;</span>
<span class="code-tag">&lt;/jaxrs:server&gt;</span>
/<span class="code-tag">&lt;beans&gt;</span></pre>
</div></div>

<p>Using this option is handy when you have multiple bindings involved which support the schema validation. In this case<br/>
individual MessageBodyReader implementations which have a method setSchemas(List&lt;Sring&gt; schemaLocations) called. Default JAXBElementProvider and JSONProvider which rely on JAXB can be enabled to do the validation this way. In the above example two schema documents are provided, with b.xsd schema presumably importing a.xsd  </p>

<p>2. Configuring providers individually</p>

<p>Please see <span class="nobr"><a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/src/test/resources/jaxrs/WEB-INF/beans.xml" title="Visit page outside Confluence" rel="nofollow">this example<sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span> of how both JAXB and JSON providers are using a shared schema validation configuration.</p>

<h2><a name="JAX-RS-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. @Produces and @Consumes annotations are used to declare the supported request and response media types. </p>

<p>TODO : more content here</p>


<h2><a name="JAX-RS-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-Logging"></a>Logging</h2>

<p>Existing CXF features can be applied to jaxrs:server, whenever it makes sense.<br/>
To enable logging of requests and responses, simply do :</p>
<div class="code"><div class="codeContent">
<pre class="code-xml"><span class="code-tag">&lt;jaxrs:server&gt;</span>
<span class="code-tag">&lt;jaxrs:features&gt;</span>
     <span class="code-tag">&lt;cxf:logging/&gt;</span>
<span class="code-tag">&lt;/jaxrs:features&gt;</span>
<span class="code-tag">&lt;jaxrs:server&gt;</span></pre>
</div></div>

<h2><a name="JAX-RS-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 modifies 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>Here are the interface definitions : </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 by returning a non-null Response. </p>

<p>A response filter implementation can get an access to OperationResourceInfo object representing a method to be invoked on a resource class :</p>

<div class="code"><div class="codeContent">
<pre class="code-java">OperationResourceInfo ori = exchange.get(OperationResourceInfo.class);</pre>
</div></div>  

<p>Use OperationResourceInfo in your filter with care. In principle a given request chain may have filters which may want to  overwrite Accept or ContentType message headers which might lead to another method be selected. However if you know no such filters (will) exist in your application then you might want to check an OperationResourceInfo instance as part of your filter logic. </p>

<p>When modifying an input message, one would typically want to replace a message input stream or one of its headers, such as ContentType :</p>
<div class="code"><div class="codeContent">
<pre class="code-java">InputStream is = message.getContent(InputStream.class);
message.setContent(<span class="code-keyword">new</span> MyFilterInputStream(is));
message.put(Message.ACCEPT_CONTENT_TYPE, <span class="code-quote">"custom/media"</span>);</pre>
</div></div>

<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 or modify the output message. When modifying an output message, one may want to either replace an output stream before message body providers attempt to write to it or replace the actual response object :</p>
<div class="code"><div class="codeContent">
<pre class="code-java"><span class="code-comment">// replace an output stream
</span>OutputStream os = message.getContent(OutputStream.class);
message.setContent(<span class="code-keyword">new</span> MyFilterOutputStream(os));

<span class="code-comment">// replace an actual object
</span>response.setEntity(<span class="code-keyword">new</span> MyWrapper(response.getEntity()))
<span class="code-comment">// or using a low-level Message api <span class="code-keyword">if</span> needed
</span>MessageContentsList objs = MessageContentsList.getContentsList(message);
<span class="code-keyword">if</span> (objs !== <span class="code-keyword">null</span> &amp;&amp; objs.size() == 1) {
    <span class="code-object">Object</span> responseObj = objs.remove(0);
    obj.add(<span class="code-keyword">new</span> MyWrapper(responseObj));
}</pre>
</div></div>

<p>Please see <span class="nobr"><a href="http://sberyozkin.blogspot.com/2008/07/rest-and-soap-united-in-cxf.html" title="Visit page outside Confluence" rel="nofollow">this blog entry<sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span> for another example of when response filters can be useful.</p>

<p>Multiple request and response handlers are supported.</p>

<p>The implementations can be registered like any other types of providers :</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;ref bean=<span class="code-quote">"authorizationFilter"</span> /&gt;</span>
    <span class="code-tag">&lt;/jaxrs:providers&gt;</span>
    <span class="code-tag">&lt;bean id=<span class="code-quote">"authorizationFilter"</span> class=<span class="code-quote">"com.bar.providers.AuthorizationRequestHandler"</span>&gt;</span>
        <span class="code-tag"><span class="code-comment">&lt;!-- authorization bean properties --&gt;</span></span>
    <span class="code-tag">&lt;/bean&gt;</span>
<span class="code-tag">&lt;/jaxrs:server&gt;</span>
<span class="code-tag">&lt;/beans&gt;</span></pre>
</div></div>

<h3><a name="JAX-RS-DifferencebetweenJAXRSfiltersandCXFinterceptors"></a>Difference between JAXRS filters and CXF interceptors</h3>

<p>JAXRS runtime flow is mainly implemented by a pair of 'classical' CXF interceptors. JAXRSInInterceptor is currently at Phase.PRE_STREAM phase while JAXRSOutInterceptor is currently at Phase.MARSHAL phase.</p>

<p>JAXRS filters can be thought of as additional handlers. JAXRSInInterceptor deals with a chain of RequestHandlers, just before the invocation. JAXRSOutInterceptor deals with a chain of ResponseHandlers, just after the invocation but before message body writers get their chance.</p>

<p>Sometimes you may want to use CXF interceptors rather than writing JAXRS filters. For example, suppose you combine JAXWS and JAXRS and you need to log only inbound or outbound messages. You can reuse the existing CXF interceptors :</p>

<div class="code"><div class="codeContent">
<pre class="code-xml"><span class="code-tag">&lt;beans&gt;</span>
<span class="code-tag">&lt;bean id=<span class="code-quote">"logInbound"</span> class=<span class="code-quote">"org.apache.cxf.interceptor.LoggingInInterceptor"</span>/&gt;</span>
<span class="code-tag">&lt;bean id=<span class="code-quote">"logOutbound"</span> class=<span class="code-quote">"org.apache.cxf.interceptor.LoggingOutInterceptor"</span>/&gt;</span>

<span class="code-tag">&lt;jaxrs:server&gt;</span> 
 <span class="code-tag">&lt;jaxrs:inInterceptors&gt;</span>
     <span class="code-tag">&lt;ref bean=<span class="code-quote">"logInbound"</span>/&gt;</span>
 <span class="code-tag">&lt;/jaxrs:inInterceptors&gt;</span>
 <span class="code-tag">&lt;jaxrs:outInterceptors&gt;</span>
    <span class="code-tag">&lt;ref bean=<span class="code-quote">"logOutbound"</span>/&gt;</span>
 <span class="code-tag">&lt;/jaxrs:outInterceptors&gt;</span>
<span class="code-tag">&lt;/jaxrs:server&gt;</span>

<span class="code-tag">&lt;jaxws:endpoint&gt;</span>
 <span class="code-tag">&lt;jaxws:inInterceptors&gt;</span>
     <span class="code-tag">&lt;ref bean=<span class="code-quote">"logInbound"</span>/&gt;</span>
 <span class="code-tag">&lt;/jaxws:inInterceptors&gt;</span>
 <span class="code-tag">&lt;jaxws:outInterceptors&gt;</span>
    <span class="code-tag">&lt;ref bean=<span class="code-quote">"logOutbound"</span>/&gt;</span>
 <span class="code-tag">&lt;/jaxws:outInterceptors&gt;</span>
<span class="code-tag">&lt;/jaxws:endpoint&gt;</span>

<span class="code-tag">&lt;/beans&gt;</span></pre>
</div></div> 

<p>Reusing other CXF interceptors/features such as GZIP handlers can be useful too.</p>

<h2><a name="JAX-RS-Custominvokers"></a>Custom invokers</h2>

<p>Using custom JAXR-RS invokers is yet another way to pre or post process a given invocation. For example, this <span class="nobr"><a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/CustomJAXRSInvoker.java" title="Visit page outside Confluence" rel="nofollow">invoker<sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span> does a security check before delegating to the default JAXRS invoker. A custom invoker, like a request filter, has the access to all the information accumulated during the processing of a given call, but additionally, it can also check the actual method parameter values.</p>

<p>Custom invokers can be registered like this :</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 address=<span class="code-quote">"/"</span>&gt;</span> 
 <span class="code-tag">&lt;jaxrs:invoker&gt;</span>
   <span class="code-tag">&lt;bean class=<span class="code-quote">"org.apache.cxf.systest.jaxrs.CustomJAXRSInvoker"</span>/&gt;</span>
 <span class="code-tag">&lt;/jaxrs:invoker&gt;</span>
<span class="code-tag">&lt;/jaxrs:server&gt;</span>

<span class="code-tag">&lt;/beans&gt;</span></pre>
</div></div> 


<h2><a name="JAX-RS-AdvancedHTTP"></a>Advanced HTTP</h2>

<p>CXF JAXRS provides support for a number of advanced HTTP features by handling If-Match, If-Modified-Since and ETags headers. JAXRS Request context object can be used to check the preconditions. Vary, CacheControl, Cookies and Set-Cookies are also supported.</p>

<h2><a name="JAX-RS-SupportforContinuations"></a>Support for Continuations </h2>

<p>Please see <span class="nobr"><a href="http://sberyozkin.blogspot.com/2008/12/continuations-in-cxf.html" title="Visit page outside Confluence" rel="nofollow">this blog entry<sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span> describing how JAXRS (and indeed) JAXWS services can rely on the CXF Continuations API. Currently, only Jetty based services can rely on this option.</p>

<h2><a name="JAX-RS-SecureJAXRSservices"></a>Secure JAX-RS services</h2>

<p>A demo called samples\jax_rs\basic_https shows you how to do communications using HTTPS.<br/>
Spring Security can be quite easily applied too (see "JAXRS and Spring AOP" section for some general advice).</p>

<h2><a name="JAX-RS-SecurityManagerandIllegalAccessExceptions"></a>SecurityManager and IllegalAccessExceptions</h2>

<p>If java.lang.SecurityManager is installed then you'll likely need to configure the trusted JAXRS codebase with a 'suppressAccessChecks' permission for the injection of JAXRS context or parameter fields to succeed. For example, you may want to update a Tomcat <span class="nobr"><a href="http://tomcat.apache.org/tomcat-5.5-doc/security-manager-howto.html" title="Visit page outside Confluence" rel="nofollow">catalina.policy<sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span> with the following permission :</p>

<div class="code"><div class="codeContent">
<pre class="code-java">grant codeBase <span class="code-quote">"file:${catalina.home}/webapps/yourwebapp/lib/cxf.jar"</span> {
    permission java.lang.reflect.ReflectPermission <span class="code-quote">"suppressAccessChecks"</span>;
};</pre>
</div></div>

<h1><a name="JAX-RS-ConfiguringJAXRSservices"></a>Configuring JAX-RS services</h1>

<h2><a name="JAX-RS-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(<span class="code-keyword">new</span> BookStore()));</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-ClientAPI"></a>Client API</h2>

<p>JAX-RS 1.0 does not provide for the standard approach toward consuming pure HTTP-based services so in CXF we have provided 3 flavors of the client API : proxy-based, HTTP-centric and XML-centric.</p>

<h3><a name="JAX-RS-ProxybasedAPI"></a>Proxy-based API</h3>

<p>With the proxy-based API, one can reuse on the client side the interfaces or even the resource classes which have already been designed for processing the HTTP requests on the server side. When reused on the client side, the simply act as the remote proxies.</p>

<p><span class="nobr"><a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/JAXRSClientFactory.java" title="Visit page outside Confluence" rel="nofollow">JAXRSClientFactory<sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span> is a utility class which wraps <span class="nobr"><a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/JAXRSClientFactoryBean.java" title="Visit page outside Confluence" rel="nofollow">JAXRSClientFactoryBean<sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span>. JAXRSClientFactory has a number of utility methods but JAXRSClientFactoryBean can be used directly when needed.</p>

<p>For example, given these class definitions :</p>

<div class="code"><div class="codeContent">
<pre class="code-java">@Path(<span class="code-quote">"/bookstore"</span>)
<span class="code-keyword">public</span> <span class="code-keyword">interface</span> BookStore {
   @GET
   Books getAllBooks();
   
   @Path(<span class="code-quote">"{id}"</span>)
   BookResource getBookSubresource(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">long</span> id) <span class="code-keyword">throws</span> NoBookFoundException;
}

<span class="code-keyword">public</span> class BookStoreImpl <span class="code-keyword">implements</span> BookStore {
   <span class="code-keyword">public</span> Books getAllBooks() {}
   
   <span class="code-keyword">public</span> Book getBookSubresource(<span class="code-object">long</span> id) <span class="code-keyword">throws</span> NoBookFoundException {}
}

<span class="code-keyword">public</span> <span class="code-keyword">interface</span> BookResource {
   @GET
   Book getDescription();
}

<span class="code-keyword">public</span> class BookResourceImpl <span class="code-keyword">implements</span> BookResource {
   @GET
   Book getDescription() {}
}</pre>
</div></div>

<p>the following client code retrieves a Book with id '1' and a collection of books: </p>

<div class="code"><div class="codeContent">
<pre class="code-java">BookStore store = JAXRSClientFactory.create(<span class="code-quote">"http:<span class="code-comment">//bookstore.com"</span>, BookStore.class);
</span><span class="code-comment">// (1) remote GET call to http://bookstore.com/bookstore
</span>Books books = store.getAllBooks();
<span class="code-comment">// (2) no remote call
</span>BookResource subresource = store.getBookSubresource(1);
<span class="code-comment">// {3} remote GET call to http://bookstore.com/bookstore/1
</span>Book b = subresource.getDescription();</pre>
</div></div>     

<p>When proxies are created, initially or when subresource methods are invoked, the current URI is updated with corresponding &#64;Path, &#64;PathParam, &#64;QueryParam or @MatrixParam values, while &#64;HttpHeader and &#64;CookieParam values contribute to the current set of HTTP headers. Same happens before the remote invocation is done. </p>

<p>MessageBodyReaders and MessageBodyWriters are used to process request or response bodies, same way as on the server side. More specifically. method body writers are invoked whenever a remote method parameter is assumed to be a request body (that is, it has no JAX-RS annotations attached) or when a form submission is emulated with the help of either &#64;FormParams or JAX-RS MultivaluedMap. </p>

<h4><a name="JAX-RS-Customizingproxies"></a>Customizing proxies </h4>

<h4><a name="JAX-RS-Handlingexceptions"></a>Handling exceptions</h4>

<h4><a name="JAX-RS-ConvertingtoHTTPcentricclients"></a>Converting to HTTP-centric clients</h4>

<h2><a name="JAX-RS-HTTPcentricclients"></a>HTTP-centric clients</h2>

<h4><a name="JAX-RS-Convertingtoproxies"></a>Converting to proxies</h4>

<h2><a name="JAX-RS-XMLcentricclients"></a>XML-centric clients</h2>

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

<h3><a name="JAX-RS-web.xml"></a>web.xml</h3>

<p>In web.xml one needs to register one or more CXFServlet(s) and link to an application context configuration.</p>

<h4><a name="JAX-RS-UsingSpringContextLoaderListener"></a>Using Spring ContextLoaderListener</h4>

<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>

<p>The application context configuration is shared between all the CXFServlets</p>

<h4><a name="JAX-RS-UsingCXFServletinitparameters"></a>Using CXFServlet init parameters </h4>

<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;servlet&gt;</span>
		<span class="code-tag">&lt;servlet-name&gt;</span>CXFServlet1<span class="code-tag">&lt;/servlet-name&gt;</span>
		<span class="code-tag">&lt;display-name&gt;</span>CXF Servlet1<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;init-param&gt;</span>
                   <span class="code-tag">&lt;param-name&gt;</span>config-location<span class="code-tag">&lt;/param-name&gt;</span>
                   <span class="code-tag">&lt;param-value&gt;</span>/WEB-INF/beans1.xml<span class="code-tag">&lt;/param-value&gt;</span>
                <span class="code-tag">&lt;/init-param&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&gt;</span>
		<span class="code-tag">&lt;servlet-name&gt;</span>CXFServlet2<span class="code-tag">&lt;/servlet-name&gt;</span>
		<span class="code-tag">&lt;display-name&gt;</span>CXF Servlet2<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;init-param&gt;</span>
                   <span class="code-tag">&lt;param-name&gt;</span>config-location<span class="code-tag">&lt;/param-name&gt;</span>
                   <span class="code-tag">&lt;param-value&gt;</span>/WEB-INF/beans2.xml<span class="code-tag">&lt;/param-value&gt;</span>
                <span class="code-tag">&lt;/init-param&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>CXFServlet1<span class="code-tag">&lt;/servlet-name&gt;</span>
		<span class="code-tag">&lt;url-pattern&gt;</span>/1/*<span class="code-tag">&lt;/url-pattern&gt;</span>
	<span class="code-tag">&lt;/servlet-mapping&gt;</span>

        <span class="code-tag">&lt;servlet-mapping&gt;</span>
		<span class="code-tag">&lt;servlet-name&gt;</span>CXFServlet2<span class="code-tag">&lt;/servlet-name&gt;</span>
		<span class="code-tag">&lt;url-pattern&gt;</span>/2/*<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>

<p>Each CXFServlet can get a unique application context configuration. Note, no Spring ContextLoaderListener is registered in web.xml in this case.</p>

<h3><a name="JAX-RS-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"><span class="code-comment">&lt;!-- do not use import statements if CXFServlet init parameters link to this beans.xml --&gt;</span></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">"customerService"</span> address=<span class="code-quote">"/service1"</span>&gt;</span>
    <span class="code-tag">&lt;jaxrs:serviceBeans&gt;</span>
      <span class="code-tag">&lt;ref bean=<span class="code-quote">"customerBean"</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">"customerBean"</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-RegisteringendpointswithoutSpring"></a>Registering endpoints without Spring</h2>

<p>If you prefer, you can register JAX-RS endpoints without depending on Spring with the help of CXFNonSpringJaxrsServlet :</p>

<div class="code"><div class="codeContent">
<pre class="code-xml"><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.jaxrs.servlet.CXFNonSpringJaxrsServlet
 <span class="code-tag">&lt;/servlet-class&gt;</span>
 <span class="code-tag">&lt;init-param&gt;</span>
  <span class="code-tag">&lt;param-name&gt;</span>jaxrs.serviceClasses<span class="code-tag">&lt;/param-name&gt;</span>
  <span class="code-tag">&lt;param-value&gt;</span>
    org.apache.cxf.systest.jaxrs.BookStore1
    org.apache.cxf.systest.jaxrs.BookStore2		      
  <span class="code-tag">&lt;/param-value&gt;</span>
 <span class="code-tag">&lt;/init-param&gt;</span>
 <span class="code-tag">&lt;init-param&gt;</span>
  <span class="code-tag">&lt;param-name&gt;</span>jaxrs.providers<span class="code-tag">&lt;/param-name&gt;</span>
  <span class="code-tag">&lt;param-value&gt;</span>
    org.apache.cxf.systest.jaxrs.BookStoreProvider1
    org.apache.cxf.systest.jaxrs.BookStoreProvider2		      
  <span class="code-tag">&lt;/param-value&gt;</span>
 <span class="code-tag">&lt;/init-param&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></pre>
</div></div>

<p>When service classes and providers are registered this way, the default life-cycle is 'singleton'. You can override it by setting a "jaxrs.scope" parameter with the value of 'prototype' (equivalent to per-request). <br/>
By default, the endpoint address is "/". One can provide a more specific value using "jaxrs.address" parameter.</p>

<p>A more portable way to register resource classes and providers with CXFNonSpringJaxrsServlet is to use a JAX-RS Application <span class="nobr"><a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookApplication.java" title="Visit page outside Confluence" rel="nofollow">implementation<sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span> :</p>


<div class="code"><div class="codeContent">
<pre class="code-xml"><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.jaxrs.servlet.CXFNonSpringJaxrsServlet
 <span class="code-tag">&lt;/servlet-class&gt;</span>
 <span class="code-tag">&lt;init-param&gt;</span>
  <span class="code-tag">&lt;param-name&gt;</span>javax.ws.rs.Application<span class="code-tag">&lt;/param-name&gt;</span>
  <span class="code-tag">&lt;param-value&gt;</span>
    org.apache.cxf.systest.jaxrs.BookApplication	      
  <span class="code-tag">&lt;/param-value&gt;</span>
 <span class="code-tag">&lt;/init-param&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></pre>
</div></div>

<p>Note that Application.getClasses() method returns a set of per-request resource class names. Application.getSingletons() returns a list of singleton resource and provider classes. </p>

<h2><a name="JAX-RS-Multipleendpointsandresourceclasses"></a>Multiple endpoints and resource classes</h2>

<p>One can configure as many jaxrs:server endpoints as needed for a given application, with every endpoint possibly providing an alternative path to a single resource bean. Every endpoint can employ as many shared or unique resource classes as needed, and have common or different providers.  </p>

<h2><a name="JAX-RS-HowtherequestURIismatchedagainstagivenjaxrsendpoint"></a>How the request URI is matched against a given jaxrs endpoint</h2>

<p>There's a number of variables involved here. </p>

<p>Lets assume you have a web application called 'rest'. CXFServlet's url-pattern is "/test/*". Finally, jaxrs:server's address is "/bar".</p>

<p>Requests like /rest/test/bar or /rest/test/bar/baz will be delivered to one of the resource classes in a given jaxrs:server endpoint. For the former request be handled, a resource class with &#64;Path("/") should be available, in the latter case - at least &#64;Path("/") or more specific @Path("/baz").</p>

<p>The same requirement can be expressed by having a CXFServlet with "/*" and jaxrs:server with "/test/bar". </p>

<p>When both CXFServlet and jaxrs:server use "/" then it's a root resource class which should provide a &#64;Path with at least "/test/bar" for the above requests be matched. </p>

<p>Generally, it can be a good idea to specify the URI segments which are more likely to change now and then with CXFServlets or jaxrs:server. </p>

<h2><a name="JAX-RS-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 {
   <span class="code-keyword">public</span> 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 {
   <span class="code-keyword">public</span> 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>Note that CXF Continuations API is supported for both JAXWS and JAXRS services.</p>

<h3><a name="JAX-RS-Dealingwithcontexts"></a>Dealing with contexts</h3>

<p>When combining JAXWS and JAXRS, one may need to access some context information as part of processing a given request. At the moment, CXF JAXRS does not offer a context implementation which can be used to access a request-specific information common for both JAXWS and JAXRS requests, in cases when the same methods are used to handle both JAXWS and JAXRS requests. Please use a JAXWS WebServiceContext and JAXRS contexts or CXF JAXRS composite MessageContext :</p>

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

   @Resource WebServiceContext jaxwsContext;
   @Resource MessageContext jaxrsContext;

   @WebMethod
   @POST
   <span class="code-keyword">public</span> void doIt(<span class="code-object">String</span> b) {
       isUserInRole();
   };

   <span class="code-keyword">private</span> void isUserInRole() <span class="code-keyword">throws</span> WebApplicationException {
       <span class="code-keyword">if</span> (jaxwsContext.getSecurityContext() != <span class="code-keyword">null</span>) {
           <span class="code-comment">// soap invocation
</span>           jaxwsContext.getSecurityContext().isUserInRole(theRole);
       } <span class="code-keyword">else</span> {
           <span class="code-comment">// http-only jaxrs one
</span>           jaxrsContext.getSecurityContext().isUserInRole(theRole);
       }  
   }
}</pre>
</div></div>  

<p>Note that injected context instances (jaxwsContext and jaxrsContext) are in fact thread-local proxies hence they will not be equal to null even if they do not represent a given request. For example, jaxrsContext will not be equal to null even if it's not a JAXWS invocation which is being processed at the moment.</p>

<p>However, if say a (JAXWS or JAXRS) SecurityContext needs to be accessed then it will be set in, say, jaxwsContext only if it's a JAXWS/SOAP invocation. For this reason it can be handy using a composite CXF JAXRS MessageContext when accessing a JAXRS-specific context information when combining JAXWS and JAXRS as one can easily check if it's actually a JAXRS request by simply checking an individual context like SecurityContext or UriInfo for null.</p>

<p>Using individual contexts like JAXRS SecurityContext might be less attractive :</p>

<div class="code"><div class="codeContent">
<pre class="code-java">@WebService
<span class="code-keyword">public</span> class CustomerService {
   @Resource WebServiceContext jaxwsContext;
   <span class="code-comment">// @Resource can be applied too
</span>   @Context SecurityContext jaxrsSecurityContext;  
}</pre>
</div></div>

<p>as some methods of SecurityContext return boolean values so only throwing a runtime exception can reliably indicate that this context is actually not in scope.</p>

<p>Note that if you do not share the same service methods between JAXRS and JAXWS invocations then you can directly access corresponding contexts : </p>

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

   @Resource WebServiceContext jaxwsContext;
   @Resource MessageContext jaxrsContext;

   @WebMethod
   <span class="code-keyword">public</span> void doItSoap(<span class="code-object">String</span> b) {
       isUserInRole(jaxwsContext.getSecurityContext().getPrincipal());
   };

   @POST
   <span class="code-keyword">public</span> void doItSoap(<span class="code-object">String</span> b) {
       isUserInRole(jaxwsContext.getSecurityContext().getPrincipal());
   }

   <span class="code-keyword">private</span> void isUserInRole(Principal p) <span class="code-keyword">throws</span> WebApplicationException {
       ...  
   }
}</pre>
</div></div>

<p>Another option is to avoid the use of contexts in the service code and deal with them in CXF interceptors or JAXRS filters. Sometimes it's possible to avoid the use of contexts altogether. For example, Spring Security can be used to secure a given service at an individual method level.     </p>

<h2><a name="JAX-RS-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>)
    @Produces(<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). For example :</p>
<div class="code"><div class="codeContent">
<pre class="code-xml"><span class="code-tag">&lt;aop:config proxy-target-class=<span class="code-quote">"true"</span>/&gt;</span></pre>
</div></div>

<h2><a name="JAX-RS-AreasforimprovementandTODOlist."></a>Areas for improvement and TODO list.</h2>

<p> Optional auto-discovery of providers (classpath scanning) - needed for TCK <br/>
 Support for Spring lifecycles (prototype, etc)</p>

<p> ASM-generate XmlJavaTypeAdapters when needed<br/>
 Provide JAXP-Source provider capable of applying preconfigured XSLT templates or XPath expressions<br/>
 Create some useful request filter implementations : JavaScript code generation, WADL or JavaDocs generation</p>

<h3><a name="JAX-RS-Howtocontribute"></a>How to contribute</h3>

<p> CXF JAX-RS implementation sits on top of the core CXF runtime and is quite self-contained and isolated from other CXF modules such as jaxws and simple frontends.</p>

<p> Please check this <span class="nobr"><a href="http://issues.apache.org/jira/secure/IssueNavigator.jspa?reset=true&amp;mode=hide&amp;pid=12310511&amp;sorter/order=DESC&amp;sorter/field=priority&amp;resolution=-1&amp;component=12311911" title="Visit page outside Confluence" rel="nofollow">list<sup><img class="rendericon" src="/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"/></sup></a></span> and see if you are interested in fixing one of the issues.</p>

<p> If you are about to submit a patch after building a trunk/rt/frontend/jaxrs, then please also run JAX-RS system tests in trunk/systests :<br/>
 &gt; mvn test -Dtest=JAXRS* </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