JSON-PRC запрос из Java приложения к биллингу

Материал из BiTel WiKi

Перейти к: навигация, поиск

Пример работы взят из исходного кода системы BGCRM.

Для работы используется библиотека JSON Jackson.

Загрузка библиотеки производится из Maven репозитария: [1]

Понадобятся библиотеки: jackson-core.jar, ackson-databind.jar, jackson-annotations.jar. Также можно получить из из дистрибутива биллинга.

Класс-запрос:

public class RequestJsonRpc
{
	private final String module;
	private final int moduleId;
	private final String service;
	private final String method;
 
	private final Map<String, Object> params = new HashMap<String, Object>();
 
	public RequestJsonRpc( String module, String service, String method )
	{
		this( module, 0, service, method );
	}
 
	public RequestJsonRpc( String module, int moduleId, String service, String method )
	{
		this.module = module;
		this.moduleId = moduleId;
		this.service = service;
		this.method = method;
	}
 
	public String getUrl()
	{
		StringBuilder result = new StringBuilder( module );
 
		if( moduleId > 0 )
		{
			result.append( "/" );
			result.append( moduleId );
		}
		result.append( "/" );
		result.append( service );
 
		return result.toString();
	}
 
	public String getMethod()
	{
		return method;
	}
 
	public void setParam( String name, Object value )
	{
		params.put( name, value );
	}
 
	public void setParamContractId( int value )
	{
		params.put( "contractId", value );
	}
 
	public Map<String, Object> getParams()
	{
		return params;
	}
}

Метод отправки запроса:

private JsonNode postData( RequestJsonRpc request, UserAccount user )
    		throws Exception
    	{
    		JsonNode result = null;
 
    		ObjectNode rootObject = m.createObjectNode();
    		rootObject.put( "method", request.getMethod() );
 
    		ObjectNode userObject = rootObject.putObject( "user" );
    		userObject.put( "user", user.getLogin() );
    		userObject.put( "pswd", user.getPassword() );
 
    		ObjectNode paramsObject = rootObject.putObject( "params" );
    		for( Map.Entry<String, Object> me : request.getParams().entrySet() )
    		{
    			paramsObject.putPOJO( me.getKey(), me.getValue() );
    		}
 
    		URL fullUrl = new URL( url.toString() + "/json/" + request.getUrl() );
 
    		HttpURLConnection con = (HttpURLConnection)fullUrl.openConnection();
    		con.setRequestMethod( "POST" );    		
    		con.setDoOutput( true );
    		con.setDoInput( true );
 
    		con.setRequestProperty( "Content-type", "application/json; charset=UTF-8" );
 
    		String serialized = m.writer().writeValueAsString( rootObject );
 
    		if( log.isDebugEnabled() )
			{
				log.debug( this.hashCode() + " " + fullUrl );
				log.debug( this.hashCode() + " " + (serialized.length() < LOGGING_REQUEST_TRIM_LENGTH ? serialized : serialized.substring( 0, LOGGING_REQUEST_TRIM_LENGTH )) );
			}
 
    		new PrintStream( con.getOutputStream(), true, requestEncoding ).print( serialized );
 
    		if( con.getResponseCode() == HttpURLConnection.HTTP_OK )
    		{
    			String response = new String( IOUtils.toByteArray( con.getInputStream() ), requestEncoding ); 
 
    			result = m.readTree( response );
 
    			if( log.isDebugEnabled() )
    			{
    				final int len = response.length();
    				log.debug( this.hashCode() + " [ length = " + len + " ] xml = " +
    						   ( len > LOGGING_RESPONSE_TRIM_LENGTH ? response.substring( 0, LOGGING_RESPONSE_TRIM_LENGTH ) + "..." : response ) );
    			}
 
    			con.disconnect();
    		}
 
    		return result;
    	}

Метод проверки статуса ответа:

private void checkDocumentStatus( JsonNode rootNode, User user )
    	throws BGException
    {
    	String status = rootNode.path( "status" ).textValue();
    	if( !"ok".equals( status ) )
    	{
    		throw new BGMessageException( "На запрос пользователя " + user.getTitle() + " биллинг вернул ошибку: " + rootNode.path( "message" ).textValue() );
    	}
    }

Библиотека Jackson позволяет сериализовать в JSON представление любой Java Bean объект, на основании get методов. И загружать извлекать данные из JSON в Java объекты. Некоторые примеры работы:

Удаление сервиса Inet:

RequestJsonRpc req = new RequestJsonRpc( INET_MODULE_ID, moduleId, "InetServService", "inetServDelete" );
req.setParam( "id", id );
 
transferData.postData( req, user );

Изменение сервиса Inet:

private static final String INET_MODULE_ID = "ru.bitel.bgbilling.modules.inet.api";
....
 
public void updateService( InetService inetServ, List<InetServiceOption> optionList, 
	                           boolean generateLogin, boolean generatePassword, long saWaitTimeout  )
    	throws BGException
    {
		RequestJsonRpc req = new RequestJsonRpc( INET_MODULE_ID, moduleId, "InetServService", "inetServUpdate" );
    	req.setParam( "inetServ", inetServ );
    	req.setParam( "optionList", optionList );
    	req.setParam( "generateLogin", generateLogin );
    	req.setParam( "generatePassword", generatePassword );
    	req.setParam( "saWaitTimeout", saWaitTimeout );
 
    	transferData.postData( req, user );
    }

Загрузка списка типов сервисов:

// определение объекта Mapper в TransferData
public static final ObjectMapper m = new ObjectMapper();
static
{
   // опция не ругаться, если какие-то опции не найдены
   m.configure( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false );
}
 
public List<InetServiceType> getServiceTypeList()
    	throws BGException
    {
		RequestJsonRpc req = new RequestJsonRpc( INET_MODULE_ID, moduleId, "InetServService", "inetServTypeList" );
    	try
		{
			return TransferData.m.readValue( transferData.postDataReturn( req, user ).traverse(),  
			                                 TransferData.m.getTypeFactory().constructCollectionType( List.class, InetServiceType.class ) );
		}
		catch( Exception e )
		{
			throw new BGException( e.getMessage(), e );
		}
    }

Получение сервиса:

public InetService getService( int id )
    	throws BGException
    {
    	RequestJsonRpc req = new RequestJsonRpc( INET_MODULE_ID, moduleId, "InetServService", "inetServGet" );
    	req.setParam( "inetServId", id );
 
    	JsonNode response = transferData.postDataReturn( req, user );
    	return TransferData.m.convertValue( response, InetService.class );
    }

Ссылка на документацию:

Личные инструменты