javaweb.用Jesery 构建rest服务

REST概念:

每个资源由URI标识。
使用统一的接口。处理资源使用POST,GET,PUT,DELETE操作类似创建,读取,更新和删除(CRUD)操作。
无状态。每个请求是一个独立的请求。从客户端到服务器的每个请求都必须包含所有必要的信息,以便于理解。
通信都是通过展现。例如XML,JSON

1@Path ,定义路径。

2@GET@POST@PUT等,定义提交请求的方法。

3@Consumes,定义接收请求的参数格式,是JSONXML,还是form表单。

4@Produces,定义输出的格式,输出XMLJSON等格式。

5@XmlRootElement@XmlElement@XmlAttribute定义根元素、元素、属性,使用这些注解可以自定义xml的输出格式。

6@FormParam@QueryParam@PathParam,获取单个参数的三种方式:分别是从表单获取参数、从url问号之后获取参数、获取路径参数。还可以直接将POJO作为方法参数,根据接收的参数格式自动封装bean,比如底部代码中的formJson(Member member)方法。

7@Context,从容器的上下文获取HttpServletRequestHttpServletResponse等对象。

常见问题
官网
getstart
参考


  1. pom.xml

    <?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>xyz.bingone</groupId>
        <artifactId>JerseyTest</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>war</packaging>
        <dependencies>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.9</version>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
            </dependency>
    
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.10</version>
                <scope>test</scope>
            </dependency>
            <!-- Jersey -->
            <dependency>
                <groupId>com.sun.jersey</groupId>
                <artifactId>jersey-server</artifactId>
                <version>1.13</version>
            </dependency>
            <dependency>
                <groupId>com.sun.jersey</groupId>
                <artifactId>jersey-bundle</artifactId>
                <version>1.13</version>
            </dependency>
            <dependency>
                <groupId>com.sun.jersey</groupId>
                <artifactId>jersey-servlet</artifactId>
                <version>1.13</version>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>servlet-api</artifactId>
                <version>2.5</version>
            </dependency>
            <!-- Spring 3 dependencies -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>3.0.5.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>3.0.5.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
                <version>3.0.5.RELEASE</version>
            </dependency>
    
            <!-- Jersey + Spring -->
            <dependency>
                <groupId>com.sun.jersey.contribs</groupId>
                <artifactId>jersey-spring</artifactId>
                <version>1.13</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-core</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-context</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-web</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-beans</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-context</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.6</source>
                        <target>1.6</target>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    
    </project>
    
  2. web.xml
    下面的com.sun.jersey.spi.spring.container.servlet.SpringServlet
    是为了和Spring整合用的,如果不用Spring可以使用com.sun.jersey.spi.container.servlet.ServletContainerinit-parm 中是rest管理的包。

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee   http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>applicationContext.xml</param-value>
        </context-param>
    
        <listener>
            <listener-class>
                org.springframework.web.context.ContextLoaderListener
            </listener-class>
        </listener>
    
        <servlet>
            <servlet-name>Jersey Web Application</servlet-name>
            <servlet-class>
        com.sun.jersey.spi.spring.container.servlet.SpringServlet
            </servlet-class>
    
            <init-param>
                <param-name>
                    com.sun.jersey.config.property.packages
                </param-name>
                <param-value>xyz.bingone.resources</param-value>
            </init-param>
    
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>Jersey Web Application</servlet-name>
            <url-pattern>/resources/*</url-pattern>
        </servlet-mapping>
    
    </web-app>
  3. 在xyz.bingone.resources包中创建类

    package xyz.bingone.resources;
    import javax.ws.rs.GET;
    import javax.ws.rs.Path;
    import javax.ws.rs.Produces;
    import javax.ws.rs.core.MediaType;
    
    /**
     * Root resource (exposed at "myresource" path)
     */
    @Path("test")
    public class MyResource {
        /**
         * Method handling HTTP GET requests. The returned object will be sent
         * to the client as "text/plain" media type.
         *
         * @return String that will be returned as a text/plain response.
         */
        @GET
        @PATH("hello")
        @Produces(MediaType.TEXT_PLAIN)
        public String getIt(@QueryParam("n") int n) {
            return "Got it!" + n;
        }
    }
  4. 打包。访问地址localhost:8080/myresources/test/hello?=10
    结果Got it! 10


  5. 异常处理

    1. 抛出WebApplicationException或其子类

      public class CustomNotFoundException extends WebApplicationException {
      
        /**
        * Create a HTTP 404 (Not Found) exception.
        */
        public CustomNotFoundException() {
          super(Responses.notFound().build());
        }
      
        /**
        * Create a HTTP 404 (Not Found) exception.
        * @param message the String that is the entity of the 404 response.
        */
        public CustomNotFoundException(String message) {
          super(Response.status(Responses.NOT_FOUND).
          entity(message).type("text/plain").build());
        }
      }
      
      @Path("items/{itemid}/")
      public Item getItem(@PathParam("itemid") String itemid) {
        Item i = getItems().get(itemid);
        if (i == null) {
          throw new CustomNotFoundException("Item, " + itemid + ", is not found");
        }
      
        return i;
      }
    2. 使用ExceptionMapper,当有T异常抛出时,Jesery进行处理。
      @Provider
      public class EntityNotFoundMapper implements ExceptionMapper<javax.persistence.EntityNotFoundException> {
        public Response toResponse(javax.persistence.EntityNotFoundException ex) {
          return Response.status(404).
            entity(ex.getMessage()).
            type("text/plain").
            build();
        }
      }

注意

stackoverflow的回答
不要在类中获取response对其操作,因为改变其返回值不可取。
下面这个是对返回值为String的方法修改response无结果原因解释。

Here’s what’s happening:

The method executes, and you interact with the ServletResponse and set the status code to 500. But since you don’t write any data, the response isn’t committed.

Then the method returns a String value. Since Jersey has no way of knowing if you’ve interacted with the ServletResponse or not, it behaves normally.

A String method that returns implies a 200 response code (void implies 204, etc). Jersey tries to set the response code to the default, ultimately by calling setStatus(200) on the response instance. Since the response hasn’t been committed yet, this isn’t a problem, and the response of 500 is changed to 200.

The HttpServletResponse is committed and is sent back to the client.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值