@SuppressWarnings("unused")
public class JsonRpcServer extends JsonRpcBasicServer {
	private static final Logger logger = LoggerFactory.getLogger(JsonRpcServer.class);

	private static final String GZIP = "gzip";
	private String contentType = JSONRPC_CONTENT_TYPE;

	/**
	 * Creates the server with the given {@link ObjectMapper} delegating
	 * all calls to the given {@code handler} {@link Object} but only
	 * methods available on the {@code remoteInterface}.
	 *
	 * @param mapper          the {@link ObjectMapper}
	 * @param handler         the {@code handler}
	 * @param remoteInterface the interface
	 */
	public JsonRpcServer(ObjectMapper mapper, Object handler, Class<?> remoteInterface) {
		super(mapper, handler, remoteInterface);
	}

	/**
	 * Creates the server with the given {@link ObjectMapper} delegating
	 * all calls to the given {@code handler}.
	 *
	 * @param mapper  the {@link ObjectMapper}
	 * @param handler the {@code handler}
	 */
	public JsonRpcServer(ObjectMapper mapper, Object handler) {
		super(mapper, handler, null);
	}

	/**
	 * Creates the server with a default {@link ObjectMapper} delegating
	 * all calls to the given {@code handler} {@link Object} but only
	 * methods available on the {@code remoteInterface}.
	 *
	 * @param handler         the {@code handler}
	 * @param remoteInterface the interface
	 */
	public JsonRpcServer(Object handler, Class<?> remoteInterface) {
		super(new ObjectMapper(), handler, remoteInterface);
	}

	/**
	 * Creates the server with a default {@link ObjectMapper} delegating
	 * all calls to the given {@code handler}.
	 *
	 * @param handler the {@code handler}
	 */
	public JsonRpcServer(Object handler) {
		super(new ObjectMapper(), handler, null);
	}

	/**
	 * Handles a portlet request.
	 *
	 * @param request  the {@link ResourceRequest}
	 * @param response the {@link ResourceResponse}
	 * @throws IOException on error
	 */
	public void handle(ResourceRequest request, ResourceResponse response) throws IOException {
		logger.debug("Handing ResourceRequest {}", request.getMethod());
		response.setContentType(contentType);
		InputStream input = getRequestStream(request);
		OutputStream output = response.getPortletOutputStream();
		handleRequest(input, output);
		// fix to not flush within handleRequest() but outside so http status code can be set
		output.flush();
	}

	private InputStream getRequestStream(ResourceRequest request) throws IOException {
		if (request.getMethod().equals("POST")) {
			return request.getPortletInputStream();
		} else if (request.getMethod().equals("GET")) {
			return createInputStream(request);
		} else {
			throw new IOException("Invalid request method, only POST and GET is supported");
		}
	}

	private static InputStream createInputStream(ResourceRequest request) throws IOException {
		return createInputStream(request.getParameter(METHOD), request.getParameter(ID), request.getParameter(PARAMS));
	}

	/**
	 * Handles a servlet request.
	 *
	 * @param request  the {@link HttpServletRequest}
	 * @param response the {@link HttpServletResponse}
	 * @throws IOException on error
	 */
	public void handle(HttpServletRequest request, HttpServletResponse response) throws IOException {
		logger.debug("Handling HttpServletRequest {}", request);
		response.setContentType(contentType);
		OutputStream output = response.getOutputStream();
		InputStream input = getRequestStream(request);
		int result = ErrorResolver.JsonError.PARSE_ERROR.code;
		int contentLength = 0;
		ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
		try {
			String acceptEncoding = request.getHeader(ACCEPT_ENCODING);
			result = handleRequest0(input, output, acceptEncoding, response, byteOutput);

			contentLength = byteOutput.size();
		} catch (Throwable t) {
			if (StreamEndedException.class.isInstance(t)) {
				logger.debug("Bad request: empty contents!");
			} else {
				logger.error(t.getMessage(), t);
			}
		}
		int httpStatusCode = httpStatusCodeProvider == null ? DefaultHttpStatusCodeProvider.INSTANCE.getHttpStatusCode(result)
				: httpStatusCodeProvider.getHttpStatusCode(result);
		response.setStatus(httpStatusCode);
		response.setContentLength(contentLength);
		byteOutput.writeTo(output);
		output.flush();
	}

	private InputStream getRequestStream(HttpServletRequest request) throws IOException {
		InputStream input;
		if (request.getMethod().equals("POST")) {
			input = request.getInputStream();
		} else if (request.getMethod().equals("GET")) {
			input = createInputStream(request);
		} else {
			throw new IOException("Invalid request method, only POST and GET is supported");
		}
		return input;
	}

	private int handleRequest0(InputStream input, OutputStream output, String contentEncoding, HttpServletResponse response, ByteArrayOutputStream byteOutput) throws IOException {
		return handleRequest(input, byteOutput);
	}

	private static InputStream createInputStream(HttpServletRequest request) throws IOException {
		String method = request.getParameter(METHOD);
		String id = request.getParameter(ID);
		String params = request.getParameter(PARAMS);
		if (method == null && id == null && params == null) {
			return new ByteArrayInputStream(new byte[]{});
		} else {
			return createInputStream(method, id, params);
		}
	}

	public void setContentType(String contentType) {
		this.contentType = contentType;
	}

} public static final String DATA = "data"; public static final String ERROR = "error"; public static final String ERROR_MESSAGE = "message"; public static final String RESULT = "result"; public static JsonNode decodeAnswer(ByteArrayOutputStream byteArrayOutputStream) throws IOException {
	return mapper.readTree(byteArrayOutputStream.toString(JSON_ENCODING));
} public static JsonNode getFromArrayWithId(final JsonNode node, final int id) {
	for (JsonNode n : node) {
		if (n.get(JsonRpcBasicServer.ID).asInt() == id) {
			return n;
		}
	}
	throw new IllegalStateException("could not find in " + node + " id " + id);
} public static HashMap<String, Object> messageWithListParams(final Object id, final String methodName, final Object... args) throws JsonProcessingException {
	return messageOfStream(id, methodName, Arrays.asList(args));
} public static InputStream multiMessageOfStream(Object... args) throws JsonProcessingException {
	return createStream(args);
} public static ByteArrayOutputStream toByteArrayOutputStream(byte[] data) throws IOException {
	ByteArrayOutputStream result = new ByteArrayOutputStream(data.length);
	result.write(data);
	return result;
}
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.googlecode.jsonrpc4j.JsonRpcServer;
import org.easymock.EasyMock;
import org.easymock.Mock;
import org.easymock.MockType;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.util.StreamUtils;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import static com.googlecode.jsonrpc4j.JsonRpcBasicServer.DATA;
import static com.googlecode.jsonrpc4j.JsonRpcBasicServer.ERROR;
import static com.googlecode.jsonrpc4j.JsonRpcBasicServer.ERROR_MESSAGE;
import static com.googlecode.jsonrpc4j.JsonRpcBasicServer.RESULT;
import static com.googlecode.jsonrpc4j.util.Util.decodeAnswer;
import static com.googlecode.jsonrpc4j.util.Util.getFromArrayWithId;
import static com.googlecode.jsonrpc4j.util.Util.messageWithListParams;
import static com.googlecode.jsonrpc4j.util.Util.multiMessageOfStream;
import static com.googlecode.jsonrpc4j.util.Util.toByteArrayOutputStream;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
package com.googlecode.jsonrpc4j.server;




public abstract class JsonRpcServerBatchTest {
    @Mock(type = MockType.NICE)
    protected JsonRpcServerTest.ServiceInterface mockService;
    protected JsonRpcServer jsonRpcServer;

    @Test
    public void parallelBatchProcessingTest() throws Exception {
        EasyMock.expect(mockService.testMethod("Parameter1")).andReturn("Result1");
        EasyMock.expect(mockService.testMethod("Parameter2")).andReturn("Result2");
        EasyMock.replay(mockService);

        InputStream inputStream = multiMessageOfStream(
                messageWithListParams(1, "testMethod", "Parameter1"),
                messageWithListParams(2, "testMethod", "Parameter2"));

        MockHttpServletRequest request = new MockHttpServletRequest("POST", "/test-post");
        MockHttpServletResponse response = new MockHttpServletResponse();

        request.setContent(StreamUtils.copyToByteArray(inputStream));

        jsonRpcServer.handle(request, response);

        assertEquals(HttpServletResponse.SC_OK, response.getStatus());
        JsonNode answer = decodeAnswer(toByteArrayOutputStream(response.getContentAsByteArray()));