I am following the tutorial on https://sawtooth.hyperledger.org/docs/core/releases/latest/_autogen/txn_submit_tutorial.html
I have made some changes just to learn about how things actually work, and this is the java code:
import com.google.protobuf.ByteString;
import com.mashape.unirest.http.Unirest;
import sawtooth.sdk.processor.Utils;
import sawtooth.sdk.protobuf.*;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Signature;
import java.security.spec.ECGenParameterSpec;
public class BatchSender {
    public static void main(String[] args) throws Exception{
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");
        ECGenParameterSpec parameterSpec = new ECGenParameterSpec("secp256k1");
        keyPairGenerator.initialize(parameterSpec);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        Signature ecdsaSign = Signature.getInstance("SHA256withECDSA");
        ecdsaSign.initSign(keyPair.getPrivate());
        byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
        String publicKeyHex = Utils.hash512(publicKeyBytes);
        ByteString publicKeyByteString = ByteString.copyFrom(new String(publicKeyBytes),"UTF-8");
        String payload = "{'key':1, 'value':'value comes here'}";
        String payloadBytes = Utils.hash512(payload.getBytes());
        ByteString payloadByteString  = ByteString.copyFrom(payload.getBytes());
        TransactionHeader txnHeader = TransactionHeader.newBuilder().
                setBatcherPubkeyBytes(publicKeyByteString).
                setFamilyName("plain_info").
                setFamilyVersion("1.0").
                addInputs("1cf1266e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7").
                setNonce("1").
                addOutputs("1cf1266e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7").
                setPayloadEncoding("application/json").
                setPayloadSha512(payloadBytes).
                setSignerPubkey(publicKeyHex).build();
        ByteString txnHeaderBytes = txnHeader.toByteString();
        ecdsaSign.update(txnHeaderBytes.toByteArray());
        byte[] txnHeaderSignature = ecdsaSign.sign();
        Transaction txn = Transaction.newBuilder().setHeader(txnHeaderBytes).setPayload(payloadByteString).setHeaderSignature(Utils.hash512(txnHeaderSignature)).build();
        BatchHeader batchHeader = BatchHeader.newBuilder().setSignerPubkey(publicKeyHex).addTransactionIds(txn.getHeaderSignature()).build();
        ByteString batchHeaderBytes = batchHeader.toByteString();
        ecdsaSign.update(batchHeaderBytes.toByteArray());
        byte[] batchHeaderSignature = ecdsaSign.sign();
        Batch batch = Batch.newBuilder().setHeader(batchHeaderBytes).setHeaderSignature(Utils.hash512(batchHeaderSignature)).addTransactions(txn).build();
        BatchList batchList = BatchList.newBuilder().addBatches( batch).build();
        ByteString batchBytes = batchList.toByteString();
        String serverResponse =  Unirest.post("http://rest-api:8080/batches").header("Content-Type","application/octet-stream").body(batchBytes.toByteArray()).asString().getBody();
        System.out.println(serverResponse);
    }
}
The docker log is as follows:
sawtooth-validator-default | [2017-11-21 08:20:09.842 DEBUG    interconnect] ServerThread receiving CLIENT_BATCH_SUBMIT_REQUEST message: 1242 bytes
sawtooth-validator-default | [2017-11-21 08:20:09.844 DEBUG    signature_verifier] batch failed signature validation: 30a2f4a24be3e624f5a35b17cb505b65cb8dd41600545c6dcfac7534205091552e171082922d4eb71f1bb186fe49163f349c604b631f64fa8f1cfea1c8bb2818
sawtooth-validator-default | [2017-11-21 08:20:09.844 DEBUG    interconnect] ServerThread sending CLIENT_BATCH_SUBMIT_RESPONSE to b'50b094689ac14b39'
The batch is getting rejected. How to solve this problem?