Jersey REST WebServcie Example_weixin_33834628的博客-程序员宅基地

技术标签: java  测试  json  

1 介绍

1.1 什么是JAX-RS标准

JAX-RS是java领域的REST式的WEB服务的标准规范。它的目标是这样的:

(1)基于POJO,规定使用POJO来公布WEB资源

(2)以HTTP为中心,采用HTTP协议,无状态

(3)格式独立性,JAX-RS2.0对传输数据类型/格式的支持非常宽泛,允许在标准风格之上使用额外的数据类型

(4)容器独立性,JAX-RS2.0的应用可以部署在各种Servlet容器中,比如Tomcat/Jetty,也可以部署在JAX-RS容器中比如GlassFish

(5)内置于JavaEE,JAX-RS2.0是java ee规范的一部分,它定义了在一个JavaEE容器内的Web资源类的内部如何使用JavaEE的功能 和组件

1.2 什么是Jersey

Jersey是JAX-RS标准的参考实现。此外还有其他实现比如SpringMVC,CXF等等

2 基于Jersey构建Web服务

2.1 创建项目

这里和Spring整合在一起,无非就是把Service组件注入Resource对象

2.1.1 pom.xml

<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>JerseyExample</groupId>
	<artifactId>JerseyExample</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>JerseyExample</name>
	<description />
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<repositories>
		<repository>
			<id>snapshot-repository.java.net</id>
			<name>Java.net Snapshot Repository for Maven</name>
			<url>https://maven.java.net/content/repositories/snapshots/</url>
			<layout>default</layout>
		</repository>
	</repositories>

	<dependencies>
		<!-- Jersey server -->
		<dependency>
			<groupId>com.sun.jersey</groupId>
			<artifactId>jersey-server</artifactId>
			<version>1.8</version>
		</dependency>

		<!-- Jersey client -->
		<dependency>
			<groupId>com.sun.jersey</groupId>
			<artifactId>jersey-client</artifactId>
			<version>1.8</version>
		</dependency>

		<!-- http://mvnrepository.com/artifact/com.sun.jersey/jersey-json -->
		<dependency>
			<groupId>com.sun.jersey</groupId>
			<artifactId>jersey-json</artifactId>
			<version>1.8</version>
		</dependency>


		<!-- Spring 4 dependencies -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>4.1.6.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>4.1.6.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>4.1.6.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>4.1.6.RELEASE</version>
		</dependency>

		<!-- Jersey + Spring -->
		<dependency>
			<groupId>com.sun.jersey.contribs</groupId>
			<artifactId>jersey-spring</artifactId>
			<version>1.8</version>
			<exclusions>
				<exclusion>
					<groupId>org.springframework</groupId>
					<artifactId>spring</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.springframework</groupId>
					<artifactId>spring-core</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>

		<!-- 处理json -->
		<dependency>
			<groupId>com.sun.jersey</groupId>
			<artifactId>jersey-bundle</artifactId>
			<version>1.18.1</version>
		</dependency>

		<dependency>
			<groupId>com.sun.jersey.contribs</groupId>
			<artifactId>jersey-multipart</artifactId>
			<version>1.8</version>
		</dependency>

		<!-- jsp接口 -->
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.1</version>
			<scope>provided</scope>
		</dependency>
		<!-- servlet接口 -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
			<scope>provided</scope>
		</dependency>

	</dependencies>
	<build>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.3.2</version>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
				</configuration>
			</plugin>
			<plugin>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.2</version>
				<configuration>
					<version>3.1</version>
					<failOnMissingWebXml>false</failOnMissingWebXml>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

2.1.2 web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>JerseyExample</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  <context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath*:applicationContext.xml</param-value>
	</context-param>

	<listener>
		<listener-class>
			org.springframework.web.context.ContextLoaderListener
		</listener-class>
	</listener>

	<servlet>
		<servlet-name>jersey-serlvet</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>com.lin.jersey.resources</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>jersey-serlvet</servlet-name>
		<url-pattern>/rest/*</url-pattern>
	</servlet-mapping>
  
</web-app>

2.2 domain类

package com.lin.jersey.domain;

import java.io.Serializable;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class News implements Serializable {
	
	private static final long serialVersionUID = -4381505327088114370L;
	
	private int id;
	
	private String title;
	
	private String content;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	@Override
	public String toString() {
		return "News [id=" + id + ", title=" + title + ", content=" + content
				+ "]";
	}

}

需要在该类上使用注解@XmlRootElement,用于传输时JSON/XML与对象的转换

2.3 业务逻辑组件

一般把业务逻辑组件注入到Resource类,和MVC是一样的,JavaEE的REST服务只是把Controller换成了Resource,Service和DAO层是一样的。。。

package com.lin.jersey.service;

import java.util.ArrayList;
import java.util.List;

import com.lin.jersey.domain.News;

public class NewsServcieImpl {
	
	private List<News> newsDAO = new ArrayList<News>();
	
	public NewsServcieImpl()
	{
		for(int i=0;i<10;i++)
		{
			News news = new News();
			news.setId(i);
			news.setTitle("Title"+i);
			news.setContent("Content"+i);
			
			newsDAO.add(news);
		}
	}
	
	/**
	 * create
	 * @param news
	 */
	public void addNews(News news)
	{
		if(news != null)
		{
			newsDAO.add(news);
		}
	}
	
	/**
	 * delete
	 * @param id
	 */
	public void deleteNews(int id)
	{
		for(int i=0;i<newsDAO.size();i++)
		{
			if(newsDAO.get(i).getId() == id)
			{
				newsDAO.remove(i);
				return;
			}
		}
	}
	
	/**
	 * update
	 * @param news
	 */
	public void updateNews(News news)
	{
		News temp = null;
		for(int i=0;i<newsDAO.size();i++)
		{
			temp = newsDAO.get(i);
			if(temp.getId() == news.getId())
			{
				newsDAO.remove(i);
				newsDAO.add(news);
				return;
			}
		}
	}
	
	/**
	 * read
	 * @param id
	 * @return
	 */
	public News queryNews(int id)
	{
		for(News news : newsDAO)
		{
			if(news.getId() == id)
			{
				return news;
			}
		}
		return null;
	}
	
	/**
	 * read all
	 * @return
	 */
	public News[] queryAllNews()
	{
		News[] newsArray = new News[newsDAO.size()];
		for(int i=0;i<newsDAO.size();i++)
		{
			newsArray[i] = newsDAO.get(i);
		}
		return newsArray;
	}

}

2.4 Resource类

package com.lin.jersey.resources;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

import com.lin.jersey.domain.News;
import com.lin.jersey.service.NewsServcieImpl;

@Path("/news")
public class NewsResource {
	
	@Context
	private HttpServletRequest request;
	
	@Context
	private HttpServletResponse response;
	
	private NewsServcieImpl newsService;

	public NewsServcieImpl getNewsService() {
		return newsService;
	}

	public void setNewsService(NewsServcieImpl newsService) {
		this.newsService = newsService;
	}
	
	@POST
	@Consumes(MediaType.APPLICATION_JSON)
	public Response addNews(News news)
	{
		String result = news.toString();
		System.out.println(result);
		return Response.status(201).entity(result).build();
	}
	
	/**
	 * 以提交表单的方式访问REST服务
	 */
	@POST
	@Produces(MediaType.TEXT_HTML)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public void addNews(@FormParam("id")int id,@FormParam("title")String title,@FormParam("content")String content)
	{
		News news = new News();
		news.setId(id);
		news.setTitle(title);
		news.setContent(content);
		
		newsService.addNews(news);
		System.out.println(news.toString());
		try {
			request.getRequestDispatcher("/WEB-INF/success.jsp").forward(request, response);//在服务中进行页面跳转
		} catch (ServletException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 用URL的方式访问并提交参数到REST服务
	 * @param uriuInfo
	 * @return
	 */
	@Path("parameters")
	@GET
	@Produces({MediaType.APPLICATION_JSON})
	public News queryNews(@QueryParam("id")int id,@QueryParam("title")String title,@QueryParam("content")String content)
	{
		System.out.println("id:"+id+"\t"+"title:"+title+"\t"+"cotent:"+content);
		
		News news = new News();
		news.setId(id);
		news.setTitle(title);
		news.setContent(content);
		return news;
	}
	
	/**
	 * 默认的GET方法
	 * @return
	 */
	@GET
	@Produces({MediaType.APPLICATION_JSON})
	public News[] getAllNews()
	{
		return newsService.queryAllNews();
	}
}

关于注解:

@Context:把Servlet体系结构中的相关对象诸如到Resource对象

@Path:构成服务的URI

@GET@POST ,@PUT,@DELETE:作用于方法,表示客户端访问时使用HTTP哪种方法

@Produces:向客户端传输的数据形式

@Consumes:从客户端接受的数据的形式

@QueryParam:已GET方式访问服务时,URL中的参数与Resource类方法参数的对应

此外还有其他注解,用法可以看JAX-RS标准,在包javax.ws.rs内。

3 访问WEB服务

3.1 在浏览器中访问

3.2 使用Jersey客户端访问

package com.lin.jersey.test;

import java.util.HashMap;
import java.util.Map;

import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;

import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import com.lin.jersey.domain.News;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.UniformInterfaceException;
import com.sun.jersey.api.client.WebResource;

public class JerseyClient {

	public static void main(String[] args) {

		// testPost();
		//testGet();
		testGetWithParameter();
	}
      
        /**
        * POST 方法
        */
	private static void testPost() {
		Client client = Client.create();
		WebResource webResource = client
				.resource("http://localhost:8080/JerseyExample/rest/news");
		News news = new News();
		news.setId(20);
		news.setTitle("test");
		news.setContent("test");
		ClientResponse response;
		try {
			response = webResource.type("application/json").post(
					ClientResponse.class, news);
			System.out.print(response.toString());
		} catch (UniformInterfaceException ue) {
			System.out.print(ue.getMessage());
		}
	}
        
        /**
        * GET 方法
        */
	private static void testGet() {
		try {

			Client client = Client.create();

			WebResource webResource = client
					.resource("http://localhost:8080/JerseyExample/rest/news");

			ClientResponse response = webResource.accept("application/json")
					.get(ClientResponse.class);

			if (response.getStatus() != 200) {
				throw new RuntimeException("Failed : HTTP error code : "
						+ response.getStatus());
			}

			String output = response.getEntity(String.class);

			System.out.println("Output from Server .... \n");
			System.out.println(output);

		} catch (Exception e) {

			e.printStackTrace();

		}
	}


        /**
        * 有参数的GET方法
        */
	private static void testGetWithParameter() {
		
		try {

			Client client = Client.create();

			WebResource webResource = client
					.resource("http://localhost:8080/JerseyExample/rest/news/parameters")
					.queryParam("id","20").queryParam("title", "test").queryParam("content", "test");

			ClientResponse response = webResource.accept("application/json")
					.get(ClientResponse.class);

			if (response.getStatus() != 200) {
				throw new RuntimeException("Failed : HTTP error code : "
						+ response.getStatus());
			}

			String output = response.getEntity(String.class);

			System.out.println("Output from Server .... \n");
			System.out.println(output);

		} catch (Exception e) {

			e.printStackTrace();
		}
	}
}

4 REST安全

转载于:https://my.oschina.net/ChiLin/blog/692701

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_33834628/article/details/91736009

智能推荐

React 中嵌套路由_猕猴桃-HR的博客-程序员宅基地_react 嵌套路由

1: React 中嵌套路由:class App extends Component { render() { return ( &lt;div className="container"&gt; &lt;div className="jumbotron-fluid" py-4 mt-4&gt; &lt;Header a={1}&gt; &lt;/div&gt; &lt;div classN.

Drupal 7 模块 .info 文件介绍_stevenhzhang的博客-程序员宅基地

Drupal使用.info文件来保存关于主题(theme)和模块(modules)的基本数据(metadata)。图文中文详解Drupal 7模块中的.info文件。

AtCoder Regular Contest 101 F - Robots and Exits_RainbowCrown的博客-程序员宅基地

题意题意就是一个以为数轴上某些位置有出口,某些位置有机器人。然后你可以同时控制所以的机器人往左或往右走一格。机器人走到出口就会立即退出。求方案数。一个不同的方案数当且仅当有某个机器人从不同出口出去。思考历程这题我是某天晚上训练快结束时看到的。感觉很熟悉,因为以前似乎也有个机器人的题。然鹅想了很久的dp都感觉不太行。其实模型稍微转化一下模型就变成一个非常普及组的题目了。当然这个转化是真的奇妙。题解首先每个机器人其实都是独立的,而这个机器人只有两种情况对答案贡献,往左往右。具体怎么走.

如何在win10环境下编译安装go-talib包_42条巴别鱼的博客-程序员宅基地

如何在win10环境下编译安装go-talib包1. 背景talib是非常成熟的技术分析指标库,非常适用于开发基于技术指标的量化策略。我们CoinSmart团队之前的数据代码以go为主。为了利用充分复用已有代码,最好还是在go环境下开发。为此我们选择了github上的d4l3k作为talib的go封装,开发环境主要是windows10。d4l3k项目页面上关于windows环境下的安装介绍非常...

一些日语学习网站_bluesmile979的博客-程序员宅基地

 Super日语背诵:http://recite.super.yeshj.com/jp一些个人Blog: 霧のガーデン:http://blog.hjenglish.com/asfog  站长:asfog 标非新 然立译:http://www.donews.net/silentangel  站长:zhanglinan 青梅茶屋:http://blog.hjenglish.com/tinmei  站长

Mac应用开发--隐藏窗口里默认按钮(最大化、最小化、关闭等)的方法 NSWindowCloseButton..._weixin_30571465的博客-程序员宅基地

Mac 平台上的软件窗口里会默认存在一些按钮,比如最大化、最小化、关闭窗口等。下面的方法可以隐藏掉窗口的默认按钮。 例如我们要只保留关闭按钮,最简单的方法是:[[window standardWindowButton:NSWindowZoomButton] setHidden:YES];[[window standardWindowButton:NSWindowMiniat...

随便推点

腾讯面试:一条SQL语句执行得很慢的原因有哪些?---不看后悔系列_weixin_30466953的博客-程序员宅基地

说实话,这个问题可以涉及到 MySQL 的很多核心知识,可以扯出一大堆,就像要考你计算机网络的知识时,问你“输入URL回车之后,究竟发生了什么”一样,看看你能说出多少了。之前腾讯面试的实话,也问到这个问题了,不过答的很不好,之前没去想过相关原因,导致一时之间扯不出来。所以今天,我带大家来详细扯一下有哪些原因,相信你看完之后一定会有所收获,不然你打我。开始装逼:分类讨论一条 SQL 语句执行的...

request获得访问路径,端口,ip等_cxy_12345的博客-程序员宅基地_request获取ip和端口

System.out.println(request.getLocalAddr());System.out.println(request.getServerName());System.out.println(request.getRemoteAddr());//获得访问该服务的客户端的ip地址,大多数时候是真实的,但是当使用了代理,则不正确System.out.print...

人类离用真正的大脑进行人工智能研究还有多远?_中国财经IT的博客-程序员宅基地

在人工智能领域,神经网络的发明显然是受到了生物神经网络的启发,但是大脑里的学习过程真的和计算机中的算法一样吗?如果研究人员能够解答这一问题,也许可以发展出更加强大的深度学习模型,并进一步了解人类的智能。  经济日报-中国经济网科技频道了解到近日研究人员发表论文,表示他们发现一种算法,可以利用哺乳动物的神经元进行深度学习。而且他们的实验也用一种更接近生物学的方法,展示了真实的大脑如何进行深度学习

[jQ/PHP]再谈使用JS数组储值的运用(提交PHP处理)_dilunzhuang0924的博客-程序员宅基地

---------------------------------------------------------------------------------------------------从一个例子中看JS数组和对象的分工合作:/** * JS数组与对象使用.(传递多条json数据,实例局部) * @黑眼诗人 &lt;www.chenwei.ws&gt; */f...

oracle 日期绑定变量,Oracle将变量绑定到\u date参数E_李晓舟的博客-程序员宅基地

我正在编写使用Python脚本执行SQL(Oracle)语句的代码,如下所示:PYTHON:with open(os.path.join(WORKING_PATH, "sql", "fetchCalendar.sql"), 'r') asfetch_date = fetch.read()#(Some other code)CD = timestamp_tostring(ACTUALDATE)pri...

laravel8(一)Target class [XXXXXController] does not exist.错误的解决办法_camellias_的博客-程序员宅基地

Laravel 8配置好路由后,访问提示:Target class [XXXXXController] does not exist.错误。出现这个错误的原因是Laravel8对路由命名空间做出了更新(详见:路由命名空间更新),而我们仍然在使用Laravel6或者7版本的方式写路由。Laravel 8路由配置方式:use App\Http\Controllers\UserController; Route::get('/users', [UserController::class, 'ind

推荐文章

热门文章

相关标签