The stateful design, which fills up templates with a bunch of hidden html-input fields, in order to open web-pages in the same "state" as you left them and all sorts of other crap.
You also need to look into Portlets, which "splits" up a web-pages into seemingly stand-alone components. These are then combined into horribly complicated Servlets as you deploy, where http paramters are namespaced with some random _portletId=lsøjfksjo1920 things in order to figure out which parameters goes to which "part of the web-page". Again, all of this is so bad, you'd think it was a joke; but it was Java's offering for web-development, and a huge number of people CHOOSE that technology in the early 2000's.
Everything is broken :-)
It really should be taught in schools as how not to design anything. I actually once worked on some extension (at least I think it was) of Java Server Faces which sent serialized Java objects as hidden html-input elements (base64-encoded binary blobs) back and forth with each request(!!). At least I hope that was not part of the core JSF technology. You really should run away from most of the early Java web-tech, it truly was horrid.
It's also strange that a language, which was so "connected" to the early days of the web (even had their own html element <applet>) ended up with such strange things for web-development shortly after.