-1

Could You please help me to edit styles in geoserver by POST method? I am in trouble with this and I am stuck in one place. When I run this code and go to http://localhost:8010/styles/point on the page and I have Whitelabel error and in postman I have an error 400 Bad Request

public class StyleRequest {
    private String fill = "#042041";
    private String stroke = "#040001";

    public String getFill() {
        return fill;
    }

    public void setFill(String fill) {
        this.fill = fill;
    }

    public String getStroke() {
        return stroke;
    }

    public void setStroke(String stroke) {
        this.stroke = stroke;
    }
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/styles")
public class StyleController {

    private GeoServerStyleService styleService;

    @Autowired
    public StyleController(GeoServerStyleService styleService) {
        this.styleService = styleService;
    }

    @PostMapping("/{name}")
    public ResponseEntity<Void> editStyle(@PathVariable String name, @RequestBody StyleRequest styleRequest) {
        styleService.editStyle(name, styleRequest.getFill(), styleRequest.getStroke());
        return ResponseEntity.ok().build();
    }
}
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;

@Service
public class GeoServerStyleService {

    private WebClient webClient;

    public GeoServerStyleService() {
        this.webClient = WebClient.builder()
                .baseUrl("http://localhost:8080/geoserver/rest/")
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE)
                .build();
    }

    public void editStyle(String styleName, String fill, String stroke) {
        String styleXml = "<NamedLayer>\n" +
                "    <Name>" + styleName + "</Name>\n" +
                "    <UserStyle>\n" +
                "      <Title>A dark yellow polygon style</Title>\n" +
                "      <FeatureTypeStyle>\n" +
                "        <Rule>\n" +
                "          <Title>dark yellow polygon</Title>\n" +
                "          <PolygonSymbolizer>\n" +
                "            <Fill>\n" +
                "              <CssParameter name=\"fill\">" + fill + "</CssParameter>\n" +
                "            </Fill>\n" +
                "            <Stroke>\n" +
                "              <CssParameter name=\"stroke\">" + stroke + "</CssParameter>\n" +
                "              <CssParameter name=\"stroke-width\">0.5</CssParameter>\n" +
                "            </Stroke>\n" +
                "          </PolygonSymbolizer>\n" +
                "        </Rule>\n" +
                "      </FeatureTypeStyle>\n" +
                "    </UserStyle>\n" +
                "  </NamedLayer>";

        webClient.post()
                .uri("styles/" + styleName + ".xml")
                .body(BodyInserters.fromValue(styleXml))
                .retrieve()
                .toBodilessEntity()
                .block();
    }
}

I tried run code on http://localhost:8010/styles/point on the page and I have Whitelabel error and in postman I have an error 400 Bad Request. I don`t know what I can try

Piterek237
  • 61
  • 11
  • 1
    Your Java object `StyleRequest` in no-way matches the XML you are sending. There is thus no way it will map to that. – M. Deinum Jul 18 '23 at 07:07
  • What should I do instead? – Piterek237 Jul 18 '23 at 07:08
  • 1
    Create an object that matches your XML structure (and includes mapping annations from JAXB or Jackson XML), or receive the plain XML as a string and use XPath to extract what you need. – M. Deinum Jul 18 '23 at 07:09
  • So i Have to create in StyleRequest all the variables that comes from my style point in geo? Point Red Square point Rule 1 Red Square point A red fill with 6 pixels size square #FF0000 6 – Piterek237 Jul 18 '23 at 07:20
  • Don't post xml in the comments as that is totally unreadable. But yes you have to create a java representation from the XML **or** receive the XML as a `String` and use something like XPath or DOM to manually parse it and retrieve what you want. – M. Deinum Jul 18 '23 at 07:23
  • Okay thank You. I had to send it like that because it was too long for comment. So I deleted spaces. Sorry for that. I will try the second method first – Piterek237 Jul 18 '23 at 07:37
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/254534/discussion-between-piterek237-and-m-deinum). – Piterek237 Jul 18 '23 at 10:07

2 Answers2

1

There are two steps to creating a new style via the REST API,

You can create a new style on the server in two ways. In the first way, the creation is done in two steps: the style entry is created in the catalog, and then the style content is uploaded

So you need to do a POST to http://localhost:8080/geoserver/rest/styles with a body of:

<style><name>roads_style</name><filename>roads.sld</filename></style>

to create the style entry, and then a PUT to http://localhost:8080/geoserver/rest/styles/roads_style - where the last element matches the name in the body above, with a content-type of application/vnd.ogc.sld+xml and a body containing the actual SLD (XML). If you want to change the style then you just repeat this step with the new SLD file.

See the manual for examples

Ian Turton
  • 10,018
  • 1
  • 28
  • 47
0

Is it something like this?

@Component
public class GeoServerClient {

RestTemplate rest;
String url;

@Autowired
public GeoServerClient(RestTemplate rest, @Value("${geo.url}") String url) {
this.rest= rest;
this.url= url;
}

public void createNewStyle() {
String createStyleUrl = geoserverUrl + "/rest/styles";
String xmlBody = "<style><name>roads_style</name><filename>roads.sld</filename>                    
</style>";

HttpHeaders head= new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_XML);

HttpEntity<String> request= new HttpEntity<>(xmlBody, headers);
}
}
Piterek237
  • 61
  • 11
  • 1
    That will complete step one - provided all your styles are called `roads_style` – Ian Turton Jul 19 '23 at 13:30
  • @IanTurton I have a question. Cause in rest http://10.56.56.66:8081/geoserver/rest/styles/point.html i have on this page the file to dowload with name default_point.sld which is geoserver style. Do You maybe know how to get into this style with help of GET Method to display it on screen? – Piterek237 Jul 20 '23 at 07:25