@javax.ws.rs.ApplicationPath("webresources")
public class ApplicationConfig extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> resources = new java.util.HashSet<Class<?>>();
try {
Class jsonProvider = Class.forName("org.glassfish.jersey.jackson.JacksonFeature");
resources.add(jsonProvider);
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(getClass().getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
addRestResourceClasses(resources);
return resources;
}
private void addRestResourceClasses(Set<Class<?>> resources) {
resources.add(com.example.jaxrsexam.D3Resource.class);
}
}
警告: StandardWrapperValve[com.snail.uploadexam.ApplicationConfig]: Servlet.service() for servlet com.snail.exampleweb.ApplicationConfig threw exception java.lang.ClassNotFoundException: com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector not found by com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider [129]
@javax.ws.rs.ApplicationPath("webresources")
public class ApplicationConfig extends ResourceConfig {
public ApplicationConfig() {
this
.packages("com.snail.waf21.rest")
// -- Jacson
.register((new JacksonJaxbJsonProvider(new ObjectMapper(),
JacksonJaxbJsonProvider.DEFAULT_ANNOTATIONS)))
// -- JSONP
.register(org.glassfish.jersey.jackson.JacksonFeature.class);
}
}
ResourceConfig? も Application を継承しているpackage com.example.jaxrsexam;
import java.util.Date;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "d3")
public class D3Bean {
private Date date;
private int freq;
public D3Bean() {
super();
}
public D3Bean(Date date, int freq) {
this();
this.date = date;
this.freq = freq;
}
@XmlElement
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
@XmlElement
public int getFreq() {
return freq;
}
public void setFreq(int freq) {
this.freq = freq;
}
}
→ Lombokと組み合わせてgetter/setterを書きたくない方は「Glassfish JAX-RS Lombok と組み合わせる」を参照
package com.example.jaxrsexam;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.enterprise.context.RequestScoped;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.server.JSONP;
/**
* REST Web Service
*
* @author atsushi
*/
@Path("d3")
@RequestScoped
public class D3Resource {
@Context
private UriInfo context;
/**
* Creates a new instance of D3Resource
*/
public D3Resource() {
}
/**
* JSONを返す.
* @return Object
*/
@GET
@Path("json")
@Produces(MediaType.APPLICATION_JSON)
public List<D3Bean> getJson() throws Exception {
return createDummyData();
}
/**
* XMLを返す.
* @return Object
*/
@GET
@Path("xml")
@Produces(MediaType.APPLICATION_XML)
public List<D3Bean> getXml() throws Exception {
return createDummyData();
}
/**
* XMLを返す.
* @return Object
*/
@GET
@Path("text")
@Produces(MediaType.TEXT_PLAIN)
public String getText() throws Exception {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
StringBuilder sb = new StringBuilder();
sb.append("date,freq\n");
for (D3Bean bean : createDummyData()) {
sb.append(df.format(bean.getDate()));
sb.append(",");
sb.append(bean.getFreq());
sb.append("\n");
}
return sb.toString();
}
/**
* JSONPを返す.
* JSONPを返すときには、MIME Type を application/javascript にする
* application/json だとダメ
* @return Object
*/
@GET
@Path("jsonp")
@JSONP(queryParam = "callback")
@Produces("application/javascript")
public List<D3Bean> getJsonp() {
return createDummyData();
}
/**
* エラーを返す.
* @return Object
*/
@GET
@Path("error")
@Produces(MediaType.TEXT_PLAIN)
public String getError() throws Exception {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
private List<D3Bean> createDummyData() {
long current = System.currentTimeMillis();
List<D3Bean> ret = new ArrayList<>();
for (int cnt = 0; cnt < 10; cnt++) {
ret.add(new D3Bean(new Date(current + cnt * 86400000L), cnt));
}
return ret;
}
}
[~]$ curl http://localhost:8080/JAX-RSExam/webresources/d3/json
[{"date":1371995770259,"freq":0},
{"date":1372082170259,"freq":1},
{"date":1372168570259,"freq":2},
{"date":1372254970259,"freq":3},
{"date":1372341370259,"freq":4},
{"date":1372427770259,"freq":5},
{"date":1372514170259,"freq":6},
{"date":1372600570259,"freq":7},
{"date":1372686970259,"freq":8},
{"date":1372773370259,"freq":9}]
[~]$ curl http://localhost:8080/JAX-RSExam/webresources/d3/jsonp?callback=jQuery12345678
jQuery12345678(
[{"date":1371995774786,"freq":0},
{"date":1372082174786,"freq":1},
{"date":1372168574786,"freq":2},
{"date":1372254974786,"freq":3},
{"date":1372341374786,"freq":4},
{"date":1372427774786,"freq":5},
{"date":1372514174786,"freq":6},
{"date":1372600574786,"freq":7},
{"date":1372686974786,"freq":8},
{"date":1372773374786,"freq":9}])
[~]$ curl http://localhost:8080/JAX-RSExam/webresources/d3/xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<d3Beans>
<d3><date>2013-06-23T22:56:27.035+09:00</date><freq>0</freq></d3>
<d3><date>2013-06-24T22:56:27.035+09:00</date><freq>1</freq></d3>
<d3><date>2013-06-25T22:56:27.035+09:00</date><freq>2</freq></d3>
<d3><date>2013-06-26T22:56:27.035+09:00</date><freq>3</freq></d3>
<d3><date>2013-06-27T22:56:27.035+09:00</date><freq>4</freq></d3>
<d3><date>2013-06-28T22:56:27.035+09:00</date><freq>5</freq></d3>
<d3><date>2013-06-29T22:56:27.035+09:00</date><freq>6</freq></d3>
<d3><date>2013-06-30T22:56:27.035+09:00</date><freq>7</freq></d3>
<d3><date>2013-07-01T22:56:27.035+09:00</date><freq>8</freq></d3>
<d3><date>2013-07-02T22:56:27.035+09:00</date><freq>9</freq></d3>
</d3Beans>
[~]$ curl http://localhost:8080/JAX-RSExam/webresources/d3/text
date,freq
2013-06-23 22:56:31,0
2013-06-24 22:56:31,1
2013-06-25 22:56:31,2
2013-06-26 22:56:31,3
2013-06-27 22:56:31,4
2013-06-28 22:56:31,5
2013-06-29 22:56:31,6
2013-06-30 22:56:31,7
2013-07-01 22:56:31,8
2013-07-02 22:56:31,9
[~]$ curl http://localhost:8080/JAX-RSExam/webresources/d3/error -I
HTTP/1.1 404 Not Found
X-Powered-By: Servlet/3.1 JSP/2.3 (GlassFish Server Open Source Edition 4.0 Java/Oracle Corporation/1.7)
Server: GlassFish Server Open Source Edition 4.0
Content-Language:
Content-Type: text/html
Date: Sun, 23 Jun 2013 13:56:44 GMT
Content-Length: 1082
@Path("d3")
@RequestScoped
public class D3Resource {
@GET
@Path("json")
@Produces(MediaType.APPLICATION_JSON)
public List<D3Bean> getJson() throws Exception {
return createDummyData();
}
@GET
@Path("order")
public Response order(@QueryParam("item") String item, @QueryParam("amount") int amount) {
// 注文処理
}
@GET
@Path("item/{id}")
public Response order(@PathParam("id") String itemId) {
// 商品検索処理
}
@POST
@Path("item")
public Response order(@FormParam("id") String itemId, @FormParam("amount") int amount) {
// 商品受注処理
}
@POST
@Path("item")
public Response order(@BeanParam OrderBean order) {
// 商品受注処理
}
@Data
public class OrderBean {
@FormParam("id")
private String itemId;
@FormParam("amount")
private int amount;
}
cf. @Data は Lombok
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.TEXT_PLAIN)
public String order(Order order) {
return String.format("I got your order. Item : %s / Amount : %d", order.getItem(), order.getAmount());
}@Data
@NoArgsConstructor // jax-rs needs no arg constructor, XmlRootElement is not needed.
public class Order {
private String item;
private int amount;
}$.ajax({
url:url,
type:"POST",
data:JSON.stringify(args),
contentType:"application/json; charset=utf-8",
dataType:"text",
success: function(data){
console.log(data);
alert(data);
}
});
@POST
@Path("setNewItem/{id}")
@Consumes(MediaType.APPLICATION_XML)
public Response setNewItem(@PathParam("id") String itemId, javax.xml.bind.JAXBElement elem) {
// 商品登録処理
}
| MIME Type (@Consumes) | Data Type |
| */* | byte[] |
| */* | java.lang.String |
| */* | java.io.InputStream? |
| */* | java.io.Reader |
| */* | java.io.File |
| */* | javax.activation.DataSource? |
| text/xml, application/xml, application/-*+xml | javax.xml.transform.Source |
| text/-xml, application/xml, application/*+xml | javax.xml.bind.JAXBElement |
| application/x-www-form-urlencoded | MultivaluedMap?<String, String> |
| */* | javax.ws.rs.core.StreamingOutput? |
public class D3Resourc {
@Context
private UriInfo context;public class D3Resourc {
@EJB
private GeoEJB geoEJB;
public class D3Resourc {
@GET
public String doSomething(@Context HttpHeaders headers) {
// do something
}
}
public class D3Resourc {
@GET
public String doSomething(@CookieParam("sessionid") sessionId) {
// do something
}
}
@GET
@Path("error")
@Produces(MediaType.TEXT_PLAIN)
public String getError() throws Exception {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
throw new WebApplicationException(Response.Status.NOT_FOUND);
throw new WebApplicationException(
Response.status(400).entity("item not found").build());@Provider
public class BizExceptionMapper implements ExceptionMapper<BizException>{
@Override
public Response toResponse(BizException exception) {
return Response.status(418).type("application/json")
.entity("{code: " + exception.getCode() + ", message:" + exception.getMessage() + "}")
.build();
}
}
メソッド引数に @Context HttpServletRequest? request
/**
* JSONPを返す.
* JSONPを返すときには、MIME Type を application/javascript にする
* application/json だとダメ
* @return Object
*/
@GET
@Path("jsonp")
@JSONP(queryParam = "callback")
@Produces("application/javascript")
public List<D3Bean> getJsonp() {
return createDummyData();
}
jQuery12345678(
[{"date":1371995774786,"freq":0},
{"date":1372082174786,"freq":1},
{"date":1372168574786,"freq":2},
{"date":1372254974786,"freq":3},
{"date":1372341374786,"freq":4},
{"date":1372427774786,"freq":5},
{"date":1372514174786,"freq":6},
{"date":1372600574786,"freq":7},
{"date":1372686974786,"freq":8},
{"date":1372773374786,"freq":9}]) <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>JAX-RSExam</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>JAX-RSExam</name>
<properties>
<endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<compilerArguments>
<endorseddirs>${endorsed.dir}</endorseddirs>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<outputDirectory>${endorsed.dir}</outputDirectory>
<silent>true</silent>
<artifactItems>
<artifactItem>
<groupId>javax</groupId>
<artifactId>javaee-endorsed-api</artifactId>
<version>7.0</version>
<type>jar</type>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@GET
@Path("item/{id}")
@Produces({"application/javascript"})
public JSONWithPadding findItem(@PathParam("id") integer id, @QueryParam("callback") String callback) {
return new JSONWithPadding(ejb.findItem(id), callback);
} @GET
@Path("/download")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response download() throws UnsupportedEncodingException {
StringBuilder contents = new StringBuilder();
contents.append("日本語");
InputStream is = new ByteArrayInputStream(contents.toString().getBytes("UTF-8"));
String fname = URLEncoder.encode("日本語ファイル名.txt", "UTF-8");
return Response.ok(is)
.header("Content-disposition", "attachment; filename=" + fname)
.build();
}
<dependency>
<groupId>org.glassfish.main.extras</groupId>
<artifactId>glassfish-embedded-all</artifactId>
<version>3.1.2.2</version>
<scope>provided</scope>
</dependency>
import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataParam;
@Path("d3")
@RequestScoped
public class D3Resource {
@POST
@Path("convert")
@Consumes("multipart/form-data")
@Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_OCTET_STREAM})
public Response convert(
@FormDataParam("file") InputStream file,
@FormDataParam("file") FormDataContentDisposition fileDisposition,
@FormDataParam("action") String action) {
if (null == action) {
return Response.ok(
String.format("{\"name\":\"%s\",\"action\":\"%s\"}", fileDisposition.getFileName(), action))
.build();
} else {
return Response.ok(new BufferedInputStream(file))
.header("Content-disposition", "attachment; filename=" + fileDisposition.getFileName())
.build();
}
}
}
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>File Convert</title>
</head>
<body>
<h1>Convert</h1>
<form id="uploadForm" method="post" action="webresources/d3/convert" enctype="multipart/form-data">
<input type="file" name="file"/></br>
<input type="submit" name="action" value="convert"/>
<button type="button">get info</button> <!-- Default type is submit -->
</form>
</body>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
$("button").on('click', function() {
var $form = $('#uploadForm');
var fd = new FormData($form[0]);
var url = 'webresources/d3/convert';
$.ajax(url, {
type: 'post',
processData: false,
contentType: false,
data: fd,
dataType: 'html',
success: function(dataText) {
console.log(dataText);
var data = $.parseJSON(dataText);
alert(data.name + " is uploaded.");
}
});
});
</script>
</html>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>2.4.1</version>
<scope>provided</scope>
</dependency>
import org.glassfish.jersey.media.multipart.FormDataParam;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
@Path("d3")
@RequestScoped
public class D3Resource {
@POST
@Path("convert")
@Consumes("multipart/form-data")
@Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_OCTET_STREAM})
public Response convert(
@FormDataParam("file") InputStream file,
@FormDataParam("file") FormDataContentDisposition fileDisposition,
@FormDataParam("action") String action) {
if (null == action) {
return Response.ok(
String.format("{\"name\":\"%s\",\"action\":\"%s\"}", fileDisposition.getFileName(), action))
.build();
} else {
return Response.ok(new BufferedInputStream(file))
.header("Content-disposition", "attachment; filename=" + fileDisposition.getFileName())
.build();
}
}
}
package com.example.jaxrsexam;
import java.util.Set;
import javax.ws.rs.core.Application;
@javax.ws.rs.ApplicationPath("webresources")
public class ApplicationConfig extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> resources = new java.util.HashSet<Class<?>>();
try {
Class jsonProvider = Class.forName("org.glassfish.jersey.jackson.JacksonFeature");
// Class jsonProvider = Class.forName("org.glassfish.jersey.moxy.json.MoxyJsonFeature");
// Class jsonProvider = Class.forName("org.glassfish.jersey.jettison.JettisonFeature");
resources.add(jsonProvider);
// Add additional features such as support for Multipart.
Class multiPartFeature = Class.forName("org.glassfish.jersey.media.multipart.MultiPartFeature");
resources.add(multiPartFeature);
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(getClass().getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
addRestResourceClasses(resources);
return resources;
}
/**
* Do not modify addRestResourceClasses() method. It is automatically
* re-generated by NetBeans REST support to populate given list with all
* resources defined in the project.
*/
private void addRestResourceClasses(Set<Class<?>> resources) {
resources.add(com.example.jaxrsexam.D3Resource.class);
}
}
@GET
@Path("item")
public Response order(@FormParam("id") final String itemId) {
// 商品検索処理
}