@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) { // 商品検索処理 }