Интерфейсы в Java: не может сделать реализованные методы защищенными или частными

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

Я столкнулся с этой проблемой, но я думаю, что решил ее в очень сложном пути - как хакеры используют, чтобы избежать использования кавычек. Я использовал это в сочетании с эмулированными подготовленными заявлениями. Я использую его, чтобы предотвратить все возможные типы инъекций SQL.

Мой подход:

  • Если вы ожидаете, что ввод будет целым, убедитесь, что он действительно целое число. В языке с переменным типом, таком как PHP, этот очень важен. Вы можете использовать, к примеру, это очень простое, но мощное решение: sprintf("SELECT 1,2,3 FROM table WHERE 4 = %u", $input);
  • Если вы ожидаете чего-то еще от целого шестнадцатеричного значения. Если вы отбросите его, вы полностью избежите ввода. В C / C ++ есть функция, называемая mysql_hex_string() , в PHP вы можете использовать bin2hex() . Не беспокойтесь о том, что экранированная строка будет иметь размер в 2 раза по сравнению с исходной длиной, потому что даже если вы используете mysql_real_escape_string, PHP должен выделять одну и ту же емкость ((2*input_length)+1), что то же самое.
  • hex метод часто используется при передаче двоичных данных, но я не вижу причин, почему бы не использовать его во всех данных для предотвращения атак SQL-инъекций. Обратите внимание, что вам необходимо предварительно добавить данные с помощью 0x или использовать функцию MySQL UNHEX.

Так, например, запрос:

SELECT password FROM users WHERE name = 'root'

Будет:

SELECT password FROM users WHERE name = 0x726f6f74

или

SELECT password FROM users WHERE name = UNHEX('726f6f74')

Hex - идеальный выход.

Разница между функцией UNHEX и префиксом 0x

В комментариях было некоторое обсуждение, поэтому я, наконец, хочу дать понять. Эти два подхода очень похожи, но в некоторых отношениях они немного различаются:

Префикс ** 0x ** может использоваться только для столбцов данных, таких как char, varchar, text, block, binary, и т. д. Кроме того, его использование немного сложно, если вы собираетесь вставить пустую строку. Вам придется полностью заменить его на '', или вы получите сообщение об ошибке.

UNHEX () работает в любом столбце; вам не нужно беспокоиться о пустой строке.


Hex-методы часто используются в качестве атак

Обратите внимание, что этот шестиугольный метод часто используется как атака SQL-инъекции, где целые числа точно так же, как и строки mysql_real_escape_string. Тогда вы можете избежать использования кавычек.

Например, если вы просто делаете что-то вроде этого:

"SELECT title FROM article WHERE id = " . mysql_real_escape_string($_GET["id"])

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

SELECT ... WHERE id = -1 union all select table_name from information_schema.tables

и теперь просто извлеките структуру таблицы:

SELECT ... WHERE id = -1 union all select column_name from information_schema.column где table_name = 0x61727469636c65

И тогда просто выберите нужные данные. Разве это не круто?

Но если кодер инъекционного сайта будет шестнадцатеричным, инъекция не будет возможна, потому что запрос будет выглядеть следующим образом: SELECT ... WHERE id = UNHEX('2d312075...3635')

27
задан N.N. 27 November 2012 в 12:41
поделиться

7 ответов

читайте это .

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

это, что Вы хотите?

24
ответ дан duffymo 28 November 2019 в 05:05
поделиться

Когда я бодал против этого, я использую пакет доступный внутренний или вложенный класс для реализации интерфейса, продвигая реализованный метод из общедоступного класса.

Обычно это - потому что у меня есть класс с определенным общедоступным API, который должен реализовать что-то еще для получения, это - сделанное задание (довольно часто, потому что что-то еще было обратным вызовом, замаскированным как интерфейс < grin>) - это происходит много с вещами как Сопоставимый. Я не хочу общедоступный API, загрязненный (вынужденная общественность) интерфейсная реализация.

Hope это помогает.

кроме того, если Вы действительно хотите методы, получил доступ только пакетом, Вы не хотите защищенный спецификатор объема, Вы хотите (опущенный) спецификатор объема значения по умолчанию. Используя защищенный, конечно, позволит подклассам видеть методы.

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

8
ответ дан Lawrence Dol 28 November 2019 в 05:05
поделиться

Вы классифицируете, может использовать защиту пакета и все еще реализовать интерфейс:

class Foo implements Runnable 
{
    public void run()
    {
    }
}

, Если Вы хотите, чтобы некоторые методы были защищены / пакет и другие не, он кажется, что Ваши классы несут больше чем одну ответственность и должны быть разделены на несколько.

Редактирование после чтения комментариев к этому и другим ответам:

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

Вместо этого думайте частный / защищенные методы как определение контракта для подклассов и используйте интерфейсы для определения контракта с внешним миром.

, О, и человеку, который решил, мой пример должен использовать K& R заключение в фигурные скобки: если это определяется в терминах Сервиса, уверенного. Иначе разве Вы не можете найти, что что-нибудь лучше делает с Вашим временем?

11
ответ дан kdgregory 28 November 2019 в 05:05
поделиться

Этот вопрос основан на неправильном операторе:

я знаю, что интерфейс должен быть общедоступен

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

проблема, я не могу сделать интерфейс, или реализованные методы защитили

Здесь, это:

C:\oreyes\cosas\java\interfaces>type a\*.java
a\Inter.java
package a;

interface Inter {
    public void face();
}

a\Face.java
package a;

class Face implements Inter {
    public void face() {
        System.out.println( "face" );
    }
}


C:\oreyes\cosas\java\interfaces>type b\*.java
b\Test.java

package b;
import a.Inter;
import a.Face;

public class Test {
    public static void main( String [] args ) {
        Inter inter = new Face();
        inter.face();
    }
}

C:\oreyes\cosas\java\interfaces>javac -d . a\*.java b\Test.java
b\Test.java:2: a.Inter is not public in a; cannot be accessed from outside package
import a.Inter;
        ^
b\Test.java:3: a.Face is not public in a; cannot be accessed from outside package
import a.Face;
        ^
b\Test.java:7: cannot find symbol
symbol  : class Inter
location: class b.Test
        Inter inter = new Face();
        ^
b\Test.java:7: cannot find symbol
symbol  : class Face
location: class b.Test
        Inter inter = new Face();
                          ^
4 errors

C:\oreyes\cosas\java\interfaces>

Следовательно, достигая, что Вы хотели, предотвращают интерфейс и использование класса за пределами пакета.

4
ответ дан OscarRyz 28 November 2019 в 05:05
поделиться

Вот то, как это могло быть сделано с помощью абстрактных классов.

единственное неудобное - то, что это заставляет Вас "разделить на подклассы".

Согласно руководству Java, необходимо последовать тому совету "большинство" времен, но я думаю в этой ситуации, это будет в порядке.

public abstract class Ab { 
    protected abstract void method();
    abstract void otherMethod();
    public static void main( String [] args ) { 
        Ab a = new AbImpl();
        a.method();
        a.otherMethod();
    }
}
class AbImpl extends Ab {
    protected void method(){
        System.out.println( "method invoked from: " + this.getClass().getName() );
    }
    void otherMethod(){ 
        System.out.println("This time \"default\" access from: " + this.getClass().getName()  );
    }
}
3
ответ дан OscarRyz 28 November 2019 в 05:05
поделиться

Можно пойти с инкапсуляцией вместо наследования.

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

Тогда можно представить только, что Вы хотите.

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

0
ответ дан Michael Haren 28 November 2019 в 05:05
поделиться

Я просто создал бы абстрактный класс. Нет никакого вреда в нем.

0
ответ дан Hash 28 November 2019 в 05:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: