Подтвердить что ты не робот

Почему я получаю "Исключение: должен быть пойман или объявлен брошен", когда я пытаюсь скомпилировать код Java?

import java.awt.*;

import javax.swing.*;
import java.awt.event.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.security.*;
import java.io.*;


public class EncryptURL extends JApplet implements ActionListener {
  Container content;
  JTextField userName = new JTextField();
     JTextField firstName = new JTextField();
      JTextField lastName = new JTextField();
      JTextField email = new JTextField();
      JTextField phone = new JTextField();
      JTextField heartbeatID = new JTextField();
      JTextField regionCode = new JTextField();
      JTextField retRegionCode = new JTextField();
      JTextField encryptedTextField = new JTextField();

    JPanel finishPanel = new JPanel();


  public void init() {
    //setTitle("Book - E Project");
    setSize(800,600);
    content = getContentPane();
    content.setBackground(Color.yellow);
    content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));


    JButton submit = new JButton("Submit");

    content.add(new JLabel("User Name"));
    content.add(userName);

    content.add(new JLabel("First Name"));
    content.add(firstName);

    content.add(new JLabel("Last Name"));
    content.add(lastName);

    content.add(new JLabel("Email"));
    content.add(email);

    content.add(new JLabel("Phone"));
    content.add(phone);

    content.add(new JLabel("HeartBeatID"));
    content.add(heartbeatID);

    content.add(new JLabel("Region Code"));
    content.add(regionCode);

    content.add(new JLabel("RetRegionCode"));
    content.add(retRegionCode);

    content.add(submit);

    submit.addActionListener(this);


  }

  public void actionPerformed(ActionEvent e) {
    if(e.getActionCommand() == "Submit"){

        String subUserName = userName.getText();
        String subFName = firstName.getText();
        String subLName = lastName.getText();
        String subEmail = email.getText();
        String subPhone = phone.getText();
        String subHeartbeatID = heartbeatID.getText();
        String subRegionCode = regionCode.getText();
        String subRetRegionCode = retRegionCode.getText();

        String concatURL = "user="+ subUserName + "&f="+ subFName + "&l=" +subLName+ "&em=" + subEmail + "&p="+subPhone+"&h="+subHeartbeatID+"&re="+subRegionCode+ "&ret=" + subRetRegionCode;
        concatURL = padString(concatURL, ' ', 16);
        byte[] encrypted = encrypt(concatURL);
        String encryptedString = bytesToHex(encrypted);
        content.removeAll();
        content.add(new JLabel("Concatenated User Input -->" + concatURL));

        content.add(encryptedTextField);
        setContentPane(content);
    }
  }

  public static byte[] encrypt(String toEncrypt) throws Exception{
    try{
      String plaintext = toEncrypt;
      String key = "01234567890abcde";
      String iv = "fedcba9876543210";

      SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
      IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());

      Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
      cipher.init(Cipher.ENCRYPT_MODE,keyspec,ivspec);
      byte[] encrypted = cipher.doFinal(toEncrypt.getBytes());

      return encrypted;
    }
    catch(Exception e){

    }

  }

  public static byte[] decrypt(byte[] toDecrypt) throws Exception{
      String key = "01234567890abcde";
      String iv = "fedcba9876543210";

      SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
      IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());

      Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
      cipher.init(Cipher.DECRYPT_MODE,keyspec,ivspec);
      byte[] decrypted = cipher.doFinal(toDecrypt);

      return decrypted;
  }
  public static String bytesToHex(byte[] data) {
    if (data==null)
    {
      return null;
    }
    else
    {
      int len = data.length;
      String str = "";
      for (int i=0; i<len; i++)
      {
        if ((data[i]&0xFF)<16)
          str = str + "0" + java.lang.Integer.toHexString(data[i]&0xFF);
        else
          str = str + java.lang.Integer.toHexString(data[i]&0xFF);
      }
      return str;
    }
  }
  public static String padString(String source, char paddingChar, int size)
  {
    int padLength = size-source.length()%size;
    for (int i = 0; i < padLength; i++) {
      source += paddingChar;
    }
    return source;
  }
}

Я получаю незарегистрированное исключение

java.lang.Exception; must be caught or declared to be thrown
byte[] encrypted = encrypt(concatURL);

а также

.java:109: missing return statement

Может ли кто-нибудь помочь мне решить эти проблемы?

4b9b3361

Ответ 1

Все ваши проблемы вытекают из этого

byte[] encrypted = cipher.doFinal(toEncrypt.getBytes());
return encrypted;

которые заключены в блок try, catch, проблема в том, что если программа обнаружила исключение, вы ничего не возвращаете. Поместите его так (измените его, как ваша логика программы):

public static byte[] encrypt(String toEncrypt) throws Exception{
    try{
        String plaintext = toEncrypt;
        String key = "01234567890abcde";
        String iv = "fedcba9876543210";

        SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
        IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());

        Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE,keyspec,ivspec);
        byte[] encrypted = cipher.doFinal(toEncrypt.getBytes());

        return encrypted;
    } catch(Exception e){
        return null;            // Always must return something
    }
}

Для второго вы должны поймать Исключение из вызова метода шифрования, как это (также измените его, как указано в вашей программной логике):

public void actionPerformed(ActionEvent e)
  .
  .
  .
    try {
        byte[] encrypted = encrypt(concatURL);
        String encryptedString = bytesToHex(encrypted);
        content.removeAll();
        content.add(new JLabel("Concatenated User Input -->" + concatURL));

        content.add(encryptedTextField);
    setContentPane(content);
    } catch (Exception exc) {
        // TODO: handle exception
    }
}

Уроки, которые вы должны извлечь из этого:

  • Метод с возвращаемым типом должен всегда возвращать объект этого типа, я имею в виду во всех возможных сценариях
  • Все проверенные исключения должны обрабатываться всегда

Ответ 2

Проблема заключается в этом методе:

  public static byte[] encrypt(String toEncrypt) throws Exception{

Это подпись , которая в значительной степени говорит:

  • что имя метода: шифровать
  • какой параметр он получает: строка с именем toEncrypt
  • его модификатор доступа: public static
  • и если он может или не может выкинуть исключение при вызове.

В этом случае подпись метода говорит, что при вызове этот метод "мог" потенциально генерировать исключение типа "Исключение".

    ....
    concatURL = padString(concatURL, ' ', 16);
    byte[] encrypted = encrypt(concatURL); <-- HERE!!!!!
    String encryptedString = bytesToHex(encrypted);
    content.removeAll();
    ......

Итак, компиляторы говорят: либо вы окружаете это с помощью конструкции try/catch, либо объявляете метод (где используется), чтобы "исключить" его самостоятельно.

Реальная проблема - это определение метода шифрования. Никакой метод никогда не должен возвращать "Исключение", потому что он слишком общий и может скрыть некоторые другие виды исключения, лучше иметь конкретное исключение.

Попробуйте следующее:

public static byte[] encrypt(String toEncrypt) {
    try{
      String plaintext = toEncrypt;
      String key = "01234567890abcde";
      String iv = "fedcba9876543210";

      SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
      IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());

      Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
      cipher.init(Cipher.ENCRYPT_MODE,keyspec,ivspec);
      byte[] encrypted = cipher.doFinal(toEncrypt.getBytes());

      return encrypted;
    } catch ( NoSuchAlgorithmException nsae ) { 
        // What can you do if the algorithm doesn't exists??
        // this usually won't happen because you would test 
        // your code before shipping. 
        // So in this case is ok to transform to another kind 
        throw new IllegalStateException( nsae );
    } catch ( NoSuchPaddingException nspe ) { 
       // What can you do when there is no such padding ( whatever that means ) ??
       // I guess not much, in either case you won't be able to encrypt the given string
        throw new IllegalStateException( nsae );
    }
    // line 109 won't say it needs a return anymore.
  }

В основном в этом конкретном случае вы должны убедиться, что в системе имеется криптографический пакет.

Java нуждается в расширении для пакета криптографии, поэтому исключения объявляются как "проверенные" исключения. Для вас обращаться, когда их нет.

В этой небольшой программе вы ничего не можете сделать, если пакет криптографии недоступен, поэтому вы проверяете это на "время разработки". Если эти исключения выбрасываются, когда ваша программа запущена, это потому, что вы сделали что-то неправильно в "разработке", поэтому подкласс RuntimeException более уместен.

Последняя строка больше не требует оператора return, в первой версии вы ловили исключение и ничего не делали с этим, что неправильно.

try { 
    // risky code ... 
} catch( Exception e ) { 
    // a bomb has just exploited
    // you should NOT ignore it 
} 

// The code continues here, but what should it do???

Если код сбой, лучше Сбой быстро

Вот несколько связанных ответов:

Ответ 3

Первая ошибка

java.lang.Exception; должен быть пойман или объявлен брошенным байтом [] encrypted = encrypt (concatURL);

означает, что ваш метод encrypt генерирует исключение, которое не обрабатывается или не объявляется с помощью метода actionPerformed, где вы его вызываете. Прочитайте все об этом в Учебное пособие по исключениям Java.

У вас есть несколько вариантов, которые вы можете выбрать, чтобы получить код для компиляции.

  • Вы можете удалить throws Exception из своего метода encrypt и обработать исключение внутри encrypt.
  • Вы можете удалить блок try/catch из encrypt и добавить throws Exception и блок обработки исключений к вашему методу actionPerformed.

Как правило, лучше обрабатывать исключение на самом низком уровне, которое вы можете, вместо того, чтобы передавать его на более высокий уровень.

Вторая ошибка просто означает, что вам нужно добавить оператор return к тому, какой метод содержит строку 109 (также encrypt, в этом случае). В методе есть оператор return, но если вызывается исключение, оно может не быть достигнуто, поэтому вам нужно либо вернуться в блок catch, либо удалить try/catch из encrypt, как я уже упоминал ранее.

Ответ 4

Вам нужно решить, как вы хотите обрабатывать исключения, созданные методом encrypt.

В настоящее время encrypt объявляется с помощью throws Exception - однако в теле метода исключения попадают в блок try/catch. Я рекомендую вам:

  • удалите предложение throws Exception из encrypt и внутренне обработайте исключения (рассмотрите возможность записи сообщения журнала как минимум); или,
  • удалите блок try/catch из тела encrypt и затем запустите вызов encrypt с помощью try/catch (т.е. в actionPerformed).

В отношении ошибки компиляции вы ссылаетесь: если в блоке try encrypt было исключено исключение, то после завершения завершения catch ничего не возвращается. Вы можете обратиться к этому, сначала объявив возвращаемое значение как null:

public static byte[] encrypt(String toEncrypt) throws Exception{
  byte[] encrypted = null;
  try {
    // ...
    encrypted = ...
  }
  catch(Exception e){
    // ...
  }
  return encrypted;
}

Однако, если вы можете исправить большую проблему (стратегию обработки исключений), эта проблема позаботится о себе - особенно если вы выберете второй вариант, который я предложил.

Ответ 5

В actionPerformed(ActionEvent e) вы вызываете encrypt(), объявляемый throw Exception. Тем не менее, actionPerformed не улавливает это исключение (с try/catch вокруг вызова encrypt()) и не объявляет, что он выбрасывает Exception сам.

Однако ваш метод encrypt действительно не бросает Exception. Он проглатывает все Исключения, даже не записывая жалобу. (Плохая практика и плохой стиль!)

Кроме того, ваш метод encrypt выполняет следующие действия:

public static byte[] encrypt(String toEncrypt) throws Exception {
  try{
    ....
    return encrypted; // HERE YOU CORRECTLY RETURN A VALUE
  } catch(Exception e) {
  }
  // YOU DO NOT RETURN ANYTHING HERE
}

То есть, если вы поймаете какое-либо исключение, вы отмените его молча, а затем упадете со дна вашего метода encrypt, не вернув ничего. Это не будет компилироваться (как вы видите), потому что метод, объявленный для возврата значения, должен либо вернуть значение, либо выбросить исключение для каждого возможного пути кода.

Ответ 6

В вашем "шифрованном" методе вы должны либо избавиться от try/catch, либо вместо этого добавить try/catch, где вы вызываете encrypt (внутри "actionPerformed" ) или возвращать null внутри catch в шифровании (что второй ошибка.