Detect a dropper with items in it without /testfor

The detect function of /execute does not accept NBT data, only an ID and Damage value.

You will instead need to use /testforblock, and if needing multiplayer-friendliness, mixing it with CommandStats.

Prerequisites:

Objective to hold the CommandStats value.

/scoreboard objectives add CraftSuccess dummy

Applying the AffectedBlocks trigger to players, which will set the player's score based on the success of commands that specifically affect blocks, such as /testforblock. This may need to run on a clock in the event new players can join at any time.

/stats entity @a set AffectedBlocks @a[c=1] CraftSuccess

In order for CommandStats to modify a target's score, that target must be tracked on the scoreboard prior. This may also need to run on a clock for the same reason as before.

/scoreboard players add @a CraftSuccess 0

Detection:

The following must be run in numerical order.

  1. Cause players to run the necessary /testforblock command.

    /execute @a ~ ~ ~ /testforblock ~ ~-1 ~ minecraft:dropper 1 {Items:[{id:"minecraft:blaze_rod",Slot:1b,Count:1b,Damage:0s},{id:"minecraft:blaze_rod",Slot:4b,Count:1b},{id:"minecraft:stick",Slot:7b,Count:1b}]}
    
  2. As a result, the executing player will have their own "CraftSuccess" score set equal to the number of blocks found by the /testforblock command. If the command failed, their score is set to 0. If the command succeeded, their score is set to 1. You'd then target players based on their score.

    /scoreboard players set @a[score_CraftSuccess_min=1] LSC 1
    

As a side-note, you should never mix @a as an executor and @p as the nested command's target if you're intended to target the same player. While @a can target dead players, @p cannot. That means that while the executor can run /execute while they're dead, they will not target themselves and instead target the nearest-living player. This can severely hurt accuracy and possibly break a target-sensitive mechanism.

The solution is to use the same selector when needed. For dead player targeting, you'd use @a as the executor with @a[c=1] as the nested selector:

/execute @a ~ ~ ~ /say @a[c=1]

For living-only players, you'd use @e[type=Player] with @p:

/execute @e[type=Player] ~ ~ ~ /say @p

It is also for this reason that CommandStat targets should use @a[c=1] when working with players, as this ensures there will not be an unintended target having their score modified.