JAXB Unmarshal Exception - namespaces

I generated some classes off of an xsd that I made from a web service response that I am calling.
I'm getting an Exception when I run a JUnit test class that reads in an InputStream from the web service call.
I'm stuck as to what the exception means, so I'm looking for some ideas on things to check:
javax.xml.bind.UnmarshalException: Unexpected element {http://bar.foo.com/bbs}:rule
I have a class in my generated classes at:
com.foo.bar.bbs.Rule
Does the Exception mean I do not have the Rule class in the proper package?

The following are some things to check:
#XmlRootElement
Check that the Rule class is annotated with #XmlRootElement:
#XmlRootElement
public class Rule {
}
#XmlElementDecl
Or that there is a corresponding #XmlElementDecl in the ObjectFactory class:
#XmlElementDecl(namespace = "http://bar.foo.com/bbs", name = "root")
public JAXBElement<Root> createCustomer(Root value) {
return new JAXBElement<BigInteger>(_ROOT_QNAME, Root.class, null, value);
}
#XmlSchema
You will also need to ensure that the namespace information is specified correctly. A package-info class was probably generated something like the following for you. Ensure the correct namespace is specified.
#XmlSchema(
namespace = "http://bar.foo.com/bbs",
elementFormDefault = XmlNsForm.QUALIFIED)
package com.foo.bar.bbs;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
Alternatively you could include the namespace in the #XmlRootElement annotation:
#XmlRootElement(namespace="http://bar.foo.com/bbs")
public class Rule {
}
For more information see:
http://bdoughan.blogspot.com/2010/08/jaxb-namespaces.html

Make sure you are unmarshalling the correct type of object.

Related

How to exclude properties from schemas using #JsonView

In Spring when a controller method is annotated with #JsonView, it returns only the
respective annotated properties of the object honoring the configuration
spring.jackson.mapper.default-view-inclusion, which is set to false by default.
// Kotlin code
abstract class Base {
lateinit var transientInternalProperty: String
}
class Main(val externalProperty: String) : Base()
#RestController
#RequestMapping("/")
class MainController {
#JsonView(Views.Public::class)
#GetMapping("/")
fun index() = Main()
}
Taking the above example, how to exclude non annotated properties on the generated
Main_Public schema. How to leave transientInternalProperty out of Main_Public without having to annotate it also?
I couldn't find anything about this in the documentation. Just this small section.
I tried to annotate the class itself with #JsonView to indicate "default view" for properties but it did not work.
To exclude properties from the generated OpenAPI sepc: prefer swagger-annotation, you #Hidden or #Schema(hidden = true)).

Can I match class that implements annotated Interface with knowledge only about annotation type?

just like in the topic. I have my resource class :
public class HelloWorldEndpoint implements IRest {
public String sayHello()
{
return "Hello world!";
}
}
And Interface :
#Path("/helloworld")
public interface IRest {
#GET
#Path("/hello")
String sayHello();
}
Is it possible to match sayHello() from HelloWorldEndpoint using only #Path class annotation? This is very specific example of resource class implementation, but it shows that it is possible to have REST endpoint without any annotation in class.. I've tried with inheritsAnnotation() and isAnnotatedWith() but it's not working that way unfortunatly. My goal is to find all resource classes :)
Annotations of interfaces are not inherited in accordance to the Java Langauge specification. They are neither exposed by the reflection API, for example.
In order to discover the annotation, you can manually travers the class hierarchy and look for the annotation in question. This is possible by hasSuperType(isAnnotatedWith(...)). Note that this is a rather expensive matching condition.

How can I wrap a JSON response in Spring

Suppose I have two sets of controllers in Spring:
/jsonapi1/*
/jsonapi2/*
both of which return objects that are to be interpretted as JSON text.
I'd like some kind of filter to wrap the responses from one set of these controllers so that:
the original response is contained within another object.
For example, if /jsonapi1/count returns:
{"num_humans":123, "num_androids":456}
then the response should be wrapped and returned as follows:
{ "status":0,
"content":{"num_humans":123, "num_androids":456}
}
if an exception happens in the controller, then filter should catch the exception and report it as follows
{ "status":5,
"content":"Something terrible happened"
}
The responses from the other controllers are returned unchanged.
We're currently customizing a MappingJackson2HttpMessageConverter passed to WebMvcConfigurerAdapter.configureMessageConverters in order to perform the above tasks. Works great except that it doesn't seem possible for this approach to be selective about the URLs (or controller classes) it applies to.
Is it possible to apply these kinds of wrappers to individual controller classes or URLs?
Update: Servlet filters look like a solution. Is it possible chose which filter gets applied to which controller methods, or which URLs?
I was struggling on this for multiple days. The solution by #Misha didn't work for me. I was able to finally get this working using ControllerAdvice and ResponseBodyAdvice.
ResponseBodyAdvice allows to inject custom transformation logic on the response returned by a controller but before it is converted to HttpResponse and committed.
This is how my controller method looks:
#RequestMapping("/global/hallOfFame")
public List<HallOfFame> getAllHallOfFame() {
return hallOfFameService.getAllHallOfFame();
}
Now i wanted to add some standard fields around the response like devmessage and usermessage. That logic goes into the ResponseAdvice:
#ControllerAdvice
public class TLResponseAdvice implements ResponseBodyAdvice<Object> {
#Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
#Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
ServerHttpResponse response) {
// TODO Auto-generated method stub
final RestResponse<Object> output = new RestResponse<>();
output.setData(body);
output.setDevMessage("ResponseAdviceDevMessage");
output.setHttpcode(200);
output.setStatus("Success");
output.setUserMessage("ResponseAdviceUserMessage");
return output;
}
}
The entity classes look like this:
#Setter // All lombok annotations
#Getter
#ToString
public class RestResponse<T> {
private String status;
private int httpcode;
private String devMessage;
private String userMessage;
private T data;
}
#Entity
#Data // Lombok
public class HallOfFame {
#Id
private String id;
private String name;
}
To handle exceptions, simply create another ControllerAdvice with ExceptionHandler. Use the example in this link.
Advantages of this solution:
It keeps your controllers clean. You can support any return type from your controller methods.
Your controller return type class does not need to extend some base class as required by the AOP approach.
You do not need to hack your way through Spring filters by using HttpServletResponseWrappers. They come up with a performance penalty.
EDIT - 17th September 2019
To handle exceptions use #ExceptionHandler. Refer code below.
#ExceptionHandler(Exception.class)
#ResponseBody
public MyResponseEntity<Object> handleControllerException(HttpServletRequest request, Throwable ex) {
// default value
int httpCode = HttpStatus.INTERNAL_SERVER_ERROR.value();
if(ex instanceof ResourceNotFoundException) {
httpCode = HttpStatus.NOT_FOUND.value();
}
...
}
The way I understand your question, you have exactly three choices.
Option #1
Manually wrap your objects in simple SuccessResponse, ErrorResponse, SomethingSortOfWrongResponse, etc. objects that have the fields you require. At this point, you have per-request flexibility, changing the fields on one of the response wrappers is trivial, and the only true drawback is code repetition if many of the controller's request methods can and should be grouped together.
Option #2
As you mentioned, and filter could be designed to do the dirty work, but be wary that Spring filters will NOT give you access to request or response data. Here's an example of what it might look like:
#Component
public class ResponseWrappingFilter extends GenericFilterBean {
#Override
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain) {
// Perform the rest of the chain, populating the response.
chain.doFilter(request, response);
// No way to read the body from the response here. getBody() doesn't exist.
response.setBody(new ResponseWrapper(response.getStatus(), response.getBody());
}
}
If you find a way to set the body in that filter, then yes, you could easily wrap it up. Otherwise, this option is a dead end.
Option #3
A-ha. So you got this far. Code duplication is not an option, but you insist on wrapping responses from your controller methods. I'd like to introduce the true solution - aspect-oriented programming (AOP), which Spring supports fondly.
If you're not familiar with AOP, the premise is as follows: you define an expression that matches (like a regular expression matches) points in the code. These points are called join points, while the expressions that match them are called pointcuts. You can then opt to execute additional, arbitrary code, called advice, when any pointcut or combination of pointcuts are matched. An object that defines pointcuts and advice is called an aspect.
It's great for expressing yourself more fluently in Java. The only drawback is weaker static type checking. Without further ado, here's your response-wrapping in aspect-oriented programming:
#Aspect
#Component
public class ResponseWrappingAspect {
#Pointcut("within(#org.springframework.stereotype.Controller *)")
public void anyControllerPointcut() {}
#Pointcut("execution(* *(..))")
public void anyMethodPointcut() {}
#AfterReturning(
value = "anyControllerPointcut() && anyMethodPointcut()",
returning = "response")
public Object wrapResponse(Object response) {
// Do whatever logic needs to be done to wrap it correctly.
return new ResponseWrapper(response);
}
#AfterThrowing(
value = "anyControllerPointcut() && anyMethodPointcut()",
throwing = "cause")
public Object wrapException(Exception cause) {
// Do whatever logic needs to be done to wrap it correctly.
return new ErrorResponseWrapper(cause);
}
}
The final result will be the non-repeating response wrapping that you seek. If you only want some or one controller receive this effect, then update the pointcut to match methods only within instances of that controller (rather than any class holding the #Controller annotation).
You'll need to include some AOP dependencies, add the AOP-enabling annotation in a configuration class, and make sure something component-scans the package this class is in.
Simplest way i manage custom responses from controllers is by utilising the Map variable.
so your code ends up looking like:
public #ResponseBody Map controllerName(...) {
Map mapA = new HashMap();
mapA.put("status", "5");
mapA.put("content", "something went south");
return mapA;
}
beauty of is is that you can configure it any thousand ways.
Currently i use for object transmition, custom exception handling and data reporting, too easy.
Hope this helps
I am also using AOP with #Around. Developed a custom annotation and using that for point cut. I am using a global Response. It has the status, Message and data which is of type List of type
List <? extends parent> dataList
( which can solve your class cast exception). All the entities extends this Parent class. This way I can set all the data into my List.
Also I am using the message key as param with the custom annotation and setting it in action.
Hope this helps.

Custom Neo4j GraphViz Writer

I have an application which produces a GraphViz dot file for a subgraph of my Neo4j database. It works like a charm, but there is somewhat of an issue.
Right now, the title of each node is the node id. Then the properties are listed, with their respective types. This is more information than I need and I would like to change the way the GraphViz writer is configured.
I noticed several classes/interfaces such as GraphStyle, StyleParameter, StyleConfiguration but I've tried several things and keep running into the issue that I cannot access certain classes/interfaces outside of their respective package. Maybe I'm doing it wrong, maybe it's designed so users cannot reconfigure the GraphViz writer, I don't know but I'd like to know.
How do I reconfigure the GraphViz writer so the dot file contains only that information which I want it to contain, namely a property of my choosing as the title, and nothing else as far as the nodes are concerned. Also, this is not always the same property, so for some nodes I'd like property A to be the title, and for nodes that don't have property A, I'd like property B to be the title.
Any help would be greatly appreciated.
You could try using the styles provided by this class: https://github.com/neo4j/neo4j/blob/master/community/graphviz/src/main/java/org/neo4j/visualization/graphviz/AsciiDocSimpleStyle.java
It might be useful to look into this class as well: https://github.com/neo4j/neo4j/blob/master/community/graphviz/src/main/java/org/neo4j/visualization/asciidoc/AsciidocHelper.java
I managed to get it to work. First of all, you need to create two new classes:
class NodeStyleImpl implements NodeStyle
class RelationshipStyleImpl implements RelationshipStyle
Here you can define how nodes and relations should be written in the dot notation. An example implementation looks like this :
public class NodeStyleImpl implements NodeStyle {
public void emitNodeStart(Appendable apndbl, Node node) throws IOException {
apndbl.append(" N" + node.getId() + " [\n label = \"");
}
public void emitEnd(Appendable apndbl) throws IOException {
apndbl.append("\"\n]\n");
}
public void emitProperty(Appendable apndbl, String propkey, Object propvalue) throws IOException {
if(propkey.equals("propkeyone") || propkey.equals("propkeytwo"){
apndbl.append(propvalue.toString());
}
}
}
In an analog fashion, you can write the RelationshipStyleImpl. If you're looking for more advanced configuration, you can also write a StyleConfiguration implementation. You can look at the default implementations in the Neo4j code for an example.
Then there's the issue with the GraphStyle class. The GraphStyle class has a constructor which is protected, thus only accessible from within the package. I made a pull request to change it to public but for the moment, here's a little "hack" which provides a workaround.
package org.neo4j.visualization.graphviz
public class GraphStyleImpl extends GraphStyle {
private GraphStyleImpl (NodeStyleImpl nstyle, RelationshipStyleImpl rstyle) {
super(nstyle, rstyle);
}
}
Note the package declaration. Because the GraphStyle constructor is protected, the super(nstyle, rstyle) method is only accessible from within the same package. By extending the class with a new public constructor, you can now do the following:
GraphStyle graphstyle = new GraphStyleImpl(new NodeStyleImpl(), new RelationshipStyleImpl());
GraphvizWriter writer = new GraphvizWriter(graphstyle);
If my pull request gets accepted, the use of the GraphStyleImpl class will no longer be necessary.

How can I use JUnit ExpectedException in Scala?

I'd like to be able to use JUnit 4.7's ExpectedException #Rule in Scala. However, it doesn't seem to catch anything:
import org.junit._
class ExceptionsHappen {
#Rule
def thrown = rules.ExpectedException.none
#Test
def badInt: Unit = {
thrown.expect(classOf[NumberFormatException])
Integer.parseInt("one")
}
}
This still fails with a NumberFormatException.
To make this work with JUnit 4.11 in Scala, you should meta-annotate your annotation so that the annotation is applied only to the (synthetic) getter method, not the underlying field:
import org.junit._
import scala.annotation.meta.getter
class ExceptionsHappen {
#(Rule #getter)
var thrown = rules.ExpectedException.none
#Test
def badInt: Unit = {
thrown.expect(classOf[NumberFormatException])
Integer.parseInt("one")
}
}
EDIT: Following the release of JUnit 4.11, you can now annotate a method with #Rule.
You will use it like:
private TemporaryFolder folder = new TemporaryFolder();
#Rule
public TemporaryFolder getFolder() {
return folder;
}
For earlier versions of JUnit, see the answer below.
--
No, you can't use this directly from Scala. The field needs to be public and non-static. From
org.junit.Rule:
public #interface Rule: Annotates fields that contain rules. Such a field must be public, not static, and a subtype of TestRule.
You cannot declare a public fields in Scala. All fields are private, and made accessible by accessors. See the answer to this question.
As well as this, there is already an enhancement request for junit (still Open):
Extend rules to support #Rule public MethodRule someRule() { return new SomeRule(); }
The other option is that it non-public fields be allowed, but this has already been rejected: Allow #Rule annotation on non-public fields.
So your options are:
clone junit, and implement the first suggestion, the method, and submit a pull request
Extend the Scala class from a java class which implements the #Rule
-
public class ExpectedExceptionTest {
#Rule
public ExpectedException thrown = ExpectedException.none();
}
and then inheriting from that:
class ExceptionsHappen extends ExpectedExceptionTest {
#Test
def badInt: Unit = {
thrown.expect(classOf[NumberFormatException])
Integer.parseInt("one")
}
}
which works correctly.
As a very newbie to Scala I am just using a very simple workaround: explicitly catch the exception and fail if your expected exception is not thrown.
Below is a sample skeleton:
try {
*your code that should throw an exception*
fail("Did not generate *the.Exception.you.expect*")
} catch {
case t: *the.Exception.you.expect* => // do nothing, it's expected :)
}
Without knowing JUnit rules, and without testing it, because I don't have an appropriate setup at hand, I go out on a limb and suggest turning thrown into a val.
I guess its some member that is initialized with something and then it gets some state and then some other machinery checks the state against something. You are always creating new ones and keep forgetting the expectation.
If Scala has something similar like static imports, then catch-exception is an alternative to JUnit 4.7's ExpectedException #Rule.
I'm still using JUnit 4, and found #Juh_'s comment instructive. This worked in Scala 2.11.0.
import org.junit.rules.ExpectedException
import org.junit.{Rule, Test}
import scala.reflect.{ClassTag, classTag}
class DeleteMe {
object Thrower {
def throwException[R <: Throwable: ClassTag](message: String): Unit = {
throw classTag[R].runtimeClass.getConstructor(classOf[String]).newInstance(message).asInstanceOf[R]
}
}
#Rule
def exceptionRule:ExpectedException = ExpectedException.none()
#Test(expected = classOf[Exception])
def checkConversionExceptions = {
val myMessage = "My Message"
exceptionRule.expectMessage(myMessage)
Thrower.throwException[Exception](myMessage)
()
}
}