Roberto
Roberto

Reputation: 1395

How to exclude root tag -element from jaxb wrapper?

There is app on spring+jaxb+jpa

So, I have rest - controllers and jaxv Elements:

@AllArgsConstructor
@NoArgsConstructor
@XmlRootElement(name = "root")
@Getter
public class UserWrapper {
    @XmlElementWrapper(name = "Users")
    @XmlElement(name = "User")
    private List<User> Users;

    @XmlElement(name="UserError")
    private UserError error;
}


@Getter
@Setter
@XmlRootElement(name="User")
@NoArgsConstructor
public class User{
  @XmlElement
  private String name;
  @XmlElement
  private String surname;
}

There are User entity and Wrapper for contain List of Users.

Response from my controller is:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
    <Users>
        <User>
            <Name>AAA</Name>
            <Surname>AAA</Surname>
        </User>
        <User>
            <Name>BBB</Name>
            <Surname>BBB</Surname>
        </User>
    </Users>
</root>

How to make response without tag ?

Rest controller is:

@RequestMapping(value = "/users", method = RequestMethod.GET)
    public @ResponseBody UsersWrapper findByParams(
            @RequestParam(value = "id") String id) throws Exception {
        RiskMetricError error = null;
        List<User> users = userService.find(id);

        return (new UsersWrapper(users, error));
    }

P.S. I need to make response xml like this:

        <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
        <Users>
            <User>
                <Name>AAA</Name>
                <Surname>AAA</Surname>
            </User>
            <User>
                <Name>BBB</Name>
                <Surname>BBB</Surname>
            </User>
        </Users>

Upvotes: 0

Views: 983

Answers (1)

martidis
martidis

Reputation: 2975

Comparing the two xmls (actual vs desired) you do not want to have the users content within the <root>. You can do this:

@XmlRootElement(name = "Users")
@NoArgsConstructor
@AllArgsConstructor
@XmlAccessorType(XmlAccessType.FIELD)
public class Users {

    @XmlElement(name = "User")
    private List<User> users;
}

Then User will be:

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@XmlAccessorType(XmlAccessType.FIELD)
public class User {

    @XmlElement(name = "Name")
    private String name;
    @XmlElement(name = "Surname")
    private String surname;
}

A small spring boot application to try it out:

@RestController
public class UsersEndpoint {

    @GetMapping("/users")
    public Users getUsers() {
        List<User> users = new ArrayList<>();
        users.add(new User("name1", "surname1"));
        users.add(new User("name2", "surname2"));

        return new Users(users);
    }
}

Will return this:

<Users>
    <User>
        <Name>name1</Name>
        <Surname>surname1</Surname>
    </User>
    <User>
        <Name>name2</Name>
        <Surname>surname2</Surname>
    </User>
</Users>

Update to reply to comment (elaborate on the answer):

Your POJOs and your xml structure should match. The annotations help "smooth" differences. You had <root></root> because your root class UserWrapper had this annotation: @XmlRootElement(name = "root"). If in the name you had "blah" the external tags (<root></root>) would be <blah></blah>. Additionally above your list of users you had this annotation: @XmlElementWrapper(name = "Users"). This created an extra wrapper element outside your list elements with the provided name.

So what I did is properly name the root element and remove the extra wrapper element creation.

Upvotes: 3

Related Questions